Skip to content
Snippets Groups Projects
Commit bec0588d authored by Martin Lowe's avatar Martin Lowe :flag_ca:
Browse files

Merge branch 'malowe/main/156' into 'main'

Iss #156 - Add handling of Gitlab repo field from projects API

Closes #156

See merge request !185
parents 463e16e3 8d456262
No related branches found
No related tags found
1 merge request!185Iss #156 - Add handling of Gitlab repo field from projects API
Pipeline #43602 passed
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
<quarkus.platform.version>3.2.11.Final</quarkus.platform.version> <quarkus.platform.version>3.2.11.Final</quarkus.platform.version>
<surefire-plugin.version>3.1.2</surefire-plugin.version> <surefire-plugin.version>3.1.2</surefire-plugin.version>
<maven.compiler.parameters>true</maven.compiler.parameters> <maven.compiler.parameters>true</maven.compiler.parameters>
<eclipse-api-version>0.9.5</eclipse-api-version> <eclipse-api-version>0.9.6</eclipse-api-version>
<auto-value.version>1.10.4</auto-value.version> <auto-value.version>1.10.4</auto-value.version>
<org.mapstruct.version>1.5.5.Final</org.mapstruct.version> <org.mapstruct.version>1.5.5.Final</org.mapstruct.version>
<sonar.sources>src/main</sonar.sources> <sonar.sources>src/main</sonar.sources>
......
...@@ -32,8 +32,8 @@ import jakarta.enterprise.context.ApplicationScoped; ...@@ -32,8 +32,8 @@ import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject; import jakarta.inject.Inject;
/** /**
* Helps manage projects by providing filters on top of the generic service as well as operations like adapting interest * Helps manage projects by providing filters on top of the generic service as well as operations like adapting interest groups to projects
* groups to projects for easier processing. * for easier processing.
* *
* @author Martin Lowe * @author Martin Lowe
* *
...@@ -74,18 +74,9 @@ public final class ProjectHelper { ...@@ -74,18 +74,9 @@ public final class ProjectHelper {
// match the repo URL to be valid // match the repo URL to be valid
switch (provider) { switch (provider) {
case GITLAB: case GITLAB:
return availableProjects return availableProjects.stream().filter(p -> doesProjectMatchGitlabRepos(p, repoUrl, projectNamespace)).toList();
.stream()
.filter(p -> projectNamespace.startsWith(p.getGitlab().getProjectGroup() + "/")
&& p.getGitlab().getIgnoredSubGroups().stream().noneMatch(sg -> projectNamespace.startsWith(sg + "/")))
.toList();
case GITHUB: case GITHUB:
return availableProjects return availableProjects.stream().filter(p -> doesProjectMatchGithubRepos(p, repoUrl, projectNamespace)).toList();
.stream()
.filter(p -> p.getGithubRepos().stream().anyMatch(re -> re.getUrl() != null && re.getUrl().endsWith(repoUrl))
|| (StringUtils.isNotBlank(p.getGithub().getOrg()) && projectNamespace.startsWith(p.getGithub().getOrg())
&& p.getGithub().getIgnoredRepos().stream().noneMatch(repoUrl::endsWith)))
.toList();
case GERRIT: case GERRIT:
return availableProjects return availableProjects
.stream() .stream()
...@@ -164,4 +155,34 @@ public final class ProjectHelper { ...@@ -164,4 +155,34 @@ public final class ProjectHelper {
.setSpecProjectWorkingGroup(Collections.emptyMap()) .setSpecProjectWorkingGroup(Collections.emptyMap())
.build(); .build();
} }
/**
* Check if the passed projects Gitlab repos field has a match for the given repo URL, or if the Gitlab project group is set and matches
* the project namespace of the request.
*
* @param p project being checked
* @param repoUrl URL of the repo that was the origin of the request
* @param projectNamespace the namespace of the project of the repo that created the request.
* @return true if the project is a match via Gitlab repos or project namespace, false otherwise
*/
private boolean doesProjectMatchGitlabRepos(Project p, String repoUrl, String projectNamespace) {
return p.getGitlabRepos().stream().anyMatch(re -> re.getUrl() != null && re.getUrl().endsWith(repoUrl))
|| (projectNamespace.startsWith(p.getGitlab().getProjectGroup() + "/")
&& p.getGitlab().getIgnoredSubGroups().stream().noneMatch(sg -> projectNamespace.startsWith(sg + "/")));
}
/**
* Check if the passed projects Github repos field has a match for the given repo URL, or if the Github project organization is set and
* matches the project namespace of the request.
*
* @param p project being checked
* @param repoUrl URL of the repo that was the origin of the request
* @param projectNamespace the namespace of the project of the repo that created the request.
* @return true if the project is a match via Github repos or organization, false otherwise
*/
private boolean doesProjectMatchGithubRepos(Project p, String repoUrl, String projectNamespace) {
return p.getGithubRepos().stream().anyMatch(re -> re.getUrl() != null && re.getUrl().endsWith(repoUrl))
|| (StringUtils.isNotBlank(p.getGithub().getOrg()) && projectNamespace.startsWith(p.getGithub().getOrg())
&& p.getGithub().getIgnoredRepos().stream().noneMatch(repoUrl::endsWith));
}
} }
package org.eclipsefoundation.git.eca.helper;
import java.util.List;
import org.eclipsefoundation.efservices.api.models.Project;
import org.eclipsefoundation.git.eca.namespace.ProviderType;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import io.quarkus.test.junit.QuarkusTest;
import jakarta.inject.Inject;
@QuarkusTest
class ProjectHelperTest {
@Inject
ProjectHelper helper;
/**
* Gitlab provider tests
*/
@Test
void retrieveProjectsForRepoURL_success_gitlabOrg() {
List<Project> results = helper
.retrieveProjectsForRepoURL("http://www.gitlab.eclipse.org/eclipse/dash-second/sample-repo", ProviderType.GITLAB);
Assertions.assertEquals(1, results.size());
Assertions.assertEquals("sample.proto", results.get(0).getProjectId());
}
@Test
void retrieveProjectsForRepoURL_success_gitlabRepo() {
List<Project> results = helper
.retrieveProjectsForRepoURL("http://www.gitlab.eclipse.org/eclipsefdn/sample/repo", ProviderType.GITLAB);
Assertions.assertEquals(1, results.size());
Assertions.assertEquals("spec.proj", results.get(0).getProjectId());
}
@Test
void retrieveProjectsForRepoURL_failure_gitlab_noMatch() {
List<Project> results = helper
.retrieveProjectsForRepoURL("http://www.gitlab.eclipse.org/eclipsefdn/something-that-doesnt-exist", ProviderType.GITLAB);
Assertions.assertEquals(0, results.size());
}
@Test
void retrieveProjectsForRepoURL_failure_gitlab_onlyChecksGLRepos() {
List<Project> results = helper.retrieveProjectsForRepoURL("http://www.github.com/eclipsefdn/tck-proto", ProviderType.GITLAB);
Assertions.assertEquals(0, results.size());
}
/**
* Github provider
*/
@Test
void retrieveProjectsForRepoURL_success_githubOrg() {
List<Project> results = helper.retrieveProjectsForRepoURL("http://www.github.com/eclipsefdn-tck/dash-second", ProviderType.GITHUB);
Assertions.assertEquals(1, results.size());
Assertions.assertEquals("spec.proj", results.get(0).getProjectId());
}
@Test
void retrieveProjectsForRepoURL_success_githubRepo() {
List<Project> results = helper.retrieveProjectsForRepoURL("http://www.github.com/eclipsefdn/tck-proto", ProviderType.GITHUB);
Assertions.assertEquals(1, results.size());
Assertions.assertEquals("spec.proj", results.get(0).getProjectId());
}
@Test
void retrieveProjectsForRepoURL_failure_github_noMatch() {
List<Project> results = helper
.retrieveProjectsForRepoURL("http://www.github.com/eclipsefdn/something-that-doesnt-exist", ProviderType.GITHUB);
Assertions.assertEquals(0, results.size());
}
@Test
void retrieveProjectsForRepoURL_failure_github_onlyChecksGHRepos() {
List<Project> results = helper
.retrieveProjectsForRepoURL("http://www.gitlab.eclipse.org/eclipsefdn/sample/repo", ProviderType.GITHUB);
Assertions.assertEquals(0, results.size());
}
}
...@@ -54,104 +54,106 @@ public class MockProjectsAPI implements ProjectsAPI { ...@@ -54,104 +54,106 @@ public class MockProjectsAPI implements ProjectsAPI {
Repo r6 = Repo.builder().setUrl("/gitroot/sample/gerrit.other-project").build(); Repo r6 = Repo.builder().setUrl("/gitroot/sample/gerrit.other-project").build();
// sample users // sample users
ProjectParticipant u1 = ProjectParticipant.builder().setUrl("").setUsername("da_wizz").setFullName("da_wizz") ProjectParticipant u1 = ProjectParticipant.builder().setUrl("").setUsername("da_wizz").setFullName("da_wizz").build();
.build(); ProjectParticipant u2 = ProjectParticipant.builder().setUrl("").setUsername("grunter").setFullName("grunter").build();
ProjectParticipant u2 = ProjectParticipant.builder().setUrl("").setUsername("grunter").setFullName("grunter")
.build();
this.projects.add(Project.builder() this.projects
.setName("Sample project") .add(Project
.setProjectId("sample.proj") .builder()
.setSpecProjectWorkingGroup(Collections.emptyMap()) .setName("Sample project")
.setGithubRepos(Arrays.asList(r1, r2)) .setProjectId("sample.proj")
.setGerritRepos(Arrays.asList(r5)) .setSpecProjectWorkingGroup(Collections.emptyMap())
.setCommitters(Arrays.asList(u1, u2)) .setGithubRepos(Arrays.asList(r1, r2))
.setProjectLeads(Collections.emptyList()) .setGerritRepos(Arrays.asList(r5))
.setGitlab(GitlabProject.builder().setIgnoredSubGroups(Collections.emptyList()).setProjectGroup("") .setCommitters(Arrays.asList(u1, u2))
.build()) .setProjectLeads(Collections.emptyList())
.setShortProjectId("sample.proj") .setGitlab(GitlabProject.builder().setIgnoredSubGroups(Collections.emptyList()).setProjectGroup("").build())
.setSummary("summary") .setShortProjectId("sample.proj")
.setUrl("project.url.com") .setSummary("summary")
.setWebsiteUrl("someproject.com") .setUrl("project.url.com")
.setWebsiteRepo(Collections.emptyList()) .setWebsiteUrl("someproject.com")
.setLogo("logoUrl.com") .setWebsiteRepo(Collections.emptyList())
.setTags(Collections.emptyList()) .setLogo("logoUrl.com")
.setGithub(GithubProject.builder() .setTags(Collections.emptyList())
.setOrg("") .setGithub(GithubProject.builder().setOrg("").setIgnoredRepos(Collections.emptyList()).build())
.setIgnoredRepos(Collections.emptyList()).build()) .setContributors(Collections.emptyList())
.setContributors(Collections.emptyList()) .setWorkingGroups(Collections.emptyList())
.setWorkingGroups(Collections.emptyList()) .setIndustryCollaborations(Collections.emptyList())
.setIndustryCollaborations(Collections.emptyList()) .setReleases(Collections.emptyList())
.setReleases(Collections.emptyList()) .setTopLevelProject("eclipse")
.setTopLevelProject("eclipse") .build());
.build());
this.projects.add(Project.builder() this.projects
.setName("Prototype thing") .add(Project
.setProjectId("sample.proto") .builder()
.setSpecProjectWorkingGroup(Collections.emptyMap()) .setName("Prototype thing")
.setGithubRepos(Arrays.asList(r3)) .setProjectId("sample.proto")
.setGerritRepos(Arrays.asList(r6)) .setSpecProjectWorkingGroup(Collections.emptyMap())
.setCommitters(Arrays.asList(u2)) .setGithubRepos(Arrays.asList(r3))
.setProjectLeads(Collections.emptyList()) .setGerritRepos(Arrays.asList(r6))
.setGitlab( .setCommitters(Arrays.asList(u2))
GitlabProject.builder().setIgnoredSubGroups(Collections.emptyList()) .setProjectLeads(Collections.emptyList())
.setProjectGroup("eclipse/dash-second").build()) .setGitlab(GitlabProject
.setShortProjectId("sample.proto") .builder()
.setWebsiteUrl("someproject.com") .setIgnoredSubGroups(Collections.emptyList())
.setSummary("summary") .setProjectGroup("eclipse/dash-second")
.setUrl("project.url.com") .build())
.setWebsiteRepo(Collections.emptyList()) .setShortProjectId("sample.proto")
.setLogo("logoUrl.com") .setWebsiteUrl("someproject.com")
.setTags(Collections.emptyList()) .setSummary("summary")
.setGithub(GithubProject.builder() .setUrl("project.url.com")
.setOrg("") .setWebsiteRepo(Collections.emptyList())
.setIgnoredRepos(Collections.emptyList()).build()) .setLogo("logoUrl.com")
.setContributors(Collections.emptyList()) .setTags(Collections.emptyList())
.setWorkingGroups(Collections.emptyList()) .setGithub(GithubProject.builder().setOrg("").setIgnoredRepos(Collections.emptyList()).build())
.setIndustryCollaborations(Collections.emptyList()) .setContributors(Collections.emptyList())
.setReleases(Collections.emptyList()) .setWorkingGroups(Collections.emptyList())
.setTopLevelProject("eclipse") .setIndustryCollaborations(Collections.emptyList())
.build()); .setReleases(Collections.emptyList())
.setTopLevelProject("eclipse")
.build());
this.projects.add(Project.builder() this.projects
.setName("Spec project") .add(Project
.setProjectId("spec.proj")
.setSpecProjectWorkingGroup(Map.of("id", "proj1", "name", "proj1"))
.setGithubRepos(Arrays.asList(r4))
.setGerritRepos(Collections.emptyList())
.setGitlab(GitlabProject
.builder() .builder()
.setIgnoredSubGroups(Arrays.asList("eclipse/dash/mirror")) .setName("Spec project")
.setProjectGroup("eclipse/dash") .setProjectId("spec.proj")
.build()) .setSpecProjectWorkingGroup(Map.of("id", "proj1", "name", "proj1"))
.setCommitters(Arrays.asList(u1, u2)) .setGithubRepos(Arrays.asList(r4))
.setProjectLeads(Collections.emptyList()) .setGerritRepos(Collections.emptyList())
.setShortProjectId("spec.proj") .setGitlab(GitlabProject
.setSummary("summary") .builder()
.setUrl("project.url.com") .setIgnoredSubGroups(Arrays.asList("eclipse/dash/mirror"))
.setWebsiteUrl("someproject.com") .setProjectGroup("eclipse/dash")
.setWebsiteRepo(Collections.emptyList()) .build())
.setLogo("logoUrl.com") .setGitlabRepos(Arrays.asList(Repo.builder().setUrl("http://www.gitlab.eclipse.org/eclipsefdn/sample/repo").build()))
.setTags(Collections.emptyList()) .setCommitters(Arrays.asList(u1, u2))
.setGithub(GithubProject.builder() .setProjectLeads(Collections.emptyList())
.setOrg("eclipsefdn-tck") .setShortProjectId("spec.proj")
.setIgnoredRepos(Arrays.asList("eclipsefdn-tck/tck-ignored")).build()) .setSummary("summary")
.setContributors(Collections.emptyList()) .setUrl("project.url.com")
.setWorkingGroups(Collections.emptyList()) .setWebsiteUrl("someproject.com")
.setIndustryCollaborations(Collections.emptyList()) .setWebsiteRepo(Collections.emptyList())
.setReleases(Collections.emptyList()) .setLogo("logoUrl.com")
.setTopLevelProject("eclipse") .setTags(Collections.emptyList())
.build()); .setGithub(GithubProject
.builder()
.setOrg("eclipsefdn-tck")
.setIgnoredRepos(Arrays.asList("eclipsefdn-tck/tck-ignored"))
.build())
.setContributors(Collections.emptyList())
.setWorkingGroups(Collections.emptyList())
.setIndustryCollaborations(Collections.emptyList())
.setReleases(Collections.emptyList())
.setTopLevelProject("eclipse")
.build());
} }
@Override @Override
public Response getProjects(BaseAPIParameters params, int isSpecProject) { public Response getProjects(BaseAPIParameters params, int isSpecProject) {
if (isSpecProject == 1) { if (isSpecProject == 1) {
return Response return Response.ok(projects.stream().filter(p -> p.getSpecWorkingGroup().isPresent()).toList()).build();
.ok(projects.stream().filter(p -> p.getSpecWorkingGroup().isPresent()).toList())
.build();
} }
return Response.ok(projects).build(); return Response.ok(projects).build();
...@@ -159,42 +161,52 @@ public class MockProjectsAPI implements ProjectsAPI { ...@@ -159,42 +161,52 @@ public class MockProjectsAPI implements ProjectsAPI {
@Override @Override
public Response getInterestGroups(BaseAPIParameters params) { public Response getInterestGroups(BaseAPIParameters params) {
return Response.ok(Arrays.asList(InterestGroup return Response
.builder() .ok(Arrays
.setProjectId("foundation-internal.ig.mittens") .asList(InterestGroup
.setId("1") .builder()
.setLogo("") .setProjectId("foundation-internal.ig.mittens")
.setState("active") .setId("1")
.setTitle("Magical IG Tributed To Eclipse News Sources") .setLogo("")
.setDescription(Descriptor.builder().setFull("Sample").setSummary("Sample").build()) .setState("active")
.setScope(Descriptor.builder().setFull("Sample").setSummary("Sample").build()) .setTitle("Magical IG Tributed To Eclipse News Sources")
.setGitlab(GitlabProject.builder() .setDescription(Descriptor.builder().setFull("Sample").setSummary("Sample").build())
.setIgnoredSubGroups(Collections.emptyList()) .setScope(Descriptor.builder().setFull("Sample").setSummary("Sample").build())
.setProjectGroup("eclipse-ig/mittens") .setGitlab(GitlabProject
.build()) .builder()
.setLeads(Arrays.asList(InterestGroupParticipant .setIgnoredSubGroups(Collections.emptyList())
.builder() .setProjectGroup("eclipse-ig/mittens")
.setUrl("https://api.eclipse.org/account/profile/zacharysabourin") .build())
.setUsername("zacharysabourin") .setLeads(Arrays
.setFullName("zachary sabourin") .asList(InterestGroupParticipant
.setOrganization(Organization.builder() .builder()
.setDocuments(Collections.emptyMap()) .setUrl("https://api.eclipse.org/account/profile/zacharysabourin")
.setId("id") .setUsername("zacharysabourin")
.setName("org").build()) .setFullName("zachary sabourin")
.build())) .setOrganization(Organization
.setParticipants(Arrays.asList(InterestGroupParticipant .builder()
.builder() .setDocuments(Collections.emptyMap())
.setUrl("https://api.eclipse.org/account/profile/skilpatrick") .setId("id")
.setUsername("skilpatrick") .setName("org")
.setFullName("Skil Patrick") .build())
.setOrganization(Organization.builder() .build()))
.setDocuments(Collections.emptyMap()) .setParticipants(Arrays
.setId("id") .asList(InterestGroupParticipant
.setName("org").build()) .builder()
.build())) .setUrl("https://api.eclipse.org/account/profile/skilpatrick")
.setShortProjectId("mittens") .setUsername("skilpatrick")
.setResources(Resource.builder().setMembers("members").setWebsite("google.com").build()) .setFullName("Skil Patrick")
.setMailingList("mailinglist.com") .setOrganization(Organization
.build())).build(); .builder()
.setDocuments(Collections.emptyMap())
.setId("id")
.setName("org")
.build())
.build()))
.setShortProjectId("mittens")
.setResources(Resource.builder().setMembers("members").setWebsite("google.com").build())
.setMailingList("mailinglist.com")
.build()))
.build();
} }
} }
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