commit
c798343973
@ -2,7 +2,37 @@ stages:
|
|||||||
- build
|
- build
|
||||||
- deploy
|
- deploy
|
||||||
|
|
||||||
build:
|
build-develop:
|
||||||
|
image: maven:3.8.6-eclipse-temurin-17
|
||||||
|
stage: build
|
||||||
|
variables:
|
||||||
|
MAVEN_OPTS: "-Dmaven.repo.local=./.m2/repository"
|
||||||
|
only:
|
||||||
|
- develop
|
||||||
|
except:
|
||||||
|
- tags
|
||||||
|
script:
|
||||||
|
- 'mvn -U clean package'
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- gitlab-app/target/gitlab-notification.jar
|
||||||
|
|
||||||
|
docker-build-develop:
|
||||||
|
image: upagge/docker-buildx:latest
|
||||||
|
stage: deploy
|
||||||
|
only:
|
||||||
|
- develop
|
||||||
|
except:
|
||||||
|
- tags
|
||||||
|
services:
|
||||||
|
- docker:dind
|
||||||
|
before_script:
|
||||||
|
- echo "$CI_REGISTRY_PASSWORD" | docker login $CI_REGISTRY --username $CI_REGISTRY_USER --password-stdin
|
||||||
|
script:
|
||||||
|
- docker buildx create --use
|
||||||
|
- docker buildx build --push --platform linux/amd64,linux/arm64/v8 -t "$CI_REGISTRY_IMAGE:develop" .
|
||||||
|
|
||||||
|
build-release:
|
||||||
image: maven:3.8.6-eclipse-temurin-17
|
image: maven:3.8.6-eclipse-temurin-17
|
||||||
stage: build
|
stage: build
|
||||||
variables:
|
variables:
|
||||||
@ -17,7 +47,7 @@ build:
|
|||||||
paths:
|
paths:
|
||||||
- gitlab-app/target/gitlab-notification.jar
|
- gitlab-app/target/gitlab-notification.jar
|
||||||
|
|
||||||
docker-build:
|
docker-build-release:
|
||||||
image: upagge/docker-buildx:latest
|
image: upagge/docker-buildx:latest
|
||||||
stage: deploy
|
stage: deploy
|
||||||
only:
|
only:
|
||||||
|
@ -34,4 +34,4 @@ COPY --from=app-build $BUILD_PATH/spring-boot-loader/ ./
|
|||||||
COPY --from=app-build $BUILD_PATH/dependencies/ ./
|
COPY --from=app-build $BUILD_PATH/dependencies/ ./
|
||||||
COPY --from=app-build $BUILD_PATH/application/ ./
|
COPY --from=app-build $BUILD_PATH/application/ ./
|
||||||
|
|
||||||
ENTRYPOINT java -DTELEGRAM_BOT_USERNAME=$TELEGRAM_BOT_USERNAME -DTELEGRAM_BOT_TOKEN=$TELEGRAM_BOT_TOKEN -DTELEGRAM_PERSON_ID=$TELEGRAM_PERSON_ID -DDATASOURCE_URL=$DATASOURCE_URL -DDATASOURCE_PASSWORD=$DATASOURCE_PASSWORD -DDATASOURCE_USERNAME=$DATASOURCE_USERNAME -DGITLAB_PERSONAL_TOKEN=$GITLAB_PERSONAL_TOKEN -DGITLAB_URL=$GITLAB_URL -DGITLAB_REPLACE_URL=$GITLAB_REPLACE_URL org.springframework.boot.loader.JarLauncher
|
ENTRYPOINT java -Dfile.encoding=UTF8 -Dconsole.encoding=UTF8 -DTELEGRAM_BOT_USERNAME=$TELEGRAM_BOT_USERNAME -DTELEGRAM_BOT_TOKEN=$TELEGRAM_BOT_TOKEN -DTELEGRAM_PERSON_ID=$TELEGRAM_PERSON_ID -DDATASOURCE_URL=$DATASOURCE_URL -DDATASOURCE_PASSWORD=$DATASOURCE_PASSWORD -DDATASOURCE_USERNAME=$DATASOURCE_USERNAME -DGITLAB_PERSONAL_TOKEN=$GITLAB_PERSONAL_TOKEN -DGITLAB_URL=$GITLAB_URL -DGITLAB_REPLACE_URL=$GITLAB_REPLACE_URL org.springframework.boot.loader.JarLauncher
|
@ -0,0 +1,40 @@
|
|||||||
|
package dev.struchkov.bot.gitlab.context.domain;
|
||||||
|
|
||||||
|
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
|
import static dev.struchkov.haiti.utils.Checker.checkNotNull;
|
||||||
|
import static dev.struchkov.haiti.utils.Checker.checkNull;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public enum AssigneeChanged {
|
||||||
|
|
||||||
|
BECOME(true),
|
||||||
|
DELETED(true),
|
||||||
|
NOT_AFFECT_USER(true),
|
||||||
|
NOT_CHANGED(false);
|
||||||
|
|
||||||
|
private final boolean changed;
|
||||||
|
|
||||||
|
public static AssigneeChanged valueOf(Long gitlabUserId, Person oldAssignee, Person newAssignee) {
|
||||||
|
if (checkNull(oldAssignee) && checkNotNull(newAssignee) && gitlabUserId.equals(newAssignee.getId())) {
|
||||||
|
return AssigneeChanged.BECOME;
|
||||||
|
}
|
||||||
|
if (checkNotNull(oldAssignee) && checkNull(newAssignee) && gitlabUserId.equals(oldAssignee.getId())) {
|
||||||
|
return AssigneeChanged.DELETED;
|
||||||
|
}
|
||||||
|
if (checkNotNull(oldAssignee) && checkNotNull(newAssignee) && !oldAssignee.getId().equals(newAssignee.getId())) {
|
||||||
|
if (gitlabUserId.equals(oldAssignee.getId())) {
|
||||||
|
return AssigneeChanged.DELETED;
|
||||||
|
}
|
||||||
|
if (gitlabUserId.equals(newAssignee.getId())) {
|
||||||
|
return AssigneeChanged.BECOME;
|
||||||
|
}
|
||||||
|
return AssigneeChanged.NOT_AFFECT_USER;
|
||||||
|
}
|
||||||
|
return AssigneeChanged.NOT_CHANGED;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
package dev.struchkov.bot.gitlab.context.domain;
|
||||||
|
|
||||||
|
import lombok.NonNull;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class ExistContainer<Entity, Key> {
|
||||||
|
|
||||||
|
protected final List<Entity> container;
|
||||||
|
protected final boolean allFound;
|
||||||
|
protected final Set<Key> idNoFound;
|
||||||
|
|
||||||
|
protected ExistContainer(List<Entity> container, boolean allFound, Set<Key> idNoFound) {
|
||||||
|
this.container = container;
|
||||||
|
this.allFound = allFound;
|
||||||
|
this.idNoFound = idNoFound;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T, K> ExistContainer<T, K> allFind(@NonNull List<T> container) {
|
||||||
|
return new ExistContainer<>(container, true, Collections.emptySet());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T, K> ExistContainer<T, K> notAllFind(@NonNull List<T> container, @NonNull Set<K> idNoFound) {
|
||||||
|
return new ExistContainer<>(container, false, idNoFound);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Entity> getContainer() {
|
||||||
|
return container;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAllFound() {
|
||||||
|
return allFound;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<Key> getIdNoFound() {
|
||||||
|
return idNoFound;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,40 +0,0 @@
|
|||||||
package dev.struchkov.bot.gitlab.context.domain;
|
|
||||||
|
|
||||||
import lombok.NonNull;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
|
||||||
|
|
||||||
public class ExistsContainer<Entity, Key> {
|
|
||||||
|
|
||||||
protected final Collection<Entity> container;
|
|
||||||
protected final boolean allFound;
|
|
||||||
protected final Collection<Key> idNoFound;
|
|
||||||
|
|
||||||
protected ExistsContainer(Collection<Entity> container, boolean allFound, Collection<Key> idNoFound) {
|
|
||||||
this.container = container;
|
|
||||||
this.allFound = allFound;
|
|
||||||
this.idNoFound = idNoFound;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T, K> ExistsContainer<T, K> allFind(@NonNull Collection<T> container) {
|
|
||||||
return new ExistsContainer<>(container, true, Collections.emptyList());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T, K> ExistsContainer<T, K> notAllFind(@NonNull Collection<T> container, @NonNull Collection<K> idNoFound) {
|
|
||||||
return new ExistsContainer<>(container, false, idNoFound);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Collection<Entity> getContainer() {
|
|
||||||
return container;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isAllFound() {
|
|
||||||
return allFound;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Collection<Key> getIdNoFound() {
|
|
||||||
return idNoFound;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -12,9 +12,10 @@ import lombok.Setter;
|
|||||||
@Builder
|
@Builder
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@EqualsAndHashCode(of = "id")
|
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
|
||||||
public class MessageSend {
|
public class MessageSend {
|
||||||
|
|
||||||
|
@EqualsAndHashCode.Include
|
||||||
private Long id;
|
private Long id;
|
||||||
private Long telegramId;
|
private Long telegramId;
|
||||||
private String message;
|
private String message;
|
||||||
|
@ -0,0 +1,38 @@
|
|||||||
|
package dev.struchkov.bot.gitlab.context.domain;
|
||||||
|
|
||||||
|
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public enum ReviewerChanged {
|
||||||
|
|
||||||
|
BECOME(true),
|
||||||
|
DELETED(true),
|
||||||
|
NOT_AFFECT_USER(true),
|
||||||
|
NOT_CHANGED(false);
|
||||||
|
|
||||||
|
private final boolean changed;
|
||||||
|
|
||||||
|
public static ReviewerChanged valueOf(Long gitlabUserId, List<Person> oldReviewers, List<Person> newReviewers) {
|
||||||
|
final Map<Long, Person> oldMap = oldReviewers.stream().collect(Collectors.toMap(Person::getId, p -> p));
|
||||||
|
final Map<Long, Person> newMap = newReviewers.stream().collect(Collectors.toMap(Person::getId, p -> p));
|
||||||
|
|
||||||
|
if (!oldMap.keySet().equals(newMap.keySet())) {
|
||||||
|
if (oldMap.containsKey(gitlabUserId) && !newMap.containsKey(gitlabUserId)) {
|
||||||
|
return ReviewerChanged.DELETED;
|
||||||
|
}
|
||||||
|
if (!oldMap.containsKey(gitlabUserId) && newMap.containsKey(gitlabUserId)) {
|
||||||
|
return ReviewerChanged.BECOME;
|
||||||
|
}
|
||||||
|
return ReviewerChanged.NOT_AFFECT_USER;
|
||||||
|
}
|
||||||
|
return ReviewerChanged.NOT_CHANGED;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -15,6 +15,7 @@ import javax.persistence.ManyToOne;
|
|||||||
import javax.persistence.OneToMany;
|
import javax.persistence.OneToMany;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author upagge 11.02.2021
|
* @author upagge 11.02.2021
|
||||||
@ -30,14 +31,14 @@ public class Discussion {
|
|||||||
@Column(name = "id")
|
@Column(name = "id")
|
||||||
private String id;
|
private String id;
|
||||||
|
|
||||||
@ManyToOne
|
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH})
|
||||||
@JoinColumn(name = "responsible_id")
|
@JoinColumn(name = "responsible_id")
|
||||||
private Person responsible;
|
private Person responsible;
|
||||||
|
|
||||||
@Column(name = "resolved")
|
@Column(name = "resolved")
|
||||||
private Boolean resolved;
|
private Boolean resolved;
|
||||||
|
|
||||||
@ManyToOne()
|
@ManyToOne
|
||||||
@JoinTable(
|
@JoinTable(
|
||||||
name = "discussion_merge_request",
|
name = "discussion_merge_request",
|
||||||
joinColumns = @JoinColumn(name = "discussion_id"),
|
joinColumns = @JoinColumn(name = "discussion_id"),
|
||||||
@ -50,7 +51,8 @@ public class Discussion {
|
|||||||
fetch = FetchType.EAGER,
|
fetch = FetchType.EAGER,
|
||||||
cascade = {
|
cascade = {
|
||||||
CascadeType.PERSIST,
|
CascadeType.PERSIST,
|
||||||
CascadeType.MERGE
|
CascadeType.MERGE,
|
||||||
|
CascadeType.REFRESH
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
private List<Note> notes;
|
private List<Note> notes;
|
||||||
@ -64,4 +66,13 @@ public class Discussion {
|
|||||||
return this.notes.get(0);
|
return this.notes.get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Optional<Note> getPrevLastNote() {
|
||||||
|
final int size = notes.size();
|
||||||
|
if (size > 2) {
|
||||||
|
return Optional.of(notes.get(size - 2));
|
||||||
|
}
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,22 +2,29 @@ package dev.struchkov.bot.gitlab.context.domain.entity;
|
|||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.MergeRequestState;
|
import dev.struchkov.bot.gitlab.context.domain.MergeRequestState;
|
||||||
import dev.struchkov.haiti.utils.fieldconstants.annotation.FieldNames;
|
import dev.struchkov.haiti.utils.fieldconstants.annotation.FieldNames;
|
||||||
|
import dev.struchkov.haiti.utils.fieldconstants.domain.Mode;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import javax.persistence.CascadeType;
|
||||||
import javax.persistence.CollectionTable;
|
import javax.persistence.CollectionTable;
|
||||||
import javax.persistence.Column;
|
import javax.persistence.Column;
|
||||||
import javax.persistence.ElementCollection;
|
import javax.persistence.ElementCollection;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.EnumType;
|
import javax.persistence.EnumType;
|
||||||
import javax.persistence.Enumerated;
|
import javax.persistence.Enumerated;
|
||||||
|
import javax.persistence.FetchType;
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
import javax.persistence.JoinColumn;
|
import javax.persistence.JoinColumn;
|
||||||
|
import javax.persistence.JoinTable;
|
||||||
import javax.persistence.ManyToOne;
|
import javax.persistence.ManyToOne;
|
||||||
|
import javax.persistence.OneToMany;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -28,7 +35,7 @@ import java.util.Set;
|
|||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@Entity
|
@Entity
|
||||||
@FieldNames
|
@FieldNames(mode = {Mode.TABLE, Mode.SIMPLE})
|
||||||
@Table(name = "merge_request")
|
@Table(name = "merge_request")
|
||||||
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
|
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
|
||||||
public class MergeRequest {
|
public class MergeRequest {
|
||||||
@ -66,14 +73,25 @@ public class MergeRequest {
|
|||||||
@Column(name = "conflict")
|
@Column(name = "conflict")
|
||||||
private boolean conflict;
|
private boolean conflict;
|
||||||
|
|
||||||
@ManyToOne
|
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
|
||||||
@JoinColumn(name = "author_id")
|
@JoinColumn(name = "author_id")
|
||||||
private Person author;
|
private Person author;
|
||||||
|
|
||||||
@ManyToOne
|
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
|
||||||
@JoinColumn(name = "assignee_id")
|
@JoinColumn(name = "assignee_id")
|
||||||
private Person assignee;
|
private Person assignee;
|
||||||
|
|
||||||
|
@OneToMany(
|
||||||
|
fetch = FetchType.LAZY,
|
||||||
|
cascade = {CascadeType.PERSIST, CascadeType.MERGE}
|
||||||
|
)
|
||||||
|
@JoinTable(
|
||||||
|
name = "merge_request_reviewer",
|
||||||
|
joinColumns = @JoinColumn(name = "merge_request_id", referencedColumnName = "id"),
|
||||||
|
inverseJoinColumns = @JoinColumn(name = "person_id", referencedColumnName = "id")
|
||||||
|
)
|
||||||
|
private List<Person> reviewers = new ArrayList<>();
|
||||||
|
|
||||||
@Column(name = "target_branch")
|
@Column(name = "target_branch")
|
||||||
private String targetBranch;
|
private String targetBranch;
|
||||||
|
|
||||||
|
@ -12,6 +12,9 @@ import javax.persistence.ManyToOne;
|
|||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
import static javax.persistence.CascadeType.MERGE;
|
||||||
|
import static javax.persistence.CascadeType.PERSIST;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@Entity
|
@Entity
|
||||||
@ -20,7 +23,8 @@ import java.time.LocalDateTime;
|
|||||||
public class Note {
|
public class Note {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@Column
|
@Column(name = "id")
|
||||||
|
@EqualsAndHashCode.Include
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
@Column(name = "type")
|
@Column(name = "type")
|
||||||
@ -35,7 +39,7 @@ public class Note {
|
|||||||
@Column(name = "updated_date")
|
@Column(name = "updated_date")
|
||||||
private LocalDateTime updated;
|
private LocalDateTime updated;
|
||||||
|
|
||||||
@ManyToOne
|
@ManyToOne(cascade = {PERSIST, MERGE})
|
||||||
@JoinColumn(name = "author_id")
|
@JoinColumn(name = "author_id")
|
||||||
private Person author;
|
private Person author;
|
||||||
|
|
||||||
@ -57,7 +61,7 @@ public class Note {
|
|||||||
@Column(name = "resolved")
|
@Column(name = "resolved")
|
||||||
private Boolean resolved;
|
private Boolean resolved;
|
||||||
|
|
||||||
@ManyToOne
|
@ManyToOne(cascade = {PERSIST, MERGE})
|
||||||
@JoinColumn(name = "resolved_id")
|
@JoinColumn(name = "resolved_id")
|
||||||
private Person resolvedBy;
|
private Person resolvedBy;
|
||||||
|
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
package dev.struchkov.bot.gitlab.context.domain.entity;
|
package dev.struchkov.bot.gitlab.context.domain.entity;
|
||||||
|
|
||||||
|
import dev.struchkov.haiti.utils.fieldconstants.annotation.FieldNames;
|
||||||
|
import dev.struchkov.haiti.utils.fieldconstants.domain.Mode;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
@ -14,10 +17,13 @@ import javax.persistence.Table;
|
|||||||
@Entity
|
@Entity
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
|
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
|
||||||
@Table(name = "person")
|
@Table(name = "person")
|
||||||
|
@FieldNames(mode = {Mode.TABLE, Mode.SIMPLE})
|
||||||
public class Person {
|
public class Person {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
|
@EqualsAndHashCode.Include
|
||||||
@Column(name = "id")
|
@Column(name = "id")
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ import lombok.EqualsAndHashCode;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import javax.persistence.CascadeType;
|
||||||
import javax.persistence.Column;
|
import javax.persistence.Column;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.EnumType;
|
import javax.persistence.EnumType;
|
||||||
@ -53,7 +54,7 @@ public class Pipeline {
|
|||||||
@JoinColumn(name = "project_id")
|
@JoinColumn(name = "project_id")
|
||||||
private Project project;
|
private Project project;
|
||||||
|
|
||||||
@ManyToOne
|
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH})
|
||||||
@JoinColumn(name = "person_id")
|
@JoinColumn(name = "person_id")
|
||||||
private Person person;
|
private Person person;
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@ package dev.struchkov.bot.gitlab.context.domain.notify.comment;
|
|||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.Answer;
|
import dev.struchkov.bot.gitlab.context.domain.Answer;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.notify.Notify;
|
import dev.struchkov.bot.gitlab.context.domain.notify.Notify;
|
||||||
import dev.struchkov.bot.gitlab.context.service.AppSettingService;
|
|
||||||
import dev.struchkov.bot.gitlab.context.utils.Smile;
|
import dev.struchkov.bot.gitlab.context.utils.Smile;
|
||||||
import dev.struchkov.haiti.utils.Strings;
|
import dev.struchkov.haiti.utils.Strings;
|
||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
|
@ -1,31 +0,0 @@
|
|||||||
package dev.struchkov.bot.gitlab.context.domain.notify.comment;
|
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.notify.Notify;
|
|
||||||
import dev.struchkov.bot.gitlab.context.utils.Smile;
|
|
||||||
import lombok.Builder;
|
|
||||||
|
|
||||||
import java.text.MessageFormat;
|
|
||||||
|
|
||||||
import static dev.struchkov.haiti.utils.Strings.escapeMarkdown;
|
|
||||||
|
|
||||||
public record CommentNotify(
|
|
||||||
String url,
|
|
||||||
String authorName,
|
|
||||||
String message
|
|
||||||
) implements Notify {
|
|
||||||
|
|
||||||
@Builder
|
|
||||||
public CommentNotify {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String generateMessage() {
|
|
||||||
return MessageFormat.format(
|
|
||||||
"{0} *New mention* | [MR]({1}){2}*{3}*: {4}",
|
|
||||||
Smile.COMMENT.getValue(), url, Smile.HR.getValue(), authorName, escapeMarkdown(message)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,43 @@
|
|||||||
|
package dev.struchkov.bot.gitlab.context.domain.notify.comment;
|
||||||
|
|
||||||
|
import dev.struchkov.bot.gitlab.context.domain.notify.Notify;
|
||||||
|
import dev.struchkov.bot.gitlab.context.utils.Smile;
|
||||||
|
import lombok.Builder;
|
||||||
|
|
||||||
|
import static dev.struchkov.haiti.utils.Checker.checkNotNull;
|
||||||
|
import static dev.struchkov.haiti.utils.Strings.escapeMarkdown;
|
||||||
|
|
||||||
|
@Builder
|
||||||
|
public record NewCommentNotify(
|
||||||
|
String url,
|
||||||
|
String discussionMessage,
|
||||||
|
String discussionAuthor,
|
||||||
|
String previousMessage,
|
||||||
|
String previousAuthor,
|
||||||
|
String authorName,
|
||||||
|
String message
|
||||||
|
) implements Notify {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String generateMessage() {
|
||||||
|
|
||||||
|
final StringBuilder builder = new StringBuilder(Smile.COMMENT.getValue()).append(" [New answer in discussion](").append(url).append(")\n--- --- --- ---");
|
||||||
|
|
||||||
|
if (checkNotNull(discussionMessage)) {
|
||||||
|
builder.append("\n-- -- discussion first message -- --\n")
|
||||||
|
.append("*").append(discussionAuthor).append("*: ").append(escapeMarkdown(discussionMessage));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (checkNotNull(previousMessage)) {
|
||||||
|
builder.append("\n-- -- -- previous message -- -- --\n")
|
||||||
|
.append("*").append(previousAuthor).append("*: ").append(escapeMarkdown(previousMessage));
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.append("\n-- -- -- --- new answer --- -- -- --\n")
|
||||||
|
.append("*").append(authorName).append("*: ").append(escapeMarkdown(message));
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -48,7 +48,7 @@ public class NewPrNotify extends PrNotify {
|
|||||||
labelText = "\n\n" + labelText;
|
labelText = "\n\n" + labelText;
|
||||||
}
|
}
|
||||||
return MessageFormat.format(
|
return MessageFormat.format(
|
||||||
"{0} *New MergeRequest | {1}*{2}[{3}]({4}){5}{2}{9}: {10} {12} {11}",
|
"{0} *New merge request for review | {1}*{2}[{3}]({4}){5}{2}{9}: {10} {12} {11}\n{7}: {8}",
|
||||||
Smile.FUN.getValue(),
|
Smile.FUN.getValue(),
|
||||||
projectName,
|
projectName,
|
||||||
Smile.HR.getValue(),
|
Smile.HR.getValue(),
|
||||||
|
@ -4,8 +4,6 @@ import dev.struchkov.bot.gitlab.context.utils.Smile;
|
|||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
import java.text.MessageFormat;
|
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
public class UpdatePrNotify extends PrNotify {
|
public class UpdatePrNotify extends PrNotify {
|
||||||
|
|
||||||
@ -36,10 +34,24 @@ public class UpdatePrNotify extends PrNotify {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String generateMessage() {
|
public String generateMessage() {
|
||||||
return MessageFormat.format(
|
final StringBuilder builder = new StringBuilder(Smile.UPDATE.getValue()).append(" *MergeRequest update | ").append(projectName).append("*")
|
||||||
"{0} *MergeRequest update | {6}*{3}[{1}]({2}){3}{4}: {5}",
|
.append(Smile.HR.getValue())
|
||||||
Smile.UPDATE.getValue(), title, url, Smile.HR.getValue(), Smile.AUTHOR.getValue(), author, projectName, allTasks, allResolvedTasks, personTasks, personResolvedTasks
|
.append("[").append(title).append("](").append(url).append(")");
|
||||||
);
|
|
||||||
|
|
||||||
|
if (allTasks > 0) {
|
||||||
|
builder.append(Smile.HR.getValue())
|
||||||
|
.append("All tasks: ").append(allResolvedTasks).append("/").append(allTasks);
|
||||||
|
|
||||||
|
if (personTasks > 0) {
|
||||||
|
builder.append("\nYour tasks: ").append(personResolvedTasks).append("/").append(personTasks);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.append(Smile.HR.getValue())
|
||||||
|
.append(Smile.AUTHOR.getValue()).append(": ").append(author);
|
||||||
|
|
||||||
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,59 @@
|
|||||||
|
package dev.struchkov.bot.gitlab.context.domain.notify.task;
|
||||||
|
|
||||||
|
import dev.struchkov.bot.gitlab.context.utils.Smile;
|
||||||
|
import dev.struchkov.haiti.utils.Pair;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Singular;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static dev.struchkov.haiti.utils.Checker.checkNotNull;
|
||||||
|
import static dev.struchkov.haiti.utils.Strings.escapeMarkdown;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author upagge 10.09.2020
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
public class DiscussionNewNotify extends TaskNotify {
|
||||||
|
|
||||||
|
private final String mrName;
|
||||||
|
private final List<Pair<String, String>> notes;
|
||||||
|
|
||||||
|
@Builder
|
||||||
|
public DiscussionNewNotify(
|
||||||
|
String mrName,
|
||||||
|
String authorName,
|
||||||
|
String url,
|
||||||
|
String discussionMessage,
|
||||||
|
@Singular List<Pair<String, String>> notes
|
||||||
|
) {
|
||||||
|
super(authorName, url, discussionMessage);
|
||||||
|
this.mrName = mrName;
|
||||||
|
this.notes = notes;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String generateMessage() {
|
||||||
|
final StringBuilder builder = new StringBuilder(Smile.TASK.getValue()).append(" [New discussion](").append(url).append(")")
|
||||||
|
.append(Smile.HR.getValue())
|
||||||
|
.append(escapeMarkdown(mrName))
|
||||||
|
.append(Smile.HR.getValue())
|
||||||
|
.append("*").append(authorName).append("*: ").append(escapeMarkdown(messageTask));
|
||||||
|
|
||||||
|
if (checkNotNull(notes)) {
|
||||||
|
builder.append("\n-- -- -- -- comments -- -- -- --\n")
|
||||||
|
.append(convertNotes(notes));
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String convertNotes(List<Pair<String, String>> notes) {
|
||||||
|
return notes.stream()
|
||||||
|
.map(note -> "*" + note.getKey() + "*: " + note.getValue())
|
||||||
|
.collect(Collectors.joining("\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,34 +0,0 @@
|
|||||||
package dev.struchkov.bot.gitlab.context.domain.notify.task;
|
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.utils.Smile;
|
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
import java.text.MessageFormat;
|
|
||||||
|
|
||||||
import static dev.struchkov.haiti.utils.Strings.escapeMarkdown;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author upagge 10.09.2020
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
public class TaskNewNotify extends TaskNotify {
|
|
||||||
|
|
||||||
@Builder
|
|
||||||
protected TaskNewNotify(
|
|
||||||
String authorName,
|
|
||||||
String url,
|
|
||||||
String messageTask
|
|
||||||
) {
|
|
||||||
super(authorName, url, messageTask);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String generateMessage() {
|
|
||||||
return MessageFormat.format(
|
|
||||||
"{0} *New [task]({1}) assigned{2}*{3}*: {4}",
|
|
||||||
Smile.TASK.getValue(), url, Smile.HR.getValue(), authorName, escapeMarkdown(messageTask)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -30,4 +30,7 @@ public interface MergeRequestRepository {
|
|||||||
void deleteByIds(Set<Long> mergeRequestIds);
|
void deleteByIds(Set<Long> mergeRequestIds);
|
||||||
|
|
||||||
Page<MergeRequest> filter(Filter filter, Pageable pageable);
|
Page<MergeRequest> filter(Filter filter, Pageable pageable);
|
||||||
|
|
||||||
|
List<MergeRequest> findAllByReviewerId(Long personId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package dev.struchkov.bot.gitlab.context.service;
|
package dev.struchkov.bot.gitlab.context.service;
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.ExistsContainer;
|
import dev.struchkov.bot.gitlab.context.domain.ExistContainer;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.Discussion;
|
import dev.struchkov.bot.gitlab.context.domain.entity.Discussion;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
@ -18,6 +18,8 @@ public interface DiscussionService {
|
|||||||
|
|
||||||
Discussion update(@NonNull Discussion discussion);
|
Discussion update(@NonNull Discussion discussion);
|
||||||
|
|
||||||
|
List<Discussion> updateAll(@NonNull List<Discussion> discussions);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Метод отправляющий коментарий в дискуссию.
|
* Метод отправляющий коментарий в дискуссию.
|
||||||
*
|
*
|
||||||
@ -31,7 +33,7 @@ public interface DiscussionService {
|
|||||||
*/
|
*/
|
||||||
List<Discussion> getAllByMergeRequestId(@NonNull Long mergeRequestId);
|
List<Discussion> getAllByMergeRequestId(@NonNull Long mergeRequestId);
|
||||||
|
|
||||||
ExistsContainer<Discussion, String> existsById(@NonNull Set<String> discussionIds);
|
ExistContainer<Discussion, String> existsById(@NonNull Set<String> discussionIds);
|
||||||
|
|
||||||
List<Discussion> createAll(@NonNull List<Discussion> newDiscussions);
|
List<Discussion> createAll(@NonNull List<Discussion> newDiscussions);
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package dev.struchkov.bot.gitlab.context.service;
|
package dev.struchkov.bot.gitlab.context.service;
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.ExistsContainer;
|
import dev.struchkov.bot.gitlab.context.domain.ExistContainer;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.IdAndStatusPr;
|
import dev.struchkov.bot.gitlab.context.domain.IdAndStatusPr;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.MergeRequestState;
|
import dev.struchkov.bot.gitlab.context.domain.MergeRequestState;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.MergeRequest;
|
import dev.struchkov.bot.gitlab.context.domain.entity.MergeRequest;
|
||||||
@ -18,6 +18,8 @@ public interface MergeRequestsService {
|
|||||||
|
|
||||||
MergeRequest update(@NonNull MergeRequest mergeRequest);
|
MergeRequest update(@NonNull MergeRequest mergeRequest);
|
||||||
|
|
||||||
|
List<MergeRequest> updateAll(@NonNull List<MergeRequest> mergeRequests);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Получить все идентификаторы вместе со статусами.
|
* Получить все идентификаторы вместе со статусами.
|
||||||
*
|
*
|
||||||
@ -30,10 +32,12 @@ public interface MergeRequestsService {
|
|||||||
|
|
||||||
Page<MergeRequest> getAll(@NonNull MergeRequestFilter filter, Pageable pagination);
|
Page<MergeRequest> getAll(@NonNull MergeRequestFilter filter, Pageable pagination);
|
||||||
|
|
||||||
ExistsContainer<MergeRequest, Long> existsById(@NonNull Set<Long> mergeRequestIds);
|
ExistContainer<MergeRequest, Long> existsById(@NonNull Set<Long> mergeRequestIds);
|
||||||
|
|
||||||
List<MergeRequest> createAll(List<MergeRequest> newMergeRequests);
|
List<MergeRequest> createAll(List<MergeRequest> newMergeRequests);
|
||||||
|
|
||||||
void deleteAllById(@NonNull Set<Long> mergeRequestIds);
|
void deleteAllById(@NonNull Set<Long> mergeRequestIds);
|
||||||
|
|
||||||
|
List<MergeRequest> getAllByReviewerId(@NonNull Long personId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package dev.struchkov.bot.gitlab.context.service;
|
package dev.struchkov.bot.gitlab.context.service;
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.ExistsContainer;
|
import dev.struchkov.bot.gitlab.context.domain.ExistContainer;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
|
|
||||||
@ -18,7 +18,7 @@ public interface PersonService {
|
|||||||
|
|
||||||
Person getByIdOrThrown(@NonNull Long personId);
|
Person getByIdOrThrown(@NonNull Long personId);
|
||||||
|
|
||||||
ExistsContainer<Person, Long> existsById(Set<Long> personIds);
|
ExistContainer<Person, Long> existsById(Set<Long> personIds);
|
||||||
|
|
||||||
List<Person> createAll(List<Person> newPersons);
|
List<Person> createAll(List<Person> newPersons);
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package dev.struchkov.bot.gitlab.context.service;
|
package dev.struchkov.bot.gitlab.context.service;
|
||||||
|
|
||||||
|
import dev.struchkov.bot.gitlab.context.domain.ExistContainer;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.PipelineStatus;
|
import dev.struchkov.bot.gitlab.context.domain.PipelineStatus;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.Pipeline;
|
import dev.struchkov.bot.gitlab.context.domain.entity.Pipeline;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.filter.PipelineFilter;
|
import dev.struchkov.bot.gitlab.context.domain.filter.PipelineFilter;
|
||||||
import dev.struchkov.haiti.context.domain.ExistsContainer;
|
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
@ -25,7 +25,7 @@ public interface PipelineService {
|
|||||||
|
|
||||||
Page<Pipeline> getAll(@NonNull PipelineFilter filter, @NonNull Pageable pagination);
|
Page<Pipeline> getAll(@NonNull PipelineFilter filter, @NonNull Pageable pagination);
|
||||||
|
|
||||||
ExistsContainer<Pipeline, Long> existsById(@NonNull Set<Long> pipelineIds);
|
ExistContainer<Pipeline, Long> existsById(@NonNull Set<Long> pipelineIds);
|
||||||
|
|
||||||
void deleteAllById(Set<Long> pipelineIds);
|
void deleteAllById(Set<Long> pipelineIds);
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package dev.struchkov.bot.gitlab.context.service;
|
package dev.struchkov.bot.gitlab.context.service;
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.ExistsContainer;
|
import dev.struchkov.bot.gitlab.context.domain.ExistContainer;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.Project;
|
import dev.struchkov.bot.gitlab.context.domain.entity.Project;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
@ -26,6 +26,6 @@ public interface ProjectService {
|
|||||||
|
|
||||||
boolean existsById(Long projectId);
|
boolean existsById(Long projectId);
|
||||||
|
|
||||||
ExistsContainer<Project, Long> existsById(Set<Long> projectIds);
|
ExistContainer<Project, Long> existsById(Set<Long> projectIds);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,9 @@ public enum Smile {
|
|||||||
DANGEROUS("⚠️"),
|
DANGEROUS("⚠️"),
|
||||||
COMMENT("\uD83D\uDCAC"),
|
COMMENT("\uD83D\uDCAC"),
|
||||||
ARROW("➜"),
|
ARROW("➜"),
|
||||||
HR("\n -- -- -- -- --\n"),
|
SHORT_HR("\n-- -- --\n"),
|
||||||
|
HR("\n-- -- -- -- --\n"),
|
||||||
|
HR2("\n-- -- -- -- -- -- -- -- -- --\n"),
|
||||||
FAILURE("❌"),
|
FAILURE("❌"),
|
||||||
SUCCESS("✅"),
|
SUCCESS("✅"),
|
||||||
BUILD("♻️"),
|
BUILD("♻️"),
|
||||||
|
@ -2,16 +2,20 @@ package dev.struchkov.bot.gitlab.core.service.convert;
|
|||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.MergeRequestState;
|
import dev.struchkov.bot.gitlab.context.domain.MergeRequestState;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.MergeRequest;
|
import dev.struchkov.bot.gitlab.context.domain.entity.MergeRequest;
|
||||||
|
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
||||||
import dev.struchkov.bot.gitlab.sdk.domain.MergeRequestJson;
|
import dev.struchkov.bot.gitlab.sdk.domain.MergeRequestJson;
|
||||||
import dev.struchkov.bot.gitlab.sdk.domain.MergeRequestStateJson;
|
import dev.struchkov.bot.gitlab.sdk.domain.MergeRequestStateJson;
|
||||||
|
import dev.struchkov.bot.gitlab.sdk.domain.PersonJson;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.core.convert.converter.Converter;
|
import org.springframework.core.convert.converter.Converter;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static dev.struchkov.haiti.utils.Checker.checkNotEmpty;
|
import static dev.struchkov.haiti.utils.Checker.checkNotEmpty;
|
||||||
|
import static dev.struchkov.haiti.utils.Checker.checkNotNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author upagge 15.01.2021
|
* @author upagge 15.01.2021
|
||||||
@ -35,23 +39,36 @@ public class MergeRequestJsonConverter implements Converter<MergeRequestJson, Me
|
|||||||
mergeRequest.setState(convertState(source.getState()));
|
mergeRequest.setState(convertState(source.getState()));
|
||||||
mergeRequest.setProjectId(source.getProjectId());
|
mergeRequest.setProjectId(source.getProjectId());
|
||||||
mergeRequest.setWebUrl(source.getWebUrl());
|
mergeRequest.setWebUrl(source.getWebUrl());
|
||||||
mergeRequest.setLabels(convertLabels(source.getLabels()));
|
|
||||||
if (source.getAssignee() != null) {
|
convertLabels(mergeRequest, source.getLabels());
|
||||||
|
convertReviewers(mergeRequest, source.getReviewers());
|
||||||
|
|
||||||
|
if (checkNotNull(source.getAssignee())) {
|
||||||
mergeRequest.setAssignee(convertPerson.convert(source.getAssignee()));
|
mergeRequest.setAssignee(convertPerson.convert(source.getAssignee()));
|
||||||
}
|
}
|
||||||
|
|
||||||
mergeRequest.setAuthor(convertPerson.convert(source.getAuthor()));
|
mergeRequest.setAuthor(convertPerson.convert(source.getAuthor()));
|
||||||
mergeRequest.setSourceBranch(source.getSourceBranch());
|
mergeRequest.setSourceBranch(source.getSourceBranch());
|
||||||
mergeRequest.setTargetBranch(source.getTargetBranch());
|
mergeRequest.setTargetBranch(source.getTargetBranch());
|
||||||
return mergeRequest;
|
return mergeRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Set<String> convertLabels(Set<String> source) {
|
private void convertReviewers(MergeRequest mergeRequest, List<PersonJson> jsonReviewers) {
|
||||||
if (checkNotEmpty(source)) {
|
if (checkNotEmpty(jsonReviewers)) {
|
||||||
return source.stream()
|
final List<Person> reviewers = jsonReviewers.stream()
|
||||||
.map(label -> label.replaceAll("-", "_"))
|
.map(convertPerson::convert)
|
||||||
.collect(Collectors.toSet());
|
.toList();
|
||||||
|
mergeRequest.setReviewers(reviewers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void convertLabels(MergeRequest mergeRequest, Set<String> source) {
|
||||||
|
if (checkNotEmpty(source)) {
|
||||||
|
final Set<String> labels = source.stream()
|
||||||
|
.map(label -> label.replace("-", "_"))
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
mergeRequest.setLabels(labels);
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private MergeRequestState convertState(MergeRequestStateJson state) {
|
private MergeRequestState convertState(MergeRequestStateJson state) {
|
||||||
|
@ -2,6 +2,7 @@ package dev.struchkov.bot.gitlab.core.service.convert;
|
|||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.Project;
|
import dev.struchkov.bot.gitlab.context.domain.entity.Project;
|
||||||
import dev.struchkov.bot.gitlab.sdk.domain.ProjectJson;
|
import dev.struchkov.bot.gitlab.sdk.domain.ProjectJson;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.core.convert.converter.Converter;
|
import org.springframework.core.convert.converter.Converter;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@ -9,6 +10,7 @@ import org.springframework.stereotype.Component;
|
|||||||
* @author upagge 14.01.2021
|
* @author upagge 14.01.2021
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
|
@RequiredArgsConstructor
|
||||||
public class ProjectJsonConverter implements Converter<ProjectJson, Project> {
|
public class ProjectJsonConverter implements Converter<ProjectJson, Project> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,20 +1,21 @@
|
|||||||
package dev.struchkov.bot.gitlab.core.service.impl;
|
package dev.struchkov.bot.gitlab.core.service.impl;
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.ExistsContainer;
|
import dev.struchkov.bot.gitlab.context.domain.ExistContainer;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.PersonInformation;
|
import dev.struchkov.bot.gitlab.context.domain.PersonInformation;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.Discussion;
|
import dev.struchkov.bot.gitlab.context.domain.entity.Discussion;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.MergeRequest;
|
import dev.struchkov.bot.gitlab.context.domain.entity.MergeRequest;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.Note;
|
import dev.struchkov.bot.gitlab.context.domain.entity.Note;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.notify.comment.CommentNotify;
|
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
||||||
|
import dev.struchkov.bot.gitlab.context.domain.notify.comment.NewCommentNotify;
|
||||||
|
import dev.struchkov.bot.gitlab.context.domain.notify.task.DiscussionNewNotify;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.notify.task.TaskCloseNotify;
|
import dev.struchkov.bot.gitlab.context.domain.notify.task.TaskCloseNotify;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.notify.task.TaskNewNotify;
|
|
||||||
import dev.struchkov.bot.gitlab.context.repository.DiscussionRepository;
|
import dev.struchkov.bot.gitlab.context.repository.DiscussionRepository;
|
||||||
import dev.struchkov.bot.gitlab.context.service.DiscussionService;
|
import dev.struchkov.bot.gitlab.context.service.DiscussionService;
|
||||||
import dev.struchkov.bot.gitlab.context.service.NotifyService;
|
import dev.struchkov.bot.gitlab.context.service.NotifyService;
|
||||||
import dev.struchkov.bot.gitlab.context.service.PersonService;
|
|
||||||
import dev.struchkov.bot.gitlab.core.config.properties.GitlabProperty;
|
import dev.struchkov.bot.gitlab.core.config.properties.GitlabProperty;
|
||||||
import dev.struchkov.bot.gitlab.core.config.properties.PersonProperty;
|
import dev.struchkov.bot.gitlab.core.config.properties.PersonProperty;
|
||||||
import dev.struchkov.bot.gitlab.core.utils.StringUtils;
|
import dev.struchkov.bot.gitlab.core.utils.StringUtils;
|
||||||
|
import dev.struchkov.haiti.utils.Pair;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@ -25,6 +26,7 @@ import okhttp3.RequestBody;
|
|||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
@ -32,12 +34,14 @@ import java.util.HashSet;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static dev.struchkov.haiti.context.exception.NotFoundException.notFoundException;
|
import static dev.struchkov.haiti.context.exception.NotFoundException.notFoundException;
|
||||||
|
import static dev.struchkov.haiti.utils.Checker.checkNotNull;
|
||||||
import static java.lang.Boolean.FALSE;
|
import static java.lang.Boolean.FALSE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -52,7 +56,6 @@ public class DiscussionServiceImpl implements DiscussionService {
|
|||||||
|
|
||||||
protected static final Pattern PATTERN = Pattern.compile("@[\\w]+");
|
protected static final Pattern PATTERN = Pattern.compile("@[\\w]+");
|
||||||
|
|
||||||
private final PersonService personService;
|
|
||||||
private final DiscussionRepository repository;
|
private final DiscussionRepository repository;
|
||||||
private final PersonInformation personInformation;
|
private final PersonInformation personInformation;
|
||||||
|
|
||||||
@ -62,85 +65,147 @@ public class DiscussionServiceImpl implements DiscussionService {
|
|||||||
private final NotifyService notifyService;
|
private final NotifyService notifyService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Transactional
|
||||||
public Discussion create(@NonNull Discussion discussion) {
|
public Discussion create(@NonNull Discussion discussion) {
|
||||||
discussion.getNotes().forEach(note -> personService.create(note.getAuthor()));
|
final List<Note> notes = discussion.getNotes();
|
||||||
discussion.getNotes().forEach(this::notificationPersonal);
|
|
||||||
discussion.getNotes().forEach(note -> notifyNewNote(note, discussion));
|
if (isNeedNotifyNewNote(discussion)) {
|
||||||
|
notifyNewDiscussion(discussion);
|
||||||
|
} else {
|
||||||
|
notes.forEach(this::notificationPersonal);
|
||||||
|
}
|
||||||
|
|
||||||
final boolean resolved = discussion.getNotes().stream()
|
final boolean resolved = discussion.getNotes().stream()
|
||||||
.allMatch(note -> note.isResolvable() && note.getResolved());
|
.allMatch(note -> note.isResolvable() && note.getResolved());
|
||||||
|
|
||||||
discussion.setResolved(resolved);
|
discussion.setResolved(resolved);
|
||||||
|
|
||||||
return repository.save(discussion);
|
return repository.save(discussion);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>Уведомляет пользователя, если появился новый комментарий</p>
|
* <p>Уведомляет пользователя, если появился новый комментарий</p>
|
||||||
*/
|
*/
|
||||||
private void notifyNewNote(Note note, Discussion discussion) {
|
private void notifyNewDiscussion(Discussion discussion) {
|
||||||
if (isNeedNotifyNewNote(note, discussion)) {
|
final Note firstNote = discussion.getFirstNote();
|
||||||
notifyService.send(
|
final List<Note> notes = discussion.getNotes();
|
||||||
TaskNewNotify.builder()
|
|
||||||
.authorName(note.getAuthor().getName())
|
|
||||||
.messageTask(note.getBody())
|
final MergeRequest mergeRequest = discussion.getMergeRequest();
|
||||||
.url(note.getWebUrl())
|
final DiscussionNewNotify.DiscussionNewNotifyBuilder notifyBuilder = DiscussionNewNotify.builder()
|
||||||
.build()
|
.mrName(mergeRequest.getTitle())
|
||||||
|
.authorName(firstNote.getAuthor().getName())
|
||||||
|
.discussionMessage(firstNote.getBody())
|
||||||
|
.url(firstNote.getWebUrl());
|
||||||
|
|
||||||
|
if (notes.size() > 1) {
|
||||||
|
for (int i = 1; i < notes.size(); i++) {
|
||||||
|
final Note note = notes.get(i);
|
||||||
|
notifyBuilder.note(
|
||||||
|
new Pair<>(note.getAuthor().getName(), note.getBody())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isNeedNotifyNewNote(Note note, Discussion discussion) {
|
notifyService.send(notifyBuilder.build());
|
||||||
final Long personId = personInformation.getId();
|
}
|
||||||
return note.isResolvable() // Тип комментария требует решения (Задачи)
|
|
||||||
&& personId.equals(discussion.getResponsible().getId()) // Создатель дискуссии пользователь приложения
|
private boolean isNeedNotifyNewNote(Discussion discussion) {
|
||||||
&& !personId.equals(note.getAuthor().getId()) // Создатель комментария не пользователь системы
|
final Note firstNote = discussion.getFirstNote();
|
||||||
&& FALSE.equals(note.getResolved()); // Комментарий не отмечен как решенный
|
final Long gitlabUserId = personInformation.getId();
|
||||||
|
return firstNote.isResolvable() // Тип комментария требует решения (Задачи)
|
||||||
|
&& gitlabUserId.equals(discussion.getResponsible().getId()) // Ответственный за дискуссию пользователь
|
||||||
|
&& !gitlabUserId.equals(firstNote.getAuthor().getId()) // Создатель комментария не пользователь системы
|
||||||
|
&& FALSE.equals(firstNote.getResolved()); // Комментарий не отмечен как решенный
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Discussion update(@NonNull Discussion discussion) {
|
public Discussion update(@NonNull Discussion discussion) {
|
||||||
final Discussion oldDiscussion = repository.findById(discussion.getId())
|
final Discussion oldDiscussion = repository.findById(discussion.getId())
|
||||||
.orElseThrow(notFoundException("Дискуссия не найдена"));
|
.orElseThrow(notFoundException("Дискуссия не найдена"));
|
||||||
final Map<Long, Note> idAndNoteMap = oldDiscussion
|
|
||||||
.getNotes().stream()
|
|
||||||
.collect(Collectors.toMap(Note::getId, note -> note));
|
|
||||||
|
|
||||||
// Пользователь участвовал в обсуждении
|
|
||||||
final boolean userParticipatedInDiscussion = discussion.getNotes().stream()
|
|
||||||
.anyMatch(note -> personInformation.getId().equals(note.getAuthor().getId()));
|
|
||||||
|
|
||||||
discussion.setMergeRequest(oldDiscussion.getMergeRequest());
|
|
||||||
discussion.setResponsible(oldDiscussion.getResponsible());
|
discussion.setResponsible(oldDiscussion.getResponsible());
|
||||||
discussion.getNotes().forEach(note -> updateNote(note, idAndNoteMap, userParticipatedInDiscussion));
|
discussion.setMergeRequest(oldDiscussion.getMergeRequest());
|
||||||
|
|
||||||
|
final Person responsiblePerson = discussion.getResponsible();
|
||||||
|
if (checkNotNull(responsiblePerson)) {
|
||||||
|
for (Note note : discussion.getNotes()) {
|
||||||
|
if (responsiblePerson.getId().equals(note.getAuthor().getId())) {
|
||||||
|
note.setAuthor(responsiblePerson);
|
||||||
|
}
|
||||||
|
final Person resolvedBy = note.getResolvedBy();
|
||||||
|
if (checkNotNull(resolvedBy)) {
|
||||||
|
if (responsiblePerson.getId().equals(resolvedBy.getId())) {
|
||||||
|
note.setResolvedBy(responsiblePerson);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
notifyUpdateNote(oldDiscussion, discussion);
|
||||||
|
|
||||||
final boolean resolved = discussion.getNotes().stream()
|
final boolean resolved = discussion.getNotes().stream()
|
||||||
.allMatch(note -> note.isResolvable() && note.getResolved());
|
.allMatch(note -> note.isResolvable() && note.getResolved());
|
||||||
|
|
||||||
discussion.setResolved(resolved);
|
discussion.setResolved(resolved);
|
||||||
|
|
||||||
return repository.save(discussion);
|
return repository.save(discussion);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateNote(Note note, Map<Long, Note> noteMap, boolean inDiscussion) {
|
@Override
|
||||||
if (noteMap.containsKey(note.getId())) {
|
public List<Discussion> updateAll(@NonNull List<Discussion> discussions) {
|
||||||
final Note oldNote = noteMap.get(note.getId());
|
return discussions.stream()
|
||||||
|
.map(this::update)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
if (note.isResolvable()) {
|
private void notifyUpdateNote(Discussion oldDiscussion, Discussion discussion) {
|
||||||
updateTask(note, oldNote);
|
final Map<Long, Note> noteMap = oldDiscussion
|
||||||
|
.getNotes().stream()
|
||||||
|
.collect(Collectors.toMap(Note::getId, n -> n));
|
||||||
|
|
||||||
|
// Пользователь участвовал в обсуждении
|
||||||
|
final boolean userParticipatedInDiscussion = oldDiscussion.getNotes().stream()
|
||||||
|
.anyMatch(note -> personInformation.getId().equals(note.getAuthor().getId()));
|
||||||
|
|
||||||
|
for (Note newNote : discussion.getNotes()) {
|
||||||
|
final Long newNoteId = newNote.getId();
|
||||||
|
if (noteMap.containsKey(newNoteId)) {
|
||||||
|
final Note oldNote = noteMap.get(newNoteId);
|
||||||
|
|
||||||
|
if (newNote.isResolvable()) {
|
||||||
|
updateTask(newNote, oldNote);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (inDiscussion) {
|
if (userParticipatedInDiscussion) {
|
||||||
notifyNewAnswer(note);
|
notifyNewAnswer(discussion, newNote);
|
||||||
} else {
|
} else {
|
||||||
notificationPersonal(note);
|
notificationPersonal(newNote);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void notifyNewAnswer(Note note) {
|
}
|
||||||
|
|
||||||
|
private void notifyNewAnswer(Discussion discussion, Note note) {
|
||||||
if (!personInformation.getId().equals(note.getAuthor().getId())) {
|
if (!personInformation.getId().equals(note.getAuthor().getId())) {
|
||||||
|
final Note firstNote = discussion.getFirstNote();
|
||||||
|
final Optional<Note> prevLastNote = discussion.getPrevLastNote();
|
||||||
|
|
||||||
|
|
||||||
|
final NewCommentNotify.NewCommentNotifyBuilder notifyBuilder = NewCommentNotify.builder();
|
||||||
|
|
||||||
|
if (prevLastNote.isPresent()) {
|
||||||
|
final Note prevNote = prevLastNote.get();
|
||||||
|
notifyBuilder.previousMessage(prevNote.getBody());
|
||||||
|
notifyBuilder.previousAuthor(prevNote.getAuthor().getName());
|
||||||
|
}
|
||||||
|
|
||||||
notifyService.send(
|
notifyService.send(
|
||||||
CommentNotify.builder()
|
notifyBuilder
|
||||||
.url(note.getWebUrl())
|
.url(note.getWebUrl())
|
||||||
|
.discussionMessage(firstNote.getBody())
|
||||||
|
.discussionAuthor(firstNote.getAuthor().getName())
|
||||||
.message(note.getBody())
|
.message(note.getBody())
|
||||||
.authorName(note.getAuthor().getName())
|
.authorName(note.getAuthor().getName())
|
||||||
.build()
|
.build()
|
||||||
@ -212,16 +277,16 @@ public class DiscussionServiceImpl implements DiscussionService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ExistsContainer<Discussion, String> existsById(@NonNull Set<String> discussionIds) {
|
public ExistContainer<Discussion, String> existsById(@NonNull Set<String> discussionIds) {
|
||||||
final List<Discussion> existsEntity = repository.findAllById(discussionIds);
|
final List<Discussion> existsEntity = repository.findAllById(discussionIds);
|
||||||
final Set<String> existsIds = existsEntity.stream().map(Discussion::getId).collect(Collectors.toSet());
|
final Set<String> existsIds = existsEntity.stream().map(Discussion::getId).collect(Collectors.toSet());
|
||||||
if (existsIds.containsAll(discussionIds)) {
|
if (existsIds.containsAll(discussionIds)) {
|
||||||
return dev.struchkov.bot.gitlab.context.domain.ExistsContainer.allFind(existsEntity);
|
return ExistContainer.allFind(existsEntity);
|
||||||
} else {
|
} else {
|
||||||
final Set<String> noExistsId = discussionIds.stream()
|
final Set<String> noExistsId = discussionIds.stream()
|
||||||
.filter(id -> !existsIds.contains(id))
|
.filter(id -> !existsIds.contains(id))
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
return ExistsContainer.notAllFind(existsEntity, noExistsId);
|
return ExistContainer.notAllFind(existsEntity, noExistsId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,7 +319,7 @@ public class DiscussionServiceImpl implements DiscussionService {
|
|||||||
}
|
}
|
||||||
if (recipientsLogins.contains(personInformation.getUsername())) {
|
if (recipientsLogins.contains(personInformation.getUsername())) {
|
||||||
notifyService.send(
|
notifyService.send(
|
||||||
CommentNotify.builder()
|
NewCommentNotify.builder()
|
||||||
.authorName(note.getAuthor().getName())
|
.authorName(note.getAuthor().getName())
|
||||||
.message(note.getBody())
|
.message(note.getBody())
|
||||||
.url(note.getWebUrl())
|
.url(note.getWebUrl())
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
package dev.struchkov.bot.gitlab.core.service.impl;
|
package dev.struchkov.bot.gitlab.core.service.impl;
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.ExistsContainer;
|
import dev.struchkov.bot.gitlab.context.domain.AssigneeChanged;
|
||||||
|
import dev.struchkov.bot.gitlab.context.domain.ExistContainer;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.IdAndStatusPr;
|
import dev.struchkov.bot.gitlab.context.domain.IdAndStatusPr;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.MergeRequestState;
|
import dev.struchkov.bot.gitlab.context.domain.MergeRequestState;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.PersonInformation;
|
import dev.struchkov.bot.gitlab.context.domain.PersonInformation;
|
||||||
|
import dev.struchkov.bot.gitlab.context.domain.ReviewerChanged;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.Discussion;
|
import dev.struchkov.bot.gitlab.context.domain.entity.Discussion;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.MergeRequest;
|
import dev.struchkov.bot.gitlab.context.domain.entity.MergeRequest;
|
||||||
|
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.Project;
|
import dev.struchkov.bot.gitlab.context.domain.entity.Project;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.filter.MergeRequestFilter;
|
import dev.struchkov.bot.gitlab.context.domain.filter.MergeRequestFilter;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.notify.pullrequest.ConflictPrNotify;
|
import dev.struchkov.bot.gitlab.context.domain.notify.pullrequest.ConflictPrNotify;
|
||||||
@ -16,7 +19,6 @@ import dev.struchkov.bot.gitlab.context.repository.MergeRequestRepository;
|
|||||||
import dev.struchkov.bot.gitlab.context.service.DiscussionService;
|
import dev.struchkov.bot.gitlab.context.service.DiscussionService;
|
||||||
import dev.struchkov.bot.gitlab.context.service.MergeRequestsService;
|
import dev.struchkov.bot.gitlab.context.service.MergeRequestsService;
|
||||||
import dev.struchkov.bot.gitlab.context.service.NotifyService;
|
import dev.struchkov.bot.gitlab.context.service.NotifyService;
|
||||||
import dev.struchkov.bot.gitlab.context.service.PersonService;
|
|
||||||
import dev.struchkov.bot.gitlab.context.service.ProjectService;
|
import dev.struchkov.bot.gitlab.context.service.ProjectService;
|
||||||
import dev.struchkov.bot.gitlab.core.service.impl.filter.MergeRequestFilterService;
|
import dev.struchkov.bot.gitlab.core.service.impl.filter.MergeRequestFilterService;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
@ -24,13 +26,15 @@ import lombok.RequiredArgsConstructor;
|
|||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static dev.struchkov.haiti.context.exception.NotFoundException.notFoundException;
|
import static dev.struchkov.haiti.context.exception.NotFoundException.notFoundException;
|
||||||
|
import static dev.struchkov.haiti.utils.Checker.checkNotEmpty;
|
||||||
|
import static dev.struchkov.haiti.utils.Checker.checkNotNull;
|
||||||
import static java.lang.Boolean.TRUE;
|
import static java.lang.Boolean.TRUE;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@ -39,7 +43,6 @@ public class MergeRequestsServiceImpl implements MergeRequestsService {
|
|||||||
|
|
||||||
private final NotifyService notifyService;
|
private final NotifyService notifyService;
|
||||||
private final MergeRequestRepository repository;
|
private final MergeRequestRepository repository;
|
||||||
private final PersonService personService;
|
|
||||||
private final MergeRequestFilterService filterService;
|
private final MergeRequestFilterService filterService;
|
||||||
private final ProjectService projectService;
|
private final ProjectService projectService;
|
||||||
private final DiscussionService discussionService;
|
private final DiscussionService discussionService;
|
||||||
@ -47,141 +50,156 @@ public class MergeRequestsServiceImpl implements MergeRequestsService {
|
|||||||
private final PersonInformation personInformation;
|
private final PersonInformation personInformation;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Transactional
|
||||||
public MergeRequest create(@NonNull MergeRequest mergeRequest) {
|
public MergeRequest create(@NonNull MergeRequest mergeRequest) {
|
||||||
if (mergeRequest.getAssignee() != null) {
|
|
||||||
personService.create(mergeRequest.getAssignee());
|
|
||||||
}
|
|
||||||
personService.create(mergeRequest.getAuthor());
|
|
||||||
|
|
||||||
mergeRequest.setNotification(true);
|
mergeRequest.setNotification(true);
|
||||||
|
|
||||||
final MergeRequest newMergeRequest = repository.save(mergeRequest);
|
final MergeRequest newMergeRequest = repository.save(mergeRequest);
|
||||||
|
|
||||||
notifyNewPr(newMergeRequest);
|
notifyNewMergeRequest(newMergeRequest);
|
||||||
|
|
||||||
return newMergeRequest;
|
return newMergeRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void notifyNewPr(MergeRequest newMergeRequest) {
|
/**
|
||||||
if (!personInformation.getId().equals(newMergeRequest.getAuthor().getId())) {
|
* Уведомление о новом MergeRequest.
|
||||||
|
*
|
||||||
|
* @param savedMergeRequest сохраненный в базу новый MergeRequest.
|
||||||
|
*/
|
||||||
|
private void notifyNewMergeRequest(MergeRequest savedMergeRequest) {
|
||||||
|
notifyUserAboutNewPullRequestIfHeIsReviewer(savedMergeRequest);
|
||||||
|
notifyUserAboutNewPullRequestIfHeIsAssignee(savedMergeRequest);
|
||||||
|
}
|
||||||
|
|
||||||
final String projectName = projectService.getByIdOrThrow(newMergeRequest.getProjectId()).getName();
|
private void notifyUserAboutNewPullRequestIfHeIsAssignee(MergeRequest savedMergeRequest) {
|
||||||
if (!newMergeRequest.isConflict()) {
|
final Long gitlabUserId = personInformation.getId();
|
||||||
|
final Person assignee = savedMergeRequest.getAssignee();
|
||||||
|
final Person author = savedMergeRequest.getAuthor();
|
||||||
|
|
||||||
|
if (checkNotNull(assignee)) {
|
||||||
|
if (gitlabUserId.equals(assignee.getId()) && !isAuthorSameAssignee(author, assignee)) {
|
||||||
|
final String projectName = projectService.getByIdOrThrow(savedMergeRequest.getProjectId()).getName();
|
||||||
|
if (!savedMergeRequest.isConflict()) {
|
||||||
|
//TODO [05.12.2022|uPagge]: Заменить уведомление. Нужно создать новое уведомление, если пользователя назначали ответственным
|
||||||
notifyService.send(
|
notifyService.send(
|
||||||
NewPrNotify.builder()
|
NewPrNotify.builder()
|
||||||
.projectName(projectName)
|
.projectName(projectName)
|
||||||
.labels(newMergeRequest.getLabels())
|
.labels(savedMergeRequest.getLabels())
|
||||||
.author(newMergeRequest.getAuthor().getName())
|
.author(author.getName())
|
||||||
.description(newMergeRequest.getDescription())
|
.description(savedMergeRequest.getDescription())
|
||||||
.title(newMergeRequest.getTitle())
|
.title(savedMergeRequest.getTitle())
|
||||||
.url(newMergeRequest.getWebUrl())
|
.url(savedMergeRequest.getWebUrl())
|
||||||
.targetBranch(newMergeRequest.getTargetBranch())
|
.targetBranch(savedMergeRequest.getTargetBranch())
|
||||||
.sourceBranch(newMergeRequest.getSourceBranch())
|
.sourceBranch(savedMergeRequest.getSourceBranch())
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Создатель MR является ответственным за этот MR
|
||||||
|
*
|
||||||
|
* @return true, если автор и ответственный один и тот же человек.
|
||||||
|
*/
|
||||||
|
private boolean isAuthorSameAssignee(Person author, Person assignee) {
|
||||||
|
return author.getId().equals(assignee.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void notifyUserAboutNewPullRequestIfHeIsReviewer(MergeRequest savedMergeRequest) {
|
||||||
|
final List<Person> reviewers = savedMergeRequest.getReviewers();
|
||||||
|
final Long gitlabUserId = personInformation.getId();
|
||||||
|
|
||||||
|
if (checkNotEmpty(reviewers)) {
|
||||||
|
final boolean isUserInReviewers = reviewers.stream()
|
||||||
|
.anyMatch(reviewer -> gitlabUserId.equals(reviewer.getId()));
|
||||||
|
if (isUserInReviewers) {
|
||||||
|
final String projectName = projectService.getByIdOrThrow(savedMergeRequest.getProjectId()).getName();
|
||||||
|
if (!savedMergeRequest.isConflict()) {
|
||||||
|
sendNotifyAboutNewMr(savedMergeRequest, projectName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendNotifyAboutNewMr(MergeRequest savedMergeRequest, String projectName) {
|
||||||
|
notifyService.send(
|
||||||
|
NewPrNotify.builder()
|
||||||
|
.projectName(projectName)
|
||||||
|
.labels(savedMergeRequest.getLabels())
|
||||||
|
.author(savedMergeRequest.getAuthor().getName())
|
||||||
|
.description(savedMergeRequest.getDescription())
|
||||||
|
.title(savedMergeRequest.getTitle())
|
||||||
|
.url(savedMergeRequest.getWebUrl())
|
||||||
|
.targetBranch(savedMergeRequest.getTargetBranch())
|
||||||
|
.sourceBranch(savedMergeRequest.getSourceBranch())
|
||||||
.build()
|
.build()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Transactional
|
||||||
public MergeRequest update(@NonNull MergeRequest mergeRequest) {
|
public MergeRequest update(@NonNull MergeRequest mergeRequest) {
|
||||||
if (mergeRequest.getAssignee() != null) {
|
|
||||||
personService.create(mergeRequest.getAssignee());
|
|
||||||
}
|
|
||||||
personService.create(mergeRequest.getAuthor());
|
|
||||||
|
|
||||||
final MergeRequest oldMergeRequest = repository.findById(mergeRequest.getId())
|
final MergeRequest oldMergeRequest = repository.findById(mergeRequest.getId())
|
||||||
.orElseThrow(notFoundException("МержРеквест не найден"));
|
.orElseThrow(notFoundException("MergeRequest не найден"));
|
||||||
|
|
||||||
if (mergeRequest.getNotification() == null) {
|
final Boolean notification = oldMergeRequest.getNotification();
|
||||||
|
if (checkNotNull(notification)) {
|
||||||
mergeRequest.setNotification(oldMergeRequest.getNotification());
|
mergeRequest.setNotification(oldMergeRequest.getNotification());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!oldMergeRequest.getUpdatedDate().equals(mergeRequest.getUpdatedDate()) || oldMergeRequest.isConflict() != mergeRequest.isConflict()) {
|
final Long gitlabUserId = personInformation.getId();
|
||||||
|
final AssigneeChanged assigneeChanged = AssigneeChanged.valueOf(gitlabUserId, oldMergeRequest.getAssignee(), mergeRequest.getAssignee());
|
||||||
|
final ReviewerChanged reviewerChanged = ReviewerChanged.valueOf(gitlabUserId, oldMergeRequest.getReviewers(), mergeRequest.getReviewers());
|
||||||
|
|
||||||
|
final boolean isChangedMr =
|
||||||
|
!oldMergeRequest.getUpdatedDate().equals(mergeRequest.getUpdatedDate())
|
||||||
|
|| oldMergeRequest.isConflict() != mergeRequest.isConflict();
|
||||||
|
final boolean isChangedLinkedEntity = reviewerChanged.isChanged() || assigneeChanged.isChanged();
|
||||||
|
|
||||||
|
if (isChangedMr || isChangedLinkedEntity) {
|
||||||
final Project project = projectService.getByIdOrThrow(mergeRequest.getProjectId());
|
final Project project = projectService.getByIdOrThrow(mergeRequest.getProjectId());
|
||||||
|
|
||||||
if (TRUE.equals(oldMergeRequest.getNotification())) {
|
if (TRUE.equals(notification) && isChangedMr) {
|
||||||
notifyStatus(oldMergeRequest, mergeRequest, project);
|
notifyAboutStatus(oldMergeRequest, mergeRequest, project);
|
||||||
notifyConflict(oldMergeRequest, mergeRequest, project);
|
notifyAboutConflict(oldMergeRequest, mergeRequest, project);
|
||||||
notifyUpdate(oldMergeRequest, mergeRequest, project);
|
notifyAboutUpdate(oldMergeRequest, mergeRequest, project);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TRUE.equals(notification) && isChangedLinkedEntity) {
|
||||||
|
notifyReviewer(reviewerChanged, mergeRequest, project);
|
||||||
|
notifyAssignee(assigneeChanged, mergeRequest, project);
|
||||||
}
|
}
|
||||||
|
|
||||||
return repository.save(mergeRequest);
|
return repository.save(mergeRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
return oldMergeRequest;
|
return oldMergeRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void notifyUpdate(MergeRequest oldMergeRequest, MergeRequest mergeRequest, Project project) {
|
|
||||||
if (
|
//TODO [05.12.2022|uPagge]: Добавить уведомление, если происходит удаление
|
||||||
!personInformation.getId().equals(mergeRequest.getAuthor().getId())
|
private void notifyAssignee(AssigneeChanged assigneeChanged, MergeRequest mergeRequest, Project project) {
|
||||||
&& !oldMergeRequest.getDateLastCommit().equals(mergeRequest.getDateLastCommit())
|
switch (assigneeChanged) {
|
||||||
&& !mergeRequest.isConflict()
|
case BECOME -> sendNotifyAboutNewMr(mergeRequest, project.getName());
|
||||||
) {
|
|
||||||
final List<Discussion> discussions = discussionService.getAllByMergeRequestId(oldMergeRequest.getId())
|
|
||||||
.stream()
|
|
||||||
.filter(discussion -> Objects.nonNull(discussion.getResponsible()))
|
|
||||||
.toList();
|
|
||||||
final long allTask = discussions.size();
|
|
||||||
final long resolvedTask = discussions.stream()
|
|
||||||
.filter(Discussion::getResolved)
|
|
||||||
.count();
|
|
||||||
final long allYouTasks = discussions.stream()
|
|
||||||
.filter(discussion -> personInformation.getId().equals(discussion.getFirstNote().getAuthor().getId()))
|
|
||||||
.count();
|
|
||||||
final long resolvedYouTask = discussions.stream()
|
|
||||||
.filter(discussion -> personInformation.getId().equals(discussion.getFirstNote().getAuthor().getId()) && discussion.getResolved())
|
|
||||||
.count();
|
|
||||||
notifyService.send(
|
|
||||||
UpdatePrNotify.builder()
|
|
||||||
.author(oldMergeRequest.getAuthor().getName())
|
|
||||||
.name(oldMergeRequest.getTitle())
|
|
||||||
.projectKey(project.getName())
|
|
||||||
.url(oldMergeRequest.getWebUrl())
|
|
||||||
.allTasks(allTask)
|
|
||||||
.allResolvedTasks(resolvedTask)
|
|
||||||
.personTasks(allYouTasks)
|
|
||||||
.personResolvedTasks(resolvedYouTask)
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void notifyConflict(MergeRequest oldMergeRequest, MergeRequest mergeRequest, Project project) {
|
//TODO [05.12.2022|uPagge]: Добавить уведомление, если происходит удаление ревьювера
|
||||||
if (
|
//TODO [05.12.2022|uPagge]: Заменить тип уведомления на самостоятельный
|
||||||
!oldMergeRequest.isConflict()
|
private void notifyReviewer(ReviewerChanged reviewerChanged, MergeRequest mergeRequest, Project project) {
|
||||||
&& mergeRequest.isConflict()
|
switch (reviewerChanged) {
|
||||||
&& personInformation.getId().equals(oldMergeRequest.getAuthor().getId())
|
case BECOME -> sendNotifyAboutNewMr(mergeRequest, project.getName());
|
||||||
) {
|
|
||||||
notifyService.send(
|
|
||||||
ConflictPrNotify.builder()
|
|
||||||
.sourceBranch(oldMergeRequest.getSourceBranch())
|
|
||||||
.name(mergeRequest.getTitle())
|
|
||||||
.url(mergeRequest.getWebUrl())
|
|
||||||
.projectKey(project.getName())
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void notifyStatus(MergeRequest oldMergeRequest, MergeRequest newMergeRequest, Project project) {
|
@Override
|
||||||
final MergeRequestState oldStatus = oldMergeRequest.getState();
|
@Transactional
|
||||||
final MergeRequestState newStatus = newMergeRequest.getState();
|
public List<MergeRequest> updateAll(@NonNull List<MergeRequest> mergeRequests) {
|
||||||
if (
|
return mergeRequests.stream()
|
||||||
!oldStatus.equals(newStatus)
|
.map(this::update)
|
||||||
&& oldMergeRequest.getAuthor().getId().equals(personInformation.getId())
|
.collect(Collectors.toList());
|
||||||
) {
|
|
||||||
|
|
||||||
notifyService.send(
|
|
||||||
StatusPrNotify.builder()
|
|
||||||
.name(newMergeRequest.getTitle())
|
|
||||||
.url(oldMergeRequest.getWebUrl())
|
|
||||||
.projectName(project.getName())
|
|
||||||
.newStatus(newStatus)
|
|
||||||
.oldStatus(oldStatus)
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -200,16 +218,16 @@ public class MergeRequestsServiceImpl implements MergeRequestsService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ExistsContainer<MergeRequest, Long> existsById(@NonNull Set<Long> mergeRequestIds) {
|
public ExistContainer<MergeRequest, Long> existsById(@NonNull Set<Long> mergeRequestIds) {
|
||||||
final List<MergeRequest> existsEntity = repository.findAllById(mergeRequestIds);
|
final List<MergeRequest> existsEntity = repository.findAllById(mergeRequestIds);
|
||||||
final Set<Long> existsIds = existsEntity.stream().map(MergeRequest::getId).collect(Collectors.toSet());
|
final Set<Long> existsIds = existsEntity.stream().map(MergeRequest::getId).collect(Collectors.toSet());
|
||||||
if (existsIds.containsAll(mergeRequestIds)) {
|
if (existsIds.containsAll(mergeRequestIds)) {
|
||||||
return ExistsContainer.allFind(existsEntity);
|
return ExistContainer.allFind(existsEntity);
|
||||||
} else {
|
} else {
|
||||||
final Set<Long> noExistsId = mergeRequestIds.stream()
|
final Set<Long> noExistsId = mergeRequestIds.stream()
|
||||||
.filter(id -> !existsIds.contains(id))
|
.filter(id -> !existsIds.contains(id))
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
return ExistsContainer.notAllFind(existsEntity, noExistsId);
|
return ExistContainer.notAllFind(existsEntity, noExistsId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,8 +239,96 @@ public class MergeRequestsServiceImpl implements MergeRequestsService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Transactional
|
||||||
public void deleteAllById(@NonNull Set<Long> mergeRequestIds) {
|
public void deleteAllById(@NonNull Set<Long> mergeRequestIds) {
|
||||||
repository.deleteByIds(mergeRequestIds);
|
repository.deleteByIds(mergeRequestIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<MergeRequest> getAllByReviewerId(@NonNull Long personId) {
|
||||||
|
return repository.findAllByReviewerId(personId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void notifyAboutUpdate(MergeRequest oldMergeRequest, MergeRequest mergeRequest, Project project) {
|
||||||
|
final Long botUserGitlabId = personInformation.getId();
|
||||||
|
|
||||||
|
if (
|
||||||
|
!botUserGitlabId.equals(mergeRequest.getAuthor().getId()) // Автор MR не пользователь приложения
|
||||||
|
&& !oldMergeRequest.getDateLastCommit().equals(mergeRequest.getDateLastCommit()) // Изменилась дата последнего коммита
|
||||||
|
&& !mergeRequest.isConflict() // MR не находится в состоянии конфликта
|
||||||
|
) {
|
||||||
|
|
||||||
|
long allTask = 0;
|
||||||
|
long resolvedTask = 0;
|
||||||
|
long allYouTasks = 0;
|
||||||
|
long resolvedYouTask = 0;
|
||||||
|
final List<Discussion> discussions = discussionService.getAllByMergeRequestId(oldMergeRequest.getId());
|
||||||
|
for (Discussion discussion : discussions) {
|
||||||
|
if (checkNotNull(discussion.getResponsible())) {
|
||||||
|
final boolean isBotUserAuthorDiscussion = botUserGitlabId.equals(discussion.getFirstNote().getAuthor().getId());
|
||||||
|
allTask += 1;
|
||||||
|
if (isBotUserAuthorDiscussion) {
|
||||||
|
allYouTasks += 1;
|
||||||
|
}
|
||||||
|
if (TRUE.equals(discussion.getResolved())) {
|
||||||
|
resolvedTask += 1;
|
||||||
|
if (isBotUserAuthorDiscussion) {
|
||||||
|
resolvedYouTask += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
notifyService.send(
|
||||||
|
UpdatePrNotify.builder()
|
||||||
|
.author(oldMergeRequest.getAuthor().getName())
|
||||||
|
.name(oldMergeRequest.getTitle())
|
||||||
|
.projectKey(project.getName())
|
||||||
|
.url(oldMergeRequest.getWebUrl())
|
||||||
|
.allTasks(allTask)
|
||||||
|
.allResolvedTasks(resolvedTask)
|
||||||
|
.personTasks(allYouTasks)
|
||||||
|
.personResolvedTasks(resolvedYouTask)
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void notifyAboutConflict(MergeRequest oldMergeRequest, MergeRequest mergeRequest, Project project) {
|
||||||
|
final Long gitlabUserId = personInformation.getId();
|
||||||
|
if (
|
||||||
|
!oldMergeRequest.isConflict() // У старого MR не было конфликта
|
||||||
|
&& mergeRequest.isConflict() // А у нового есть
|
||||||
|
&& gitlabUserId.equals(oldMergeRequest.getAuthor().getId()) // и MR создан пользователем бота
|
||||||
|
) {
|
||||||
|
notifyService.send(
|
||||||
|
ConflictPrNotify.builder()
|
||||||
|
.sourceBranch(oldMergeRequest.getSourceBranch())
|
||||||
|
.name(mergeRequest.getTitle())
|
||||||
|
.url(mergeRequest.getWebUrl())
|
||||||
|
.projectKey(project.getName())
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void notifyAboutStatus(MergeRequest oldMergeRequest, MergeRequest newMergeRequest, Project project) {
|
||||||
|
final MergeRequestState oldStatus = oldMergeRequest.getState();
|
||||||
|
final MergeRequestState newStatus = newMergeRequest.getState();
|
||||||
|
final Long gitlabUserId = personInformation.getId();
|
||||||
|
if (
|
||||||
|
!oldStatus.equals(newStatus) // статус изменился
|
||||||
|
&& gitlabUserId.equals(oldMergeRequest.getAuthor().getId()) // создатель MR является пользователем бота
|
||||||
|
) {
|
||||||
|
notifyService.send(
|
||||||
|
StatusPrNotify.builder()
|
||||||
|
.name(newMergeRequest.getTitle())
|
||||||
|
.url(oldMergeRequest.getWebUrl())
|
||||||
|
.projectName(project.getName())
|
||||||
|
.newStatus(newStatus)
|
||||||
|
.oldStatus(oldStatus)
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package dev.struchkov.bot.gitlab.core.service.impl;
|
package dev.struchkov.bot.gitlab.core.service.impl;
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.ExistsContainer;
|
import dev.struchkov.bot.gitlab.context.domain.ExistContainer;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
||||||
import dev.struchkov.bot.gitlab.context.repository.PersonRepository;
|
import dev.struchkov.bot.gitlab.context.repository.PersonRepository;
|
||||||
import dev.struchkov.bot.gitlab.context.service.PersonService;
|
import dev.struchkov.bot.gitlab.context.service.PersonService;
|
||||||
@ -40,16 +40,16 @@ public class PersonServiceImpl implements PersonService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ExistsContainer<Person, Long> existsById(Set<Long> personIds) {
|
public ExistContainer<Person, Long> existsById(Set<Long> personIds) {
|
||||||
final List<Person> existsEntity = repository.findAllById(personIds);
|
final List<Person> existsEntity = repository.findAllById(personIds);
|
||||||
final Set<Long> existsIds = existsEntity.stream().map(Person::getId).collect(Collectors.toSet());
|
final Set<Long> existsIds = existsEntity.stream().map(Person::getId).collect(Collectors.toSet());
|
||||||
if (existsIds.containsAll(personIds)) {
|
if (existsIds.containsAll(personIds)) {
|
||||||
return ExistsContainer.allFind(existsEntity);
|
return ExistContainer.allFind(existsEntity);
|
||||||
} else {
|
} else {
|
||||||
final Set<Long> noExistsId = personIds.stream()
|
final Set<Long> noExistsId = personIds.stream()
|
||||||
.filter(id -> !existsIds.contains(id))
|
.filter(id -> !existsIds.contains(id))
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
return ExistsContainer.notAllFind(existsEntity, noExistsId);
|
return ExistContainer.notAllFind(existsEntity, noExistsId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package dev.struchkov.bot.gitlab.core.service.impl;
|
package dev.struchkov.bot.gitlab.core.service.impl;
|
||||||
|
|
||||||
|
import dev.struchkov.bot.gitlab.context.domain.ExistContainer;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.PersonInformation;
|
import dev.struchkov.bot.gitlab.context.domain.PersonInformation;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.PipelineStatus;
|
import dev.struchkov.bot.gitlab.context.domain.PipelineStatus;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
||||||
@ -8,15 +9,14 @@ import dev.struchkov.bot.gitlab.context.domain.filter.PipelineFilter;
|
|||||||
import dev.struchkov.bot.gitlab.context.domain.notify.pipeline.PipelineNotify;
|
import dev.struchkov.bot.gitlab.context.domain.notify.pipeline.PipelineNotify;
|
||||||
import dev.struchkov.bot.gitlab.context.repository.PipelineRepository;
|
import dev.struchkov.bot.gitlab.context.repository.PipelineRepository;
|
||||||
import dev.struchkov.bot.gitlab.context.service.NotifyService;
|
import dev.struchkov.bot.gitlab.context.service.NotifyService;
|
||||||
import dev.struchkov.bot.gitlab.context.service.PersonService;
|
|
||||||
import dev.struchkov.bot.gitlab.context.service.PipelineService;
|
import dev.struchkov.bot.gitlab.context.service.PipelineService;
|
||||||
import dev.struchkov.bot.gitlab.core.service.impl.filter.PipelineFilterService;
|
import dev.struchkov.bot.gitlab.core.service.impl.filter.PipelineFilterService;
|
||||||
import dev.struchkov.haiti.context.domain.ExistsContainer;
|
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@ -27,6 +27,7 @@ import static dev.struchkov.bot.gitlab.context.domain.PipelineStatus.FAILED;
|
|||||||
import static dev.struchkov.bot.gitlab.context.domain.PipelineStatus.SKIPPED;
|
import static dev.struchkov.bot.gitlab.context.domain.PipelineStatus.SKIPPED;
|
||||||
import static dev.struchkov.bot.gitlab.context.domain.PipelineStatus.SUCCESS;
|
import static dev.struchkov.bot.gitlab.context.domain.PipelineStatus.SUCCESS;
|
||||||
import static dev.struchkov.haiti.context.exception.NotFoundException.notFoundException;
|
import static dev.struchkov.haiti.context.exception.NotFoundException.notFoundException;
|
||||||
|
import static dev.struchkov.haiti.utils.Checker.checkNotNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Реализация сервиса для работы с пайплайнами.
|
* Реализация сервиса для работы с пайплайнами.
|
||||||
@ -42,14 +43,13 @@ public class PipelineServiceImpl implements PipelineService {
|
|||||||
|
|
||||||
private final NotifyService notifyService;
|
private final NotifyService notifyService;
|
||||||
private final PipelineRepository repository;
|
private final PipelineRepository repository;
|
||||||
private final PersonService personService;
|
|
||||||
private final PipelineFilterService pipelineFilterService;
|
private final PipelineFilterService pipelineFilterService;
|
||||||
|
|
||||||
private final PersonInformation personInformation;
|
private final PersonInformation personInformation;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Transactional
|
||||||
public Pipeline create(@NonNull Pipeline pipeline) {
|
public Pipeline create(@NonNull Pipeline pipeline) {
|
||||||
personService.create(pipeline.getPerson());
|
|
||||||
final Pipeline newPipeline = repository.save(pipeline);
|
final Pipeline newPipeline = repository.save(pipeline);
|
||||||
notifyNewPipeline(pipeline, "n/a");
|
notifyNewPipeline(pipeline, "n/a");
|
||||||
return newPipeline;
|
return newPipeline;
|
||||||
@ -87,7 +87,7 @@ public class PipelineServiceImpl implements PipelineService {
|
|||||||
private boolean isNeedNotifyNewPipeline(@NonNull Pipeline pipeline) {
|
private boolean isNeedNotifyNewPipeline(@NonNull Pipeline pipeline) {
|
||||||
final Person personPipelineCreator = pipeline.getPerson();
|
final Person personPipelineCreator = pipeline.getPerson();
|
||||||
return notificationStatus.contains(pipeline.getStatus()) // Пайплайн имеет статус необходимый для уведомления
|
return notificationStatus.contains(pipeline.getStatus()) // Пайплайн имеет статус необходимый для уведомления
|
||||||
&& personPipelineCreator != null
|
&& checkNotNull(personPipelineCreator) // Создатель пайплайна не null
|
||||||
&& personInformation.getId().equals(personPipelineCreator.getId()); // Пользователь приложения является инициатором пайплайна
|
&& personInformation.getId().equals(personPipelineCreator.getId()); // Пользователь приложения является инициатором пайплайна
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,16 +102,16 @@ public class PipelineServiceImpl implements PipelineService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ExistsContainer<Pipeline, Long> existsById(@NonNull Set<Long> pipelineIds) {
|
public ExistContainer<Pipeline, Long> existsById(@NonNull Set<Long> pipelineIds) {
|
||||||
final List<Pipeline> existsEntity = repository.findAllById(pipelineIds);
|
final List<Pipeline> existsEntity = repository.findAllById(pipelineIds);
|
||||||
final Set<Long> existsIds = existsEntity.stream().map(Pipeline::getId).collect(Collectors.toSet());
|
final Set<Long> existsIds = existsEntity.stream().map(Pipeline::getId).collect(Collectors.toSet());
|
||||||
if (existsIds.containsAll(pipelineIds)) {
|
if (existsIds.containsAll(pipelineIds)) {
|
||||||
return ExistsContainer.allFind(existsEntity);
|
return ExistContainer.allFind(existsEntity);
|
||||||
} else {
|
} else {
|
||||||
final Set<Long> noExistsId = pipelineIds.stream()
|
final Set<Long> noExistsId = pipelineIds.stream()
|
||||||
.filter(id -> !existsIds.contains(id))
|
.filter(id -> !existsIds.contains(id))
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
return ExistsContainer.notAllFind(existsEntity, noExistsId);
|
return ExistContainer.notAllFind(existsEntity, noExistsId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package dev.struchkov.bot.gitlab.core.service.impl;
|
package dev.struchkov.bot.gitlab.core.service.impl;
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.ExistsContainer;
|
import dev.struchkov.bot.gitlab.context.domain.ExistContainer;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.PersonInformation;
|
import dev.struchkov.bot.gitlab.context.domain.PersonInformation;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.Project;
|
import dev.struchkov.bot.gitlab.context.domain.entity.Project;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.notify.NewProjectNotify;
|
import dev.struchkov.bot.gitlab.context.domain.notify.NewProjectNotify;
|
||||||
@ -13,6 +13,7 @@ import lombok.RequiredArgsConstructor;
|
|||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@ -34,12 +35,15 @@ public class ProjectServiceImpl implements ProjectService {
|
|||||||
private final PersonInformation personInformation;
|
private final PersonInformation personInformation;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Transactional
|
||||||
public Project create(@NonNull Project project) {
|
public Project create(@NonNull Project project) {
|
||||||
final Project newProject = repository.save(project);
|
final Project newProject = repository.save(project);
|
||||||
|
|
||||||
if (!personInformation.getId().equals(newProject.getCreatorId())) {
|
final Long gitlabUserId = personInformation.getId();
|
||||||
|
|
||||||
|
if (!gitlabUserId.equals(newProject.getCreatorId())) {
|
||||||
final String authorName = personService.getByIdOrThrown(newProject.getCreatorId()).getName();
|
final String authorName = personService.getByIdOrThrown(newProject.getCreatorId()).getName();
|
||||||
sendNotifyNewProject(newProject, authorName);
|
notifyAboutNewProject(newProject, authorName);
|
||||||
}
|
}
|
||||||
|
|
||||||
return newProject;
|
return newProject;
|
||||||
@ -74,20 +78,20 @@ public class ProjectServiceImpl implements ProjectService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ExistsContainer<Project, Long> existsById(Set<Long> projectIds) {
|
public ExistContainer<Project, Long> existsById(Set<Long> projectIds) {
|
||||||
final List<Project> existsEntity = repository.findAllById(projectIds);
|
final List<Project> existsEntity = repository.findAllById(projectIds);
|
||||||
final Set<Long> existsIds = existsEntity.stream().map(Project::getId).collect(Collectors.toSet());
|
final Set<Long> existsIds = existsEntity.stream().map(Project::getId).collect(Collectors.toSet());
|
||||||
if (existsIds.containsAll(projectIds)) {
|
if (existsIds.containsAll(projectIds)) {
|
||||||
return ExistsContainer.allFind(existsEntity);
|
return ExistContainer.allFind(existsEntity);
|
||||||
} else {
|
} else {
|
||||||
final Set<Long> noExistsId = projectIds.stream()
|
final Set<Long> noExistsId = projectIds.stream()
|
||||||
.filter(id -> !existsIds.contains(id))
|
.filter(id -> !existsIds.contains(id))
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
return ExistsContainer.notAllFind(existsEntity, noExistsId);
|
return ExistContainer.notAllFind(existsEntity, noExistsId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendNotifyNewProject(Project newProject, String authorName) {
|
private void notifyAboutNewProject(Project newProject, String authorName) {
|
||||||
notifyService.send(
|
notifyService.send(
|
||||||
NewProjectNotify.builder()
|
NewProjectNotify.builder()
|
||||||
.projectDescription(newProject.getDescription())
|
.projectDescription(newProject.getDescription())
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
package dev.struchkov.bot.gitlab.core.service.parser;
|
package dev.struchkov.bot.gitlab.core.service.parser;
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.ExistsContainer;
|
import dev.struchkov.bot.gitlab.context.domain.ExistContainer;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.Discussion;
|
import dev.struchkov.bot.gitlab.context.domain.entity.Discussion;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.MergeRequest;
|
import dev.struchkov.bot.gitlab.context.domain.entity.MergeRequest;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.Note;
|
import dev.struchkov.bot.gitlab.context.domain.entity.Note;
|
||||||
|
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
||||||
import dev.struchkov.bot.gitlab.context.service.DiscussionService;
|
import dev.struchkov.bot.gitlab.context.service.DiscussionService;
|
||||||
import dev.struchkov.bot.gitlab.context.service.MergeRequestsService;
|
import dev.struchkov.bot.gitlab.context.service.MergeRequestsService;
|
||||||
import dev.struchkov.bot.gitlab.core.config.properties.GitlabProperty;
|
import dev.struchkov.bot.gitlab.core.config.properties.GitlabProperty;
|
||||||
@ -17,13 +18,20 @@ import org.springframework.data.domain.PageRequest;
|
|||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import static dev.struchkov.bot.gitlab.core.utils.StringUtils.H_PRIVATE_TOKEN;
|
import static dev.struchkov.bot.gitlab.core.utils.StringUtils.H_PRIVATE_TOKEN;
|
||||||
|
import static dev.struchkov.haiti.utils.Checker.checkNotEmpty;
|
||||||
|
import static dev.struchkov.haiti.utils.Checker.checkNotNull;
|
||||||
|
import static dev.struchkov.haiti.utils.Checker.checkNull;
|
||||||
import static dev.struchkov.haiti.utils.network.HttpParse.ACCEPT;
|
import static dev.struchkov.haiti.utils.network.HttpParse.ACCEPT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -52,8 +60,12 @@ public class DiscussionParser {
|
|||||||
Page<MergeRequest> mergeRequestSheet = mergeRequestsService.getAll(PageRequest.of(page, COUNT));
|
Page<MergeRequest> mergeRequestSheet = mergeRequestsService.getAll(PageRequest.of(page, COUNT));
|
||||||
|
|
||||||
while (mergeRequestSheet.hasContent()) {
|
while (mergeRequestSheet.hasContent()) {
|
||||||
mergeRequestSheet.getContent()
|
final List<MergeRequest> mergeRequests = mergeRequestSheet.getContent();
|
||||||
.forEach(this::processingMergeRequest);
|
|
||||||
|
for (MergeRequest mergeRequest : mergeRequests) {
|
||||||
|
processingMergeRequest(mergeRequest);
|
||||||
|
}
|
||||||
|
|
||||||
mergeRequestSheet = mergeRequestsService.getAll(PageRequest.of(++page, COUNT));
|
mergeRequestSheet = mergeRequestsService.getAll(PageRequest.of(++page, COUNT));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -75,10 +87,10 @@ public class DiscussionParser {
|
|||||||
.map(DiscussionJson::getId)
|
.map(DiscussionJson::getId)
|
||||||
.collect(Collectors.toUnmodifiableSet());
|
.collect(Collectors.toUnmodifiableSet());
|
||||||
|
|
||||||
final ExistsContainer<Discussion, String> existsContainer = discussionService.existsById(discussionIds);
|
final ExistContainer<Discussion, String> existContainer = discussionService.existsById(discussionIds);
|
||||||
if (!existsContainer.isAllFound()) {
|
if (!existContainer.isAllFound()) {
|
||||||
final List<Discussion> newDiscussions = discussionJson.stream()
|
final List<Discussion> newDiscussions = discussionJson.stream()
|
||||||
.filter(json -> existsContainer.getIdNoFound().contains(json.getId()))
|
.filter(json -> existContainer.getIdNoFound().contains(json.getId()))
|
||||||
.map(json -> {
|
.map(json -> {
|
||||||
final Discussion discussion = conversionService.convert(json, Discussion.class);
|
final Discussion discussion = conversionService.convert(json, Discussion.class);
|
||||||
discussion.setMergeRequest(mergeRequest);
|
discussion.setMergeRequest(mergeRequest);
|
||||||
@ -86,10 +98,53 @@ public class DiscussionParser {
|
|||||||
discussion.getNotes().forEach(createNoteLink(mergeRequest));
|
discussion.getNotes().forEach(createNoteLink(mergeRequest));
|
||||||
return discussion;
|
return discussion;
|
||||||
})
|
})
|
||||||
.filter(discussion -> discussion.getNotes() != null && !discussion.getNotes().isEmpty())
|
// Фильтрация специально стоит после map(). Таким образом отбрасываются системные уведомления
|
||||||
|
.filter(discussion -> checkNotEmpty(discussion.getNotes()))
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
|
if (checkNotEmpty(newDiscussions)) {
|
||||||
|
personMapping(newDiscussions);
|
||||||
discussionService.createAll(newDiscussions);
|
discussionService.createAll(newDiscussions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void personMapping(List<Discussion> newDiscussions) {
|
||||||
|
final Stream<Person> firstStream = Stream.concat(
|
||||||
|
newDiscussions.stream()
|
||||||
|
.flatMap(discussion -> discussion.getNotes().stream())
|
||||||
|
.map(Note::getResolvedBy)
|
||||||
|
.filter(Objects::nonNull),
|
||||||
|
newDiscussions.stream()
|
||||||
|
.flatMap(discussion -> discussion.getNotes().stream())
|
||||||
|
.map(Note::getAuthor)
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
);
|
||||||
|
|
||||||
|
final Map<Long, Person> personMap = Stream.concat(
|
||||||
|
firstStream,
|
||||||
|
newDiscussions.stream()
|
||||||
|
.map(Discussion::getResponsible)
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
).distinct()
|
||||||
|
.collect(Collectors.toMap(Person::getId, p -> p));
|
||||||
|
|
||||||
|
for (Discussion newDiscussion : newDiscussions) {
|
||||||
|
final Person responsible = newDiscussion.getResponsible();
|
||||||
|
if (checkNotNull(responsible)) {
|
||||||
|
newDiscussion.setResponsible(personMap.get(responsible.getId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Note note : newDiscussion.getNotes()) {
|
||||||
|
note.setAuthor(personMap.get(note.getAuthor().getId()));
|
||||||
|
|
||||||
|
final Person resolvedBy = note.getResolvedBy();
|
||||||
|
if (checkNotNull(resolvedBy)) {
|
||||||
|
note.setResolvedBy(personMap.get(resolvedBy.getId()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -97,31 +152,45 @@ public class DiscussionParser {
|
|||||||
*/
|
*/
|
||||||
public void scanOldDiscussions() {
|
public void scanOldDiscussions() {
|
||||||
int page = 0;
|
int page = 0;
|
||||||
Page<Discussion> discussionSheet = discussionService.getAll(PageRequest.of(page, COUNT));
|
Page<Discussion> discussionPage = discussionService.getAll(PageRequest.of(page, COUNT));
|
||||||
|
|
||||||
while (discussionSheet.hasContent()) {
|
while (discussionPage.hasContent()) {
|
||||||
final List<Discussion> discussions = discussionSheet.getContent();
|
final List<Discussion> discussions = discussionPage.getContent();
|
||||||
|
|
||||||
|
// Удаляем обсуждения, которые потеряли свои MR
|
||||||
|
//TODO [05.12.2022|uPagge]: Проверить целесообразность этого действия
|
||||||
|
discussions.stream()
|
||||||
|
.filter(discussion -> checkNull(discussion.getMergeRequest()))
|
||||||
|
.map(Discussion::getId)
|
||||||
|
.forEach(discussionService::deleteById);
|
||||||
|
|
||||||
|
final List<Discussion> newDiscussions = new ArrayList<>();
|
||||||
for (Discussion discussion : discussions) {
|
for (Discussion discussion : discussions) {
|
||||||
if (discussion.getMergeRequest() != null) {
|
if (checkNotNull(discussion.getMergeRequest())) {
|
||||||
final Optional<Discussion> optNewDiscussion = HttpParse.request(createLinkOldDiscussion(discussion))
|
getOldDiscussionJson(discussion)
|
||||||
.header(ACCEPT)
|
|
||||||
.header(H_PRIVATE_TOKEN, personProperty.getToken())
|
|
||||||
.execute(DiscussionJson.class)
|
|
||||||
.map(json -> {
|
.map(json -> {
|
||||||
final Discussion newDiscussion = conversionService.convert(json, Discussion.class);
|
final Discussion newDiscussion = conversionService.convert(json, Discussion.class);
|
||||||
newDiscussion.getNotes().forEach(createNoteLink(discussion.getMergeRequest()));
|
newDiscussion.getNotes().forEach(createNoteLink(discussion.getMergeRequest()));
|
||||||
return newDiscussion;
|
return newDiscussion;
|
||||||
});
|
}).ifPresent(newDiscussions::add);
|
||||||
optNewDiscussion.ifPresent(discussionService::update);
|
|
||||||
} else {
|
|
||||||
discussionService.deleteById(discussion.getId());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
discussionSheet = discussionService.getAll(PageRequest.of(++page, COUNT));
|
if (checkNotEmpty(newDiscussions)) {
|
||||||
|
personMapping(newDiscussions);
|
||||||
|
discussionService.updateAll(newDiscussions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
discussionPage = discussionService.getAll(PageRequest.of(++page, COUNT));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private Optional<DiscussionJson> getOldDiscussionJson(Discussion discussion) {
|
||||||
|
return HttpParse.request(createLinkOldDiscussion(discussion))
|
||||||
|
.header(ACCEPT)
|
||||||
|
.header(H_PRIVATE_TOKEN, personProperty.getToken())
|
||||||
|
.execute(DiscussionJson.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String createLinkOldDiscussion(Discussion discussion) {
|
private String createLinkOldDiscussion(Discussion discussion) {
|
||||||
@ -142,7 +211,11 @@ public class DiscussionParser {
|
|||||||
|
|
||||||
private Consumer<Note> createNoteLink(MergeRequest mergeRequest) {
|
private Consumer<Note> createNoteLink(MergeRequest mergeRequest) {
|
||||||
return note -> {
|
return note -> {
|
||||||
final String url = MessageFormat.format(gitlabProperty.getUrlNote(), mergeRequest.getWebUrl(), note.getId());
|
final String url = MessageFormat.format(
|
||||||
|
gitlabProperty.getUrlNote(),
|
||||||
|
mergeRequest.getWebUrl(),
|
||||||
|
note.getId()
|
||||||
|
);
|
||||||
note.setWebUrl(url);
|
note.setWebUrl(url);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
package dev.struchkov.bot.gitlab.core.service.parser;
|
package dev.struchkov.bot.gitlab.core.service.parser;
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.ExistsContainer;
|
import dev.struchkov.bot.gitlab.context.domain.ExistContainer;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.IdAndStatusPr;
|
import dev.struchkov.bot.gitlab.context.domain.IdAndStatusPr;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.MergeRequestState;
|
import dev.struchkov.bot.gitlab.context.domain.MergeRequestState;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.MergeRequest;
|
import dev.struchkov.bot.gitlab.context.domain.entity.MergeRequest;
|
||||||
|
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.Project;
|
import dev.struchkov.bot.gitlab.context.domain.entity.Project;
|
||||||
import dev.struchkov.bot.gitlab.context.service.MergeRequestsService;
|
import dev.struchkov.bot.gitlab.context.service.MergeRequestsService;
|
||||||
import dev.struchkov.bot.gitlab.context.service.ProjectService;
|
import dev.struchkov.bot.gitlab.context.service.ProjectService;
|
||||||
@ -22,10 +23,15 @@ import org.springframework.stereotype.Service;
|
|||||||
|
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static dev.struchkov.haiti.utils.Checker.checkNotEmpty;
|
||||||
|
import static dev.struchkov.haiti.utils.Checker.checkNotNull;
|
||||||
import static dev.struchkov.haiti.utils.network.HttpParse.ACCEPT;
|
import static dev.struchkov.haiti.utils.network.HttpParse.ACCEPT;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@ -47,19 +53,20 @@ public class MergeRequestParser {
|
|||||||
public void parsingOldMergeRequest() {
|
public void parsingOldMergeRequest() {
|
||||||
final Set<IdAndStatusPr> existIds = mergeRequestsService.getAllId(OLD_STATUSES);
|
final Set<IdAndStatusPr> existIds = mergeRequestsService.getAllId(OLD_STATUSES);
|
||||||
|
|
||||||
for (IdAndStatusPr existId : existIds) {
|
final List<MergeRequest> mergeRequests = existIds.stream()
|
||||||
final String mrUrl = MessageFormat.format(gitlabProperty.getUrlPullRequest(), existId.getProjectId(), existId.getTwoId());
|
.map(this::getMergeRequest)
|
||||||
final Optional<MergeRequestJson> json = HttpParse.request(mrUrl)
|
.filter(Optional::isPresent)
|
||||||
.header(ACCEPT)
|
.map(Optional::get)
|
||||||
.header(StringUtils.H_PRIVATE_TOKEN, personProperty.getToken())
|
|
||||||
.execute(MergeRequestJson.class);
|
|
||||||
final Optional<MergeRequest> mergeRequest = json
|
|
||||||
.map(mergeRequestJson -> {
|
.map(mergeRequestJson -> {
|
||||||
final MergeRequest newMergeRequest = conversionService.convert(mergeRequestJson, MergeRequest.class);
|
final MergeRequest newMergeRequest = conversionService.convert(mergeRequestJson, MergeRequest.class);
|
||||||
parsingCommits(newMergeRequest);
|
parsingCommits(newMergeRequest);
|
||||||
return newMergeRequest;
|
return newMergeRequest;
|
||||||
});
|
})
|
||||||
mergeRequest.ifPresent(mergeRequestsService::update);
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
if (checkNotEmpty(mergeRequests)) {
|
||||||
|
personMapping(mergeRequests);
|
||||||
|
mergeRequestsService.updateAll(mergeRequests);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -83,22 +90,25 @@ public class MergeRequestParser {
|
|||||||
int page = 1;
|
int page = 1;
|
||||||
List<MergeRequestJson> mergeRequestJsons = getMergeRequestJsons(project, page);
|
List<MergeRequestJson> mergeRequestJsons = getMergeRequestJsons(project, page);
|
||||||
|
|
||||||
while (!mergeRequestJsons.isEmpty()) {
|
while (checkNotEmpty(mergeRequestJsons)) {
|
||||||
|
|
||||||
final Set<Long> jsonIds = mergeRequestJsons.stream()
|
final Set<Long> jsonIds = mergeRequestJsons.stream()
|
||||||
.map(MergeRequestJson::getId)
|
.map(MergeRequestJson::getId)
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
final ExistsContainer<MergeRequest, Long> existsContainer = mergeRequestsService.existsById(jsonIds);
|
final ExistContainer<MergeRequest, Long> existContainer = mergeRequestsService.existsById(jsonIds);
|
||||||
if (!existsContainer.isAllFound()) {
|
if (!existContainer.isAllFound()) {
|
||||||
final List<MergeRequest> newMergeRequests = mergeRequestJsons.stream()
|
final List<MergeRequest> newMergeRequests = mergeRequestJsons.stream()
|
||||||
.filter(json -> existsContainer.getIdNoFound().contains(json.getId()))
|
.filter(json -> existContainer.getIdNoFound().contains(json.getId()))
|
||||||
.map(json -> {
|
.map(json -> {
|
||||||
final MergeRequest mergeRequest = conversionService.convert(json, MergeRequest.class);
|
final MergeRequest mergeRequest = conversionService.convert(json, MergeRequest.class);
|
||||||
parsingCommits(mergeRequest);
|
parsingCommits(mergeRequest);
|
||||||
return mergeRequest;
|
return mergeRequest;
|
||||||
})
|
})
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
|
personMapping(newMergeRequests);
|
||||||
|
|
||||||
mergeRequestsService.createAll(newMergeRequests);
|
mergeRequestsService.createAll(newMergeRequests);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,6 +116,32 @@ public class MergeRequestParser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void personMapping(List<MergeRequest> newMergeRequests) {
|
||||||
|
final Map<Long, Person> personMap = Stream.concat(
|
||||||
|
newMergeRequests.stream()
|
||||||
|
.flatMap(mergeRequest -> Stream.of(mergeRequest.getAssignee(), mergeRequest.getAuthor())),
|
||||||
|
newMergeRequests.stream()
|
||||||
|
.flatMap(mergeRequest -> mergeRequest.getReviewers().stream())
|
||||||
|
).distinct()
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.collect(Collectors.toMap(Person::getId, p -> p));
|
||||||
|
|
||||||
|
for (MergeRequest newMergeRequest : newMergeRequests) {
|
||||||
|
newMergeRequest.setAuthor(personMap.get(newMergeRequest.getAuthor().getId()));
|
||||||
|
|
||||||
|
final Person assignee = newMergeRequest.getAssignee();
|
||||||
|
if (checkNotNull(assignee)) {
|
||||||
|
newMergeRequest.setAssignee(personMap.get(assignee.getId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
newMergeRequest.setReviewers(
|
||||||
|
newMergeRequest.getReviewers().stream()
|
||||||
|
.map(reviewer -> personMap.get(reviewer.getId()))
|
||||||
|
.collect(Collectors.toList())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void parsingCommits(MergeRequest mergeRequest) {
|
private void parsingCommits(MergeRequest mergeRequest) {
|
||||||
final List<CommitJson> commitJson = HttpParse.request(
|
final List<CommitJson> commitJson = HttpParse.request(
|
||||||
MessageFormat.format(gitlabProperty.getUrlCommit(), mergeRequest.getProjectId(), mergeRequest.getTwoId())
|
MessageFormat.format(gitlabProperty.getUrlCommit(), mergeRequest.getProjectId(), mergeRequest.getTwoId())
|
||||||
@ -125,4 +161,12 @@ public class MergeRequestParser {
|
|||||||
.executeList(MergeRequestJson.class);
|
.executeList(MergeRequestJson.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Optional<MergeRequestJson> getMergeRequest(IdAndStatusPr existId) {
|
||||||
|
final String mrUrl = MessageFormat.format(gitlabProperty.getUrlPullRequest(), existId.getProjectId(), existId.getTwoId());
|
||||||
|
return HttpParse.request(mrUrl)
|
||||||
|
.header(ACCEPT)
|
||||||
|
.header(StringUtils.H_PRIVATE_TOKEN, personProperty.getToken())
|
||||||
|
.execute(MergeRequestJson.class);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package dev.struchkov.bot.gitlab.core.service.parser;
|
package dev.struchkov.bot.gitlab.core.service.parser;
|
||||||
|
|
||||||
|
import dev.struchkov.bot.gitlab.context.domain.ExistContainer;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.PipelineStatus;
|
import dev.struchkov.bot.gitlab.context.domain.PipelineStatus;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.Pipeline;
|
import dev.struchkov.bot.gitlab.context.domain.entity.Pipeline;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.Project;
|
import dev.struchkov.bot.gitlab.context.domain.entity.Project;
|
||||||
@ -9,7 +10,6 @@ import dev.struchkov.bot.gitlab.core.config.properties.GitlabProperty;
|
|||||||
import dev.struchkov.bot.gitlab.core.config.properties.PersonProperty;
|
import dev.struchkov.bot.gitlab.core.config.properties.PersonProperty;
|
||||||
import dev.struchkov.bot.gitlab.core.utils.StringUtils;
|
import dev.struchkov.bot.gitlab.core.utils.StringUtils;
|
||||||
import dev.struchkov.bot.gitlab.sdk.domain.PipelineJson;
|
import dev.struchkov.bot.gitlab.sdk.domain.PipelineJson;
|
||||||
import dev.struchkov.haiti.context.domain.ExistsContainer;
|
|
||||||
import dev.struchkov.haiti.utils.network.HttpParse;
|
import dev.struchkov.haiti.utils.network.HttpParse;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.core.convert.ConversionService;
|
import org.springframework.core.convert.ConversionService;
|
||||||
@ -19,7 +19,6 @@ import org.springframework.stereotype.Service;
|
|||||||
|
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@ -31,6 +30,7 @@ import static dev.struchkov.bot.gitlab.context.domain.PipelineStatus.PREPARING;
|
|||||||
import static dev.struchkov.bot.gitlab.context.domain.PipelineStatus.RUNNING;
|
import static dev.struchkov.bot.gitlab.context.domain.PipelineStatus.RUNNING;
|
||||||
import static dev.struchkov.bot.gitlab.context.domain.PipelineStatus.WAITING_FOR_RESOURCE;
|
import static dev.struchkov.bot.gitlab.context.domain.PipelineStatus.WAITING_FOR_RESOURCE;
|
||||||
import static dev.struchkov.haiti.context.exception.ConvertException.convertException;
|
import static dev.struchkov.haiti.context.exception.ConvertException.convertException;
|
||||||
|
import static dev.struchkov.haiti.utils.Checker.checkNotEmpty;
|
||||||
import static dev.struchkov.haiti.utils.network.HttpParse.ACCEPT;
|
import static dev.struchkov.haiti.utils.network.HttpParse.ACCEPT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -75,17 +75,17 @@ public class PipelineParser {
|
|||||||
LocalDateTime newLastUpdate = LocalDateTime.now();
|
LocalDateTime newLastUpdate = LocalDateTime.now();
|
||||||
List<PipelineJson> pipelineJsons = getPipelineJsons(project.getId(), page, lastUpdate);
|
List<PipelineJson> pipelineJsons = getPipelineJsons(project.getId(), page, lastUpdate);
|
||||||
|
|
||||||
while (!pipelineJsons.isEmpty()) {
|
while (checkNotEmpty(pipelineJsons)) {
|
||||||
|
|
||||||
final Set<Long> jsonIds = pipelineJsons.stream()
|
final Set<Long> jsonIds = pipelineJsons.stream()
|
||||||
.map(PipelineJson::getId)
|
.map(PipelineJson::getId)
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
final ExistsContainer<Pipeline, Long> existsContainer = pipelineService.existsById(jsonIds);
|
final ExistContainer<Pipeline, Long> existContainer = pipelineService.existsById(jsonIds);
|
||||||
|
|
||||||
if (!existsContainer.isAllFound()) {
|
if (!existContainer.isAllFound()) {
|
||||||
|
|
||||||
final Collection<Long> idsNotFound = existsContainer.getIdNoFound();
|
final Set<Long> idsNotFound = existContainer.getIdNoFound();
|
||||||
|
|
||||||
for (Long newId : idsNotFound) {
|
for (Long newId : idsNotFound) {
|
||||||
final Pipeline newPipeline = HttpParse.request(
|
final Pipeline newPipeline = HttpParse.request(
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package dev.struchkov.bot.gitlab.core.service.parser;
|
package dev.struchkov.bot.gitlab.core.service.parser;
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.ExistsContainer;
|
import dev.struchkov.bot.gitlab.context.domain.ExistContainer;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
||||||
import dev.struchkov.bot.gitlab.context.domain.entity.Project;
|
import dev.struchkov.bot.gitlab.context.domain.entity.Project;
|
||||||
import dev.struchkov.bot.gitlab.context.service.PersonService;
|
import dev.struchkov.bot.gitlab.context.service.PersonService;
|
||||||
@ -15,6 +15,7 @@ import lombok.RequiredArgsConstructor;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.core.convert.ConversionService;
|
import org.springframework.core.convert.ConversionService;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@ -46,10 +47,12 @@ public class ProjectParser {
|
|||||||
private final GitlabProperty gitlabProperty;
|
private final GitlabProperty gitlabProperty;
|
||||||
private final PersonProperty personProperty;
|
private final PersonProperty personProperty;
|
||||||
|
|
||||||
|
@Transactional
|
||||||
public void parseAllPrivateProject() {
|
public void parseAllPrivateProject() {
|
||||||
parseProjects(PRIVATE);
|
parseProjects(PRIVATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
public void parseAllProjectOwner() {
|
public void parseAllProjectOwner() {
|
||||||
parseProjects(OWNER);
|
parseProjects(OWNER);
|
||||||
}
|
}
|
||||||
@ -66,9 +69,9 @@ public class ProjectParser {
|
|||||||
|
|
||||||
createNewPersons(projectJsons);
|
createNewPersons(projectJsons);
|
||||||
|
|
||||||
final ExistsContainer<Project, Long> existsContainer = projectService.existsById(projectIds);
|
final ExistContainer<Project, Long> existContainer = projectService.existsById(projectIds);
|
||||||
final List<Project> newProjects = projectJsons.stream()
|
final List<Project> newProjects = projectJsons.stream()
|
||||||
.filter(json -> existsContainer.getIdNoFound().contains(json.getId()))
|
.filter(json -> existContainer.getIdNoFound().contains(json.getId()))
|
||||||
.map(json -> conversionService.convert(json, Project.class))
|
.map(json -> conversionService.convert(json, Project.class))
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
@ -80,15 +83,29 @@ public class ProjectParser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void parseByUrl(String projectUrl) {
|
||||||
|
final ProjectJson projectJson = HttpParse.request(projectUrl)
|
||||||
|
.header(ACCEPT)
|
||||||
|
.header(StringUtils.H_PRIVATE_TOKEN, personProperty.getToken())
|
||||||
|
.execute(ProjectJson.class)
|
||||||
|
.orElseThrow(convertException("Ошибка получения проекта"));
|
||||||
|
if (!projectService.existsById(projectJson.getId())) {
|
||||||
|
createNewPersons(List.of(projectJson));
|
||||||
|
|
||||||
|
final Project newProject = conversionService.convert(projectJson, Project.class);
|
||||||
|
projectService.create(newProject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void createNewPersons(List<ProjectJson> projectJsons) {
|
private void createNewPersons(List<ProjectJson> projectJsons) {
|
||||||
final Set<Long> personCreatorId = projectJsons.stream()
|
final Set<Long> personCreatorId = projectJsons.stream()
|
||||||
.map(ProjectJson::getCreatorId)
|
.map(ProjectJson::getCreatorId)
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
final ExistsContainer<Person, Long> existsContainer = personService.existsById(personCreatorId);
|
final ExistContainer<Person, Long> existContainer = personService.existsById(personCreatorId);
|
||||||
|
|
||||||
if (!existsContainer.isAllFound()) {
|
if (!existContainer.isAllFound()) {
|
||||||
final Collection<Long> notFoundId = existsContainer.getIdNoFound();
|
final Collection<Long> notFoundId = existContainer.getIdNoFound();
|
||||||
|
|
||||||
final List<Person> newPersons = notFoundId.stream()
|
final List<Person> newPersons = notFoundId.stream()
|
||||||
.map(
|
.map(
|
||||||
@ -113,16 +130,4 @@ public class ProjectParser {
|
|||||||
.executeList(ProjectJson.class);
|
.executeList(ProjectJson.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void parseByUrl(String projectUrl) {
|
|
||||||
final Project project = HttpParse.request(projectUrl)
|
|
||||||
.header(ACCEPT)
|
|
||||||
.header(StringUtils.H_PRIVATE_TOKEN, personProperty.getToken())
|
|
||||||
.execute(ProjectJson.class)
|
|
||||||
.map(json -> conversionService.convert(json, Project.class))
|
|
||||||
.orElseThrow(convertException("Ошибка получения проекта"));
|
|
||||||
if (!projectService.existsById(project.getId())) {
|
|
||||||
projectService.create(project);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -21,8 +21,12 @@
|
|||||||
<artifactId>bot-context</artifactId>
|
<artifactId>bot-context</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.data</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-data-jpa</artifactId>
|
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.liquibase</groupId>
|
||||||
|
<artifactId>liquibase-core</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ import dev.struchkov.bot.gitlab.context.repository.DiscussionRepository;
|
|||||||
import dev.struchkov.bot.gitlab.data.jpa.DiscussionJpaRepository;
|
import dev.struchkov.bot.gitlab.data.jpa.DiscussionJpaRepository;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
@ -16,6 +17,7 @@ import java.util.Set;
|
|||||||
/**
|
/**
|
||||||
* @author upagge 11.02.2021
|
* @author upagge 11.02.2021
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
@Repository
|
@Repository
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class DiscussionRepositoryImpl implements DiscussionRepository {
|
public class DiscussionRepositoryImpl implements DiscussionRepository {
|
||||||
|
@ -63,4 +63,9 @@ public class MergeRequestRepositoryImpl implements MergeRequestRepository {
|
|||||||
return jpaRepository.findAll(filter.<Specification<MergeRequest>>build(), pageable);
|
return jpaRepository.findAll(filter.<Specification<MergeRequest>>build(), pageable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<MergeRequest> findAllByReviewerId(Long personId) {
|
||||||
|
return jpaRepository.findAllByReviewersIn(personId);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -18,19 +18,20 @@ import java.util.Set;
|
|||||||
|
|
||||||
public interface MergeRequestJpaRepository extends JpaRepositoryImplementation<MergeRequest, Long> {
|
public interface MergeRequestJpaRepository extends JpaRepositoryImplementation<MergeRequest, Long> {
|
||||||
|
|
||||||
Set<MergeRequest> findAllByIdIn(Set<Long> ids);
|
|
||||||
|
|
||||||
void deleteAllByIdIn(Collection<Long> id);
|
void deleteAllByIdIn(Collection<Long> id);
|
||||||
|
|
||||||
@Query("SELECT new dev.struchkov.bot.gitlab.context.domain.IdAndStatusPr(p.id, p.twoId, p.projectId, p.state) FROM MergeRequest p WHERE p.state IN :states")
|
@Query("SELECT new dev.struchkov.bot.gitlab.context.domain.IdAndStatusPr(p.id, p.twoId, p.projectId, p.state) FROM MergeRequest p WHERE p.state IN :states")
|
||||||
Set<IdAndStatusPr> findAllIdByStateIn(@Param("states") Set<MergeRequestState> states);
|
Set<IdAndStatusPr> findAllIdByStateIn(@Param("states") Set<MergeRequestState> states);
|
||||||
|
|
||||||
@Query("SELECT p.id from MergeRequest p")
|
@Query("SELECT p.id FROM MergeRequest p")
|
||||||
Set<Long> findAllIds();
|
Set<Long> findAllIds();
|
||||||
|
|
||||||
@Query("SELECT p.author.id from MergeRequest p WHERE p.id = :id")
|
@Query("SELECT p.author.id FROM MergeRequest p WHERE p.id = :id")
|
||||||
Optional<String> findAuthorById(@Param("id") Long id);
|
Optional<String> findAuthorById(@Param("id") Long id);
|
||||||
|
|
||||||
List<MergeRequest> findAllByAssigneeId(Long userId);
|
List<MergeRequest> findAllByAssigneeId(Long userId);
|
||||||
|
|
||||||
|
@Query("SELECT mr FROM MergeRequest mr LEFT JOIN mr.reviewers r WHERE r.id = :reviewerId")
|
||||||
|
List<MergeRequest> findAllByReviewersIn(@Param("reviewerId") Long reviewerId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,23 +0,0 @@
|
|||||||
FROM openjdk:17.0.2-jdk-slim-buster
|
|
||||||
MAINTAINER uPagge <me@upagge.ru>
|
|
||||||
RUN apt upgrade && addgroup gitlabbot --disabled-password && \
|
|
||||||
adduser gitlabbot --ingroup gitlabbot && \
|
|
||||||
mkdir -p /bot && \
|
|
||||||
chown -R gitlabbot:gitlabbot /bot
|
|
||||||
WORKDIR /bot
|
|
||||||
USER gitlabbot:gitlabbot
|
|
||||||
COPY target/gitlab-notification.jar app.jar
|
|
||||||
ENV TELEGRAM_PERSON_ID=TELEGRAM_PERSON_ID DATASOURCE_URL=DATASOURCE_URL \
|
|
||||||
DATASOURCE_PASSWORD=DATASOURCE_PASSWORD DATASOURCE_USERNAME=DATASOURCE_USERNAME \
|
|
||||||
GITLAB_PERSONAL_TOKEN=GITLAB_PERSONAL_TOKEN TELEGRAM_BOT_TOKEN=TELEGRAM_BOT_TOKEN \
|
|
||||||
TELEGRAM_BOT_USERNAME=TELEGRAM_BOT_USERNAME GITLAB_URL=GITLAB_URL GITLAB_REPLACE_URL=GITLAB_REPLACE_URL
|
|
||||||
ENTRYPOINT java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -DTELEGRAM_BOT_USERNAME=${TELEGRAM_BOT_USERNAME} \
|
|
||||||
-DTELEGRAM_BOT_TOKEN=$TELEGRAM_BOT_TOKEN \
|
|
||||||
-DTELEGRAM_PERSON_ID=$TELEGRAM_PERSON_ID \
|
|
||||||
-DDATASOURCE_URL=$DATASOURCE_URL \
|
|
||||||
-DDATASOURCE_PASSWORD=$DATASOURCE_PASSWORD \
|
|
||||||
-DDATASOURCE_USERNAME=$DATASOURCE_USERNAME \
|
|
||||||
-DGITLAB_PERSONAL_TOKEN=$GITLAB_PERSONAL_TOKEN \
|
|
||||||
-DGITLAB_URL=$GITLAB_URL \
|
|
||||||
-DGITLAB_REPLACE_URL=$GITLAB_REPLACE_URL \
|
|
||||||
-jar app.jar
|
|
@ -0,0 +1,13 @@
|
|||||||
|
package dev.struchkov.bot.gitlab;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
public class GitLabBotApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(GitLabBotApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,17 +0,0 @@
|
|||||||
package dev.struchkov.bot.gitlab.app;
|
|
||||||
|
|
||||||
import org.springframework.boot.SpringApplication;
|
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
|
||||||
import org.springframework.boot.autoconfigure.domain.EntityScan;
|
|
||||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
|
||||||
|
|
||||||
@EnableJpaRepositories(basePackages = {"dev.struchkov.bot.gitlab.data.jpa"})
|
|
||||||
@SpringBootApplication(scanBasePackages = "dev.struchkov.bot.gitlab")
|
|
||||||
@EntityScan(basePackages = {"dev.struchkov.bot.gitlab.context.domain.entity"})
|
|
||||||
public class GitLabBotApplication {
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
|
||||||
SpringApplication.run(GitLabBotApplication.class, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,4 +1,4 @@
|
|||||||
package dev.struchkov.bot.gitlab.app.config;
|
package dev.struchkov.bot.gitlab.config;
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.domain.PersonInformation;
|
import dev.struchkov.bot.gitlab.context.domain.PersonInformation;
|
||||||
import dev.struchkov.bot.gitlab.core.config.properties.GitlabProperty;
|
import dev.struchkov.bot.gitlab.core.config.properties.GitlabProperty;
|
@ -1,4 +1,4 @@
|
|||||||
package dev.struchkov.bot.gitlab.app.scheduler;
|
package dev.struchkov.bot.gitlab.scheduler;
|
||||||
|
|
||||||
import dev.struchkov.bot.gitlab.context.service.CleanService;
|
import dev.struchkov.bot.gitlab.context.service.CleanService;
|
||||||
import dev.struchkov.bot.gitlab.core.service.parser.DiscussionParser;
|
import dev.struchkov.bot.gitlab.core.service.parser.DiscussionParser;
|
@ -32,7 +32,7 @@ gitlab-bot:
|
|||||||
url-pull-request-close: "${GITLAB_URL}/api/v4/projects/{0,number,#}/merge_requests?state=closed&page={1, number, integer}&per_page=100"
|
url-pull-request-close: "${GITLAB_URL}/api/v4/projects/{0,number,#}/merge_requests?state=closed&page={1, number, integer}&per_page=100"
|
||||||
url-pull-request-comment: "${GITLAB_URL}/api/v4/projects/{0,number,#}/merge_requests/{1,number,#}/notes?&page={2,number,#}&per_page=100"
|
url-pull-request-comment: "${GITLAB_URL}/api/v4/projects/{0,number,#}/merge_requests/{1,number,#}/notes?&page={2,number,#}&per_page=100"
|
||||||
url-pull-request: "${GITLAB_URL}/api/v4/projects/{0,number,#}/merge_requests/{1,number,#}"
|
url-pull-request: "${GITLAB_URL}/api/v4/projects/{0,number,#}/merge_requests/{1,number,#}"
|
||||||
url-merge-request-add: ${GITLAB_URL}/api/v4/projects/{0}%2F{1}
|
url-merge-request-add: "${GITLAB_URL}/api/v4/projects/"
|
||||||
user-url: ${GITLAB_URL}/api/v4/user
|
user-url: ${GITLAB_URL}/api/v4/user
|
||||||
users-url: ${GITLAB_URL}/api/v4/users
|
users-url: ${GITLAB_URL}/api/v4/users
|
||||||
url-note: "{0}#note_{1,number,#}"
|
url-note: "{0}#note_{1,number,#}"
|
||||||
|
11
gitlab-app/src/main/resources/banner.txt
Normal file
11
gitlab-app/src/main/resources/banner.txt
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
.d8888b. d8b 888 888 888 888b 888 888 d8b .d888 d8b
|
||||||
|
d88P Y88b Y8P 888 888 888 8888b 888 888 Y8P d88P" Y8P
|
||||||
|
888 888 888 888 888 88888b 888 888 888
|
||||||
|
888 888 888888 888 8888b. 88888b. 888Y88b 888 .d88b. 888888 888 888888 888 .d88b. 888d888
|
||||||
|
888 88888 888 888 888 "88b 888 "88b 888 Y88b888 d88""88b 888 888 888 888 d8P Y8b 888P"
|
||||||
|
888 888 888 888 888 .d888888 888 888 888 Y88888 888 888 888 888 888 888 88888888 888
|
||||||
|
Y88b d88P 888 Y88b. 888 888 888 888 d88P 888 Y8888 Y88..88P Y88b. 888 888 888 Y8b. 888
|
||||||
|
"Y8888P88 888 "Y888 88888888 "Y888888 88888P" 888 Y888 "Y88P" "Y888 888 888 888 "Y8888 888
|
||||||
|
.................................................................................................................
|
||||||
|
..................................................................................... SpringBoot : 2.6.14 .......
|
||||||
|
.................................................................................................................
|
@ -1,8 +1,9 @@
|
|||||||
<databaseChangeLog
|
<databaseChangeLog
|
||||||
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
|
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.17.xsd">
|
||||||
|
|
||||||
<include file="v.1.0.0/changelog.xml" relativeToChangelogFile="true"/>
|
<include file="v.1.0.0/changelog.xml" relativeToChangelogFile="true"/>
|
||||||
|
<include file="v.1.1.3/changelog.xml" relativeToChangelogFile="true"/>
|
||||||
|
|
||||||
</databaseChangeLog>
|
</databaseChangeLog>
|
@ -2,7 +2,7 @@
|
|||||||
<databaseChangeLog
|
<databaseChangeLog
|
||||||
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.6.xsd">
|
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.17.xsd">
|
||||||
|
|
||||||
<changeSet id="2022-12-03-create-table-app-setting" author="uPagge">
|
<changeSet id="2022-12-03-create-table-app-setting" author="uPagge">
|
||||||
<insert tableName="app_setting">
|
<insert tableName="app_setting">
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<databaseChangeLog
|
<databaseChangeLog
|
||||||
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
|
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.17.xsd">
|
||||||
|
|
||||||
<changeSet id="2022-12-03-add-tab-v-1-0-0" author="uPagge">
|
<changeSet id="2022-12-03-add-tab-v-1-0-0" author="uPagge">
|
||||||
<tagDatabase tag="v.1.0.0"/>
|
<tagDatabase tag="v.1.0.0"/>
|
||||||
|
@ -0,0 +1,22 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<databaseChangeLog
|
||||||
|
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.17.xsd">
|
||||||
|
|
||||||
|
<changeSet id="2022-12-05-create-table-reviewers" author="uPagge">
|
||||||
|
<createTable tableName="merge_request_reviewer">
|
||||||
|
<column name="merge_request_id" type="int">
|
||||||
|
<constraints nullable="false" foreignKeyName="fk_merge_request_reviewer_merge_request_id"
|
||||||
|
references="merge_request(id)" deleteCascade="true"/>
|
||||||
|
</column>
|
||||||
|
<column name="person_id" type="int">
|
||||||
|
<constraints nullable="false" foreignKeyName="fk_merge_request_reviewer_person_id"
|
||||||
|
references="person(id)" deleteCascade="true"/>
|
||||||
|
</column>
|
||||||
|
</createTable>
|
||||||
|
|
||||||
|
<addPrimaryKey tableName="merge_request_reviewer" columnNames="merge_request_id, person_id"/>
|
||||||
|
</changeSet>
|
||||||
|
|
||||||
|
</databaseChangeLog>
|
@ -0,0 +1,12 @@
|
|||||||
|
<databaseChangeLog
|
||||||
|
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.17.xsd">
|
||||||
|
|
||||||
|
<changeSet id="2022-12-05-add-tab-v-1-0-0" author="uPagge">
|
||||||
|
<tagDatabase tag="v.1.1.3"/>
|
||||||
|
</changeSet>
|
||||||
|
|
||||||
|
<include file="2022-12-05-add-reviewers.xml" relativeToChangelogFile="true"/>
|
||||||
|
|
||||||
|
</databaseChangeLog>
|
@ -8,6 +8,7 @@ import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
|
|||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -40,6 +41,8 @@ public class MergeRequestJson {
|
|||||||
private PersonJson author;
|
private PersonJson author;
|
||||||
private PersonJson assignee;
|
private PersonJson assignee;
|
||||||
|
|
||||||
|
private List<PersonJson> reviewers;
|
||||||
|
|
||||||
@JsonProperty("web_url")
|
@JsonProperty("web_url")
|
||||||
private String webUrl;
|
private String webUrl;
|
||||||
|
|
||||||
|
22
pom.xml
22
pom.xml
@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-parent</artifactId>
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
<version>2.6.2</version>
|
<version>2.6.14</version>
|
||||||
<relativePath/> <!-- lookup parent from repository -->
|
<relativePath/> <!-- lookup parent from repository -->
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
@ -44,7 +44,7 @@
|
|||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
|
|
||||||
<godfather.telegram.core.version>0.0.38</godfather.telegram.core.version>
|
<godfather.telegram.core.version>0.0.39</godfather.telegram.core.version>
|
||||||
|
|
||||||
<javax.persistance.version>2.2</javax.persistance.version>
|
<javax.persistance.version>2.2</javax.persistance.version>
|
||||||
|
|
||||||
@ -152,12 +152,6 @@
|
|||||||
<version>${postgresql.version}</version>
|
<version>${postgresql.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.liquibase</groupId>
|
|
||||||
<artifactId>liquibase-core</artifactId>
|
|
||||||
<version>${liquibase.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>javax.persistence</groupId>
|
<groupId>javax.persistence</groupId>
|
||||||
<artifactId>javax.persistence-api</artifactId>
|
<artifactId>javax.persistence-api</artifactId>
|
||||||
@ -182,18 +176,6 @@
|
|||||||
<!-- /утилиты -->
|
<!-- /утилиты -->
|
||||||
<!-- spring -->
|
<!-- spring -->
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-web</artifactId>
|
|
||||||
<version>2.2.4.RELEASE</version>
|
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>ch.qos.logback</groupId>
|
|
||||||
<artifactId>logback-classic</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- /spring -->
|
<!-- /spring -->
|
||||||
<!-- http -->
|
<!-- http -->
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ public class StartNotify {
|
|||||||
if (!settingService.isFirstStart()) {
|
if (!settingService.isFirstStart()) {
|
||||||
notifyService.send(
|
notifyService.send(
|
||||||
SimpleTextNotify.builder()
|
SimpleTextNotify.builder()
|
||||||
.message("Привет. Желаю продуктивного дня :)" +
|
.message("Hello. I wish you a productive day :)" +
|
||||||
"\n-- -- -- -- --\n" +
|
"\n-- -- -- -- --\n" +
|
||||||
"Version " + appProperty.getVersion() + " | Developer: [uPagge](https://mark.struchkov.dev)")
|
"Version " + appProperty.getVersion() + " | Developer: [uPagge](https://mark.struchkov.dev)")
|
||||||
.build()
|
.build()
|
||||||
|
@ -13,13 +13,11 @@ import dev.struchkov.godfather.main.domain.annotation.Unit;
|
|||||||
import dev.struchkov.godfather.main.domain.content.Mail;
|
import dev.struchkov.godfather.main.domain.content.Mail;
|
||||||
import dev.struchkov.godfather.simple.core.unit.AnswerText;
|
import dev.struchkov.godfather.simple.core.unit.AnswerText;
|
||||||
import dev.struchkov.godfather.simple.core.unit.MainUnit;
|
import dev.struchkov.godfather.simple.core.unit.MainUnit;
|
||||||
|
import dev.struchkov.haiti.utils.Checker;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.data.domain.Page;
|
|
||||||
import org.springframework.data.domain.PageRequest;
|
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@ -92,9 +90,10 @@ public class MenuConfig {
|
|||||||
public AnswerText<Mail> addNewProject() {
|
public AnswerText<Mail> addNewProject() {
|
||||||
return AnswerText.<Mail>builder()
|
return AnswerText.<Mail>builder()
|
||||||
.answer(mail -> {
|
.answer(mail -> {
|
||||||
final List<String> urlList = Arrays.stream(mail.getText().split("/")).toList();
|
final String mailText = mail.getText();
|
||||||
int lastElement = urlList.size() - 1;
|
final String projectUrl = gitlabProperty.getUrlMergeRequestAdd() + mailText.replace(gitlabProperty.getBaseUrl(), "")
|
||||||
final String projectUrl = MessageFormat.format(gitlabProperty.getUrlMergeRequestAdd(), urlList.get(lastElement - 1), urlList.get(lastElement));
|
.substring(1)
|
||||||
|
.replace("/", "%2F");
|
||||||
projectParser.parseByUrl(projectUrl);
|
projectParser.parseByUrl(projectUrl);
|
||||||
return boxAnswer("Project added successfully");
|
return boxAnswer("Project added successfully");
|
||||||
})
|
})
|
||||||
@ -136,10 +135,9 @@ public class MenuConfig {
|
|||||||
return AnswerText.<Mail>builder()
|
return AnswerText.<Mail>builder()
|
||||||
.triggerPhrase(GET_ASSIGNEE_MERGE_REQUEST)
|
.triggerPhrase(GET_ASSIGNEE_MERGE_REQUEST)
|
||||||
.answer(() -> {
|
.answer(() -> {
|
||||||
final Long userId = personInformation.getId();
|
final Long gitlabUserId = personInformation.getId();
|
||||||
final Page<MergeRequest> sheet = mergeRequestsService.getAll(getAssigneeFilter(userId), PageRequest.of(0, 20));
|
final List<MergeRequest> mergeRequests = mergeRequestsService.getAllByReviewerId(gitlabUserId);
|
||||||
if (sheet.hasContent()) {
|
if (Checker.checkNotEmpty(mergeRequests)) {
|
||||||
final List<MergeRequest> mergeRequests = sheet.getContent();
|
|
||||||
final String text = mergeRequests.stream()
|
final String text = mergeRequests.stream()
|
||||||
.map(mergeRequest -> MessageFormat.format("[{0}]({1})", mergeRequest.getTitle(), mergeRequest.getWebUrl()))
|
.map(mergeRequest -> MessageFormat.format("[{0}]({1})", mergeRequest.getTitle(), mergeRequest.getWebUrl()))
|
||||||
.collect(Collectors.joining("\n"));
|
.collect(Collectors.joining("\n"));
|
||||||
@ -150,6 +148,7 @@ public class MenuConfig {
|
|||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private MergeRequestFilter getAssigneeFilter(Long userId) {
|
private MergeRequestFilter getAssigneeFilter(Long userId) {
|
||||||
final MergeRequestFilter mergeRequestFilter = new MergeRequestFilter();
|
final MergeRequestFilter mergeRequestFilter = new MergeRequestFilter();
|
||||||
mergeRequestFilter.setAssignee(userId);
|
mergeRequestFilter.setAssignee(userId);
|
||||||
|
Loading…
Reference in New Issue
Block a user