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

Initial commit

parents
No related branches found
No related tags found
No related merge requests found
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/classes" path="src/main/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>
.project 0 → 100644
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>Eclipse Project Code Review Creator</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
</natures>
</projectDescription>
eclipse.preferences.version=1
encoding//src/main/java=UTF-8
encoding//src/test/java=UTF-8
encoding/<project>=UTF-8
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
org.eclipse.jdt.core.compiler.compliance=11
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
org.eclipse.jdt.core.compiler.release=enabled
org.eclipse.jdt.core.compiler.source=11
activeProfiles=
eclipse.preferences.version=1
resolveWorkspaceProjects=true
version=1
pom.xml 0 → 100644
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.eclipse.dash</groupId>
<artifactId>eclipse-project-code</artifactId>
<version>0.0.2-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Eclipse Project Code Review Creator</name>
<url>https://projects.eclipse.org/projects/technology.dash</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.eclipse.dash</groupId>
<artifactId>org.eclipse.dash.licenses</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.dash</groupId>
<artifactId>eclipse-api-for-java</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
<version>5.0.1</version>
</dependency>
<dependency>
<groupId>org.gitlab4j</groupId>
<artifactId>gitlab4j-api</artifactId>
<version>5.0.1</version>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>jakarta.json</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.36</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.36</version>
</dependency>
<dependency>
<groupId>org.kohsuke</groupId>
<artifactId>github-api</artifactId>
<version>1.313</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.7.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-runner</artifactId>
<version>1.7.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>org.eclipse.dash.project_code.Main</mainClass>
</transformer>
</transformers>
<createDependencyReducedPom>
false
</createDependencyReducedPom>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<configuration>
<additionalClasspathElements>
<additionalClasspathElement>${basedir}/src/test/java</additionalClasspathElement>
</additionalClasspathElements>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.22.2</version>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<release>11</release>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<repositories>
<repository>
<id>dash-licenses-snapshots</id>
<url>https://repo.eclipse.org/content/repositories/dash-licenses-snapshots/</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
</project>
\ No newline at end of file
package org.eclipse.dash.ip.project.code;
import java.util.function.Consumer;
import org.eclipse.dash.licenses.ISettings;
import org.gitlab4j.api.GitLabApi;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.inject.Guice;
import com.google.inject.Injector;
public class InitialContributionProcess {
final Logger logger = LoggerFactory.getLogger(InitialContributionProcess.class);
public static void main(String[] args) throws InterruptedException {
new InitialContributionProcess().runOnce();
}
public void runOnce() {
run((provider) -> {
var task = provider.findTask();
if (task != null) {
task.execute();
} else {
logger.info("No pending tasks");
}
});
}
private void run(Consumer<InitialContributionReviewTaskFinder> doit) {
logger.info("Starting the processor.");
String ipLabToken = getIpLabToken().trim();
if (ipLabToken.isEmpty()) {
throw new RuntimeException("IP Lab Token not provided.");
}
try (var api = new GitLabApi(getGitLabUrl(), ipLabToken)) {
Injector injector = Guice.createInjector(new InitialContributionProcessModule(api));
var scanner = injector.getInstance(InitialContributionReviewTaskFinder.class);
doit.accept(scanner);
}
}
static String getGitLabUrl() {
return System.getProperty("org.eclipse.dash.gitlab", "https://gitlab.eclipse.org");
}
static String getEmoProjectPath() {
return System.getProperty("org.eclipse.dash.emo-path", "eclipsefdn/emo-team/emo");
}
static String getIPLabPath() {
return System.getProperty("org.eclipse.dash.iplab-path", "eclipsefdn/emo-team/iplab");
}
static String getIpLabToken() {
return System.getProperty("org.eclipse.dash.token", "");
}
}
package org.eclipse.dash.ip.project.code;
import java.io.InputStream;
import java.util.function.Consumer;
import org.eclipse.dash.api.EclipseApi;
import org.eclipse.dash.api.EclipseApi.HttpService;
import org.eclipse.dash.licenses.IProxySettings;
import org.eclipse.dash.licenses.ISettings;
import org.eclipse.dash.licenses.http.HttpClientService;
import org.eclipse.dash.licenses.http.IHttpClientService;
import org.gitlab4j.api.GitLabApi;
import com.google.inject.AbstractModule;
import com.google.inject.util.Providers;
public class InitialContributionProcessModule extends AbstractModule {
private GitLabApi api;
public InitialContributionProcessModule(GitLabApi api) {
this.api = api;
}
@Override
protected void configure() {
bind(ISettings.class).toInstance(new ISettings() {});
bind(GitLabApi.class).toInstance(api);
HttpClientService httpClient = new HttpClientService();
bind(EclipseApi.class).toInstance(new EclipseApi(new HttpService() {
@Override
public int get(String url, String contentType, Consumer<InputStream> handler) {
return httpClient.get(url, contentType, handler);
}
}));
bind(IHttpClientService.class).toInstance(httpClient);
bind(IProxySettings.class).toProvider(Providers.of(null));
bind(InitialContributionReviewTaskFinder.class).toInstance(new InitialContributionReviewTaskFinder());
}
}
/*************************************************************************
* Copyright (c) 2022 The Eclipse Foundation and others.
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
* distribution, and is available at https://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*************************************************************************/
package org.eclipse.dash.ip.project.code;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.Objects;
import java.util.regex.Pattern;
import javax.inject.Inject;
import org.eclipse.dash.api.EclipseApi;
import org.eclipse.dash.api.Project;
import org.eclipse.dash.api.SourceRepository;
import org.gitlab4j.api.Constants.IssueState;
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.GHRepository;
import org.kohsuke.github.GitHub;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Experimental: Create issues for the initial contributions for all repositories
* owned by a specific project.
*
*/
public class InitialContributionReviewTaskFinder {
final Logger logger = LoggerFactory.getLogger(InitialContributionReviewTaskFinder.class);
@Inject
EclipseApi api;
@Inject
GitLabApi gitlab;
@Inject
InitialContributionReviewTaskFinder initialContribution;
public ProjectCodeReviewTask findTask() {
try {
IssueFilter filter = new IssueFilter()
.withState(IssueState.OPENED)
.withLabels(Collections.singletonList("EDP::Initial Contribution"));
return gitlab.getIssuesApi()
.getIssuesStream(InitialContributionProcess.getEmoProjectPath(), filter)
.map(each -> createTask(each))
.filter(Objects::nonNull)
.findAny()
.orElse(null);
} catch (GitLabApiException e) {
logger.debug(e.getLocalizedMessage(), e);
}
return null;
}
public ProjectCodeReviewTask createTask(Issue issue) {
Pattern EclipseProjectIdPattern = Pattern.compile("^Project: \\[.+\\]\\(https:\\/\\/projects\\.eclipse\\.org\\/projects\\/(?<id>[^\\/]+)\\)", Pattern.MULTILINE);
var matcher = EclipseProjectIdPattern.matcher(issue.getDescription());
if (matcher.find()) {
var id = matcher.group("id");
var project = api.getProject(id);
if (project.exists()) {
return new ProjectCodeReviewTask(issue, project);
}
}
return null;
}
class ProjectCodeReviewTask {
private Issue issue;
private Project project;
public ProjectCodeReviewTask(Issue issue, Project project) {
this.issue = issue;
this.project = project;
}
public void execute() {
initialContribution.createReviews(issue, project);
}
}
public void createReviews(Issue issue, Project project) {
api.getRepositoriesApi().sourceRepositories(project)
.filter(each -> !each.isMetadata())
.forEach(each -> createReview(issue, project, each));
}
private void createReview(Issue issue, Project project, SourceRepository repository) {
if (repository.getName().endsWith("-website")) return;
logger.info("Setting up review for {}", repository.getUrl());
var existing = getExisting(project, repository);
if (existing == null) {
try {
var github = GitHub.connect("waynebeaton", System.getProperty("org.eclipse.dash.github-token"));
var repo = github.getRepository(repository.getPath() + "/" + repository.getName());
var title = getTitle(project, repo);
var description = getDescription(project, repo);
var labels = "Project Content,Initial Contribution,Review Needed";
try {
existing = gitlab.getIssuesApi().createIssue(InitialContributionProcess.getIPLabPath(), title, description, null, null, null, labels, null, null, null, null);
} catch (GitLabApiException e) {
throw new RuntimeException(e);
}
logger.info("Review created {}", existing.getWebUrl());
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
} else {
logger.info("An issue already exists {}", existing.getWebUrl());
}
try {
var linkExists = gitlab.getIssuesApi().getIssueLinksStream(InitialContributionProcess.getIPLabPath(), existing.getIid())
.filter(each -> each.getIid() == issue.getIid())
.findAny()
.isPresent();
if (!linkExists) {
gitlab.getIssuesApi().createIssueLink(InitialContributionProcess.getEmoProjectPath(), existing.getIid(), InitialContributionProcess.getIPLabPath(), issue.getIid());
}
} catch (GitLabApiException e) {
throw new RuntimeException(e);
}
}
private Issue getExisting(Project project, SourceRepository repository) {
var match = "project/{project}/{path}/{name}/"
.replace("{project}", project.getId())
.replace("{path}", repository.getPath())
.replace("{name}", repository.getName());
try {
IssueFilter filter = new IssueFilter().withLabels(Arrays.asList(new String[]{"Project Content","Initial Contribution"}));
return gitlab.getIssuesApi()
.getIssuesStream(InitialContributionProcess.getEmoProjectPath(), filter)
.filter(issue -> issue.getTitle().startsWith(match))
.findAny().orElse(null);
} catch (GitLabApiException e) {
throw new RuntimeException(e);
}
}
private String getTitle(Project project, GHRepository repository) throws IOException {
return "project/{source}/{name}/{sha}"
.replace("{source}", project.getId())
.replace("{name}", repository.getFullName())
.replace("{sha}", repository.getBranch(repository.getDefaultBranch()).getSHA1());
}
private String getDescription(Project project, GHRepository repo) throws IOException {
String sha = repo.getBranch(repo.getDefaultBranch()).getSHA1();
var browseUrl = "https://github.com/{name}/tree/{sha}"
.replace("{name}", repo.getFullName())
.replace("{branch}", repo.getDefaultBranch())
.replace("{sha}", sha);
var archiveUrl = "https://github.com/{name}/archive/{sha}.zip"
.replace("{name}", repo.getFullName())
.replace("{sha}", sha);
var builder = new StringBuilder();
return builder
.append("Project: ").append(getProjectLink(project)).append("\n\n")
//.append(" - License: {license}\n".replace("{license}", project.getLicense().toString()))
.append("[Repository]({url})\n\n".replace("{url}", repo.getHtmlUrl().toString()))
.append(" - Default branch: {branch}\n".replace("{branch}", repo.getDefaultBranch()))
.append(" - Commit: {sha}\n".replace("{sha}", sha))
.append(" - License: {license}\n".replace("{license}", repo.getLicense().getName()))
.append(" - [Browse]({url})\n".replace("{url}", browseUrl))
.append(" - [Source]({url})\n".replace("{url}", archiveUrl))
.toString();
}
private String getProjectLink(Project project) {
return "[{name}]({url})".replace("{name}", project.getName()).replace("{url}", project.getUrl());
}
}
package org.eclipse.dash.ip.project.code;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* Unit test for simple App.
*/
public class AppTest
extends TestCase
{
/**
* Create the test case
*
* @param testName name of the test case
*/
public AppTest( String testName )
{
super( testName );
}
/**
* @return the suite of tests being tested
*/
public static Test suite()
{
return new TestSuite( AppTest.class );
}
/**
* Rigourous Test :-)
*/
public void testApp()
{
assertTrue( true );
}
}
/org/
/org/
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment