Skip to content
Snippets Groups Projects
Commit a600a94b authored by Wayne Beaton's avatar Wayne Beaton
Browse files

Initial support to initiate an IP Scan

parent af785683
No related branches found
No related tags found
No related merge requests found
......@@ -49,7 +49,7 @@ public class InitialContributionProcess {
return System.getProperty("org.eclipse.dash.iplab-path", "eclipsefdn/emo-team/iplab");
}
static long getReviewCreationLimit() {
public static long getReviewCreationLimit() {
try {
return Long.valueOf(System.getProperty("org.eclipse.dash.limit"));
} catch (NumberFormatException e) {
......
......@@ -12,13 +12,12 @@ package org.eclipse.dash.ip.project.code;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Objects;
import java.util.regex.Pattern;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import jakarta.inject.Inject;
import org.eclipse.dash.api.EclipseApi;
import org.eclipse.dash.api.Project;
......@@ -28,10 +27,11 @@ import org.gitlab4j.api.GitLabApi;
import org.gitlab4j.api.GitLabApiException;
import org.gitlab4j.api.models.Issue;
import org.gitlab4j.api.models.IssueFilter;
import org.kohsuke.github.GitHub;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jakarta.inject.Inject;
public class InitialContributionReviewTaskFinder {
final Logger logger = LoggerFactory.getLogger(InitialContributionReviewTaskFinder.class);
......@@ -47,53 +47,72 @@ public class InitialContributionReviewTaskFinder {
@Inject
InitialContributionReviewTaskFinder initialContribution;
public Stream<CreateProjectCodeReviewTask> tasks() {
public Stream<CreateReviewTask> tasks() {
return Stream.concat(initialContributionTasks(), adHocReviewTasks());
}
Stream<CreateReviewTask> initialContributionTasks() {
try {
IssueFilter filter = new IssueFilter()
.withState(IssueState.OPENED)
.withLabels(Collections.singletonList("EDP::Initial Contribution"));
return gitlabApi.getIssuesApi()
.getIssuesStream(InitialContributionProcess.getEmoProjectPath(), filter)
.map(each -> createTask(each))
.map(each -> createInitialContributionTaskFromProjectId(each, getProjectId(each)))
.filter(Objects::nonNull);
} catch (GitLabApiException e) {
logger.debug(e.getLocalizedMessage(), e);
}
return null;
return Stream.empty();
}
public CreateProjectCodeReviewTask createTask(Issue issue) {
var task = createTaskFromProposalLink(issue);
if (task != null) return task;
Stream<CreateReviewTask> adHocReviewTasks() {
try {
IssueFilter filter = new IssueFilter()
.withState(IssueState.OPENED)
.withLabels(Collections.singletonList("Initiate IP Review"));
return gitlabApi.getIssuesApi()
.getIssuesStream(InitialContributionProcess.getEmoProjectPath(), filter)
.map(each -> createAdHocReviewTaskFromProjectId(each, getProjectId(each)))
.filter(Objects::nonNull);
} catch (GitLabApiException e) {
logger.debug(e.getLocalizedMessage(), e);
}
return Stream.empty();
}
String getProjectId(Issue issue) {
var projectId = getProjectIdFromProposalLink(issue);
if (projectId != null) return projectId;
task = createTaskFromProjectLink(issue);
if (task != null) return task;
projectId = getProjectIdFromProjectLink(issue);
if (projectId != null) return projectId;
task = createTaskFromIssueTitle(issue);
if (task != null) return task;
projectId = getProjectIdFromIssueTitle(issue);
if (projectId != null) return projectId;
logger.warn("Could not identify project from issue #{}", issue.getIid());
return null;
}
private CreateProjectCodeReviewTask createTaskFromProjectLink(Issue issue) {
private String getProjectIdFromProjectLink(Issue issue) {
Pattern EclipseProjectIdPattern = Pattern.compile("Project: \\[.+\\]\\(https:\\/\\/projects\\.eclipse\\.org\\/projects\\/(?<id>[\\w-]+(?:\\.[\\w-]+){0,2})\\)");
var matcher = EclipseProjectIdPattern.matcher(issue.getDescription());
if (matcher.find()) {
var id = matcher.group("id");
logger.info("Found a project ID: {}", id);
return createTaskFromProjectId(issue, id);
return id;
}
return null;
}
private CreateProjectCodeReviewTask createTaskFromIssueTitle(Issue issue) {
private String getProjectIdFromIssueTitle(Issue issue) {
return null;
}
public CreateProjectCodeReviewTask createTaskFromProposalLink(Issue issue) {
public String getProjectIdFromProposalLink(Issue issue) {
Pattern EclipseProposalPattern = Pattern.compile("Project proposal: \\[.+\\]\\((?<url>https:\\/\\/projects\\.eclipse\\.org\\/proposals\\/(?:[\\w-]+))\\)", Pattern.CASE_INSENSITIVE);
var matcher = EclipseProposalPattern.matcher(issue.getDescription());
if (matcher.find()){
......@@ -102,7 +121,7 @@ public class InitialContributionReviewTaskFinder {
Proposal proposal = api.getProposal(url);
if (proposal.exists()) {
var id = proposal.getProjectId();
return createTaskFromProjectId(issue, id);
return id;
} else {
logger.warn("Could not find a proposal with URL {}", url);
}
......@@ -110,7 +129,9 @@ public class InitialContributionReviewTaskFinder {
return null;
}
private CreateProjectCodeReviewTask createTaskFromProjectId(Issue issue, String id) {
private CreateReviewTask createInitialContributionTaskFromProjectId(Issue issue, String id) {
if (id == null) return null;
// FIXME Temporary Hack
if ("automotive.tractusx".equals(id)) return null;
if ("ecd.opensmartclide".equals(id)) return null;
......@@ -119,8 +140,8 @@ public class InitialContributionReviewTaskFinder {
if (id != null) {
var project = api.getProject(id);
if (project.exists()) {
logger.info("Creating review task for project: {}", project.getName());
return new CreateProjectCodeReviewTask(issue, project);
logger.info("Creating Initial Contribution review task for project: {}", project.getName());
return new CreateInitialContributionReviewTask(issue, project);
} else {
logger.warn("A project with id {} does not exist", id);
}
......@@ -128,18 +149,42 @@ public class InitialContributionReviewTaskFinder {
return null;
}
private CreateReviewTask createAdHocReviewTaskFromProjectId(Issue issue, String id) {
if (id == null) return null;
if (id != null) {
var project = api.getProject(id);
if (project.exists()) {
logger.info("Creating Ad Hoc review task for project: {}", project.getName());
return new CreateAdHocReviewTask(issue, project);
} else {
logger.warn("A project with id {} does not exist", id);
}
}
return null;
}
class CreateProjectCodeReviewTask {
private Issue issue;
private Project project;
abstract class CreateReviewTask {
Issue issue;
Project project;
public CreateProjectCodeReviewTask(Issue issue, Project project) {
public CreateReviewTask(Issue issue, Project project) {
this.issue = issue;
this.project = project;
}
abstract void execute();
}
class CreateInitialContributionReviewTask extends CreateReviewTask {
public CreateInitialContributionReviewTask(Issue issue, Project project) {
super(issue, project);
}
@Override
public void execute() {
repositoryService.repositories(project)
.limit(InitialContributionProcess.getReviewCreationLimit())
......@@ -172,6 +217,10 @@ public class InitialContributionReviewTaskFinder {
linkReview(review);
}
String getLabels() {
return super.getLabels() + ",Initial Contribution";
}
Issue getExisting() {
var match = "project/{project}/{path}/{name}/"
.replace("{project}", project.getId())
......@@ -190,7 +239,7 @@ public class InitialContributionReviewTaskFinder {
}
}
class CreateRepositoryReview {
abstract class CreateRepositoryReview {
Issue issue;
Project project;
......@@ -233,7 +282,7 @@ public class InitialContributionReviewTaskFinder {
Issue createReview() {
var title = getTitle(repository);
var description = getDescription(repository);
var labels = "Project Content,Initial Contribution,Review Needed";
var labels = getLabels();
try {
Issue review = gitlabApi.getIssuesApi().createIssue(InitialContributionProcess.getIPLabPath(), title, description, null, null, null, labels, null, null, null, null);
......@@ -252,6 +301,10 @@ public class InitialContributionReviewTaskFinder {
}
}
String getLabels() {
return "Project Content,Review Needed";
}
String getTitle(IRepository repository) {
return "project/{project}/{path}/{name}/{sha}"
.replace("{project}", project.getId())
......@@ -284,4 +337,78 @@ public class InitialContributionReviewTaskFinder {
return "[{name}]({url})".replace("{name}", project.getName()).replace("{url}", project.getUrl());
}
}
class CreateAdHocReviewTask extends CreateReviewTask {
CreateAdHocReviewTask(Issue issue, Project project) {
super(issue, project);
}
@Override
void execute() {
if (removeReviewRequestLabel() ) {
repositoryService.repositories(project)
.limit(InitialContributionProcess.getReviewCreationLimit())
.forEach(each -> new CreateAdHocReview(issue, project, each).createAndLinkReview());
}
}
private boolean removeReviewRequestLabel() {
var labels = new HashSet<String>();
labels.addAll(issue.getLabels());
var labelExists = labels.remove("Initiate IP Review");
try {
gitlabApi.getIssuesApi().updateIssue(InitialContributionProcess.getEmoProjectPath(), issue.getIid(), null, null, null, null, null,
String.join(",", labels), null, null, null);
} catch (GitLabApiException e) {
throw new RuntimeException(e);
}
return labelExists;
}
}
class CreateAdHocReview extends CreateRepositoryReview {
public CreateAdHocReview(Issue issue, Project project, IRepository repository) {
super(issue, project, repository);
}
public void createAndLinkReview() {
logger.info("Setting up an ad hoc review for {}", repository.getWebUrl());
var review = getExisting();
if (review == null) {
if (!repository.isEmpty()) {
review = createReview();
} else {
logger.info("Did not create a review; repository is empty {}", repository.getWebUrl());
return;
}
} else {
logger.info("An issue already exists {}", review.getWebUrl());
}
linkReview(review);
}
Issue getExisting() {
var match = "project/{project}/{path}/{name}/{sha}"
.replace("{project}", project.getId())
.replace("{path}", repository.getNamespace())
.replace("{name}", repository.getName())
.replace("{sha}", repository.getTopCommitSha());
try {
IssueFilter filter = new IssueFilter().withLabels(Arrays.asList(new String[]{"Project Content"}));
return gitlabApi.getIssuesApi()
.getIssuesStream(InitialContributionProcess.getIPLabPath(), filter)
.filter(issue -> issue.getTitle().equals(match))
.findAny().orElse(null);
} catch (GitLabApiException e) {
throw new RuntimeException(e);
}
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment