Omit extracting subfolder from a workspace URL (#523)

sparce-checkoutis no longer available from devfile 2.1, so omit the subfolder mechanism in order to support branch names with a / sign.
pull/528/head
Igor Vinokur 2023-06-15 13:41:43 +03:00 committed by GitHub
parent fbea05f0cc
commit ab83bee400
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 41 additions and 119 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012-2021 Red Hat, Inc. * Copyright (c) 2012-2023 Red Hat, Inc.
* This program and the accompanying materials are made * This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0 * available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/ * which is available at https://www.eclipse.org/legal/epl-2.0/
@ -13,7 +13,6 @@ package org.eclipse.che.api.factory.server.github;
import static org.eclipse.che.dto.server.DtoFactory.newDto; import static org.eclipse.che.dto.server.DtoFactory.newDto;
import com.google.common.base.Strings;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import javax.inject.Singleton; import javax.inject.Singleton;
@ -40,9 +39,6 @@ public class GithubSourceStorageBuilder {
Map<String, String> parameters = new HashMap<>(2); Map<String, String> parameters = new HashMap<>(2);
parameters.put("branch", githubUrl.getBranch()); parameters.put("branch", githubUrl.getBranch());
if (!Strings.isNullOrEmpty(githubUrl.getSubfolder())) {
parameters.put("keepDir", githubUrl.getSubfolder());
}
return newDto(SourceStorageDto.class) return newDto(SourceStorageDto.class)
.withLocation(githubUrl.repositoryLocation()) .withLocation(githubUrl.repositoryLocation())
.withType("github") .withType("github")
@ -59,7 +55,6 @@ public class GithubSourceStorageBuilder {
return newDto(SourceDto.class) return newDto(SourceDto.class)
.withLocation(githubUrl.repositoryLocation()) .withLocation(githubUrl.repositoryLocation())
.withType("github") .withType("github")
.withBranch(githubUrl.getBranch()) .withBranch(githubUrl.getBranch());
.withSparseCheckoutDir(githubUrl.getSubfolder());
} }
} }

View File

@ -99,20 +99,20 @@ public class GithubURLParser {
this.githubPattern = this.githubPattern =
compile( compile(
format( format(
"^%s/(?<repoUser>[^/]++)/(?<repoName>[^/]++)((/)|(?:/tree/(?<branchName>[^/]++)(?:/(?<subFolder>.*))?)|(/pull/(?<pullRequestId>[^/]++)))?$", "^%s/(?<repoUser>[^/]+)/(?<repoName>[^/]++)((/)|(?:/tree/(?<branchName>.++))|(/pull/(?<pullRequestId>\\d++)))?$",
endpoint)); endpoint));
} }
public boolean isValid(@NotNull String url) { public boolean isValid(@NotNull String url) {
return githubPattern.matcher(url).matches(); return githubPattern.matcher(trimEnd(url, '/')).matches();
} }
public GithubUrl parseWithoutAuthentication(String url) throws ApiException { public GithubUrl parseWithoutAuthentication(String url) throws ApiException {
return parse(url, false); return parse(trimEnd(url, '/'), false);
} }
public GithubUrl parse(String url) throws ApiException { public GithubUrl parse(String url) throws ApiException {
return parse(url, true); return parse(trimEnd(url, '/'), true);
} }
private GithubUrl parse(String url, boolean authenticationRequired) throws ApiException { private GithubUrl parse(String url, boolean authenticationRequired) throws ApiException {
@ -173,7 +173,6 @@ public class GithubURLParser {
.withDisableSubdomainIsolation(disableSubdomainIsolation) .withDisableSubdomainIsolation(disableSubdomainIsolation)
.withBranch(branchName) .withBranch(branchName)
.withLatestCommit(latestCommit) .withLatestCommit(latestCommit)
.withSubfolder(matcher.group("subFolder"))
.withDevfileFilenames(devfileFilenamesProvider.getConfiguredDevfileFilenames()) .withDevfileFilenames(devfileFilenamesProvider.getConfiguredDevfileFilenames())
.withUrl(url); .withUrl(url);
} }

View File

@ -46,9 +46,6 @@ public class GithubUrl extends DefaultFactoryUrl {
/** SHA of the latest commit in the current branch */ /** SHA of the latest commit in the current branch */
private String latestCommit; private String latestCommit;
/** Subfolder if any */
private String subfolder;
private String serverUrl; private String serverUrl;
private boolean disableSubdomainIsolation; private boolean disableSubdomainIsolation;
@ -143,26 +140,6 @@ public class GithubUrl extends DefaultFactoryUrl {
return this; return this;
} }
/**
* Gets subfolder of this github url
*
* @return the subfolder part
*/
public String getSubfolder() {
return this.subfolder;
}
/**
* Sets the subfolder represented by the URL.
*
* @param subfolder path inside the repository
* @return current github instance
*/
protected GithubUrl withSubfolder(String subfolder) {
this.subfolder = subfolder;
return this;
}
public GithubUrl withServerUrl(String serverUrl) { public GithubUrl withServerUrl(String serverUrl) {
this.serverUrl = serverUrl; this.serverUrl = serverUrl;
return this; return this;

View File

@ -76,15 +76,13 @@ public class GithubURLParserTest {
/** Compare parsing */ /** Compare parsing */
@Test(dataProvider = "parsing") @Test(dataProvider = "parsing")
public void checkParsing( public void checkParsing(String url, String username, String repository, String branch)
String url, String username, String repository, String branch, String subfolder)
throws ApiException { throws ApiException {
GithubUrl githubUrl = githubUrlParser.parse(url); GithubUrl githubUrl = githubUrlParser.parse(url);
assertEquals(githubUrl.getUsername(), username); assertEquals(githubUrl.getUsername(), username);
assertEquals(githubUrl.getRepository(), repository); assertEquals(githubUrl.getRepository(), repository);
assertEquals(githubUrl.getBranch(), branch); assertEquals(githubUrl.getBranch(), branch);
assertEquals(githubUrl.getSubfolder(), subfolder);
} }
/** Compare parsing */ /** Compare parsing */
@ -117,31 +115,24 @@ public class GithubURLParserTest {
@DataProvider(name = "parsing") @DataProvider(name = "parsing")
public Object[][] expectedParsing() { public Object[][] expectedParsing() {
return new Object[][] { return new Object[][] {
{"https://github.com/eclipse/che", "eclipse", "che", null, null}, {"https://github.com/eclipse/che", "eclipse", "che", null},
{"https://github.com/eclipse/che123", "eclipse", "che123", null, null}, {"https://github.com/eclipse/che123", "eclipse", "che123", null},
{"https://github.com/eclipse/che.git", "eclipse", "che", null, null}, {"https://github.com/eclipse/che.git", "eclipse", "che", null},
{"https://github.com/eclipse/che.with.dot.git", "eclipse", "che.with.dot", null, null}, {"https://github.com/eclipse/che.with.dot.git", "eclipse", "che.with.dot", null},
{"https://github.com/eclipse/-.git", "eclipse", "-", null, null}, {"https://github.com/eclipse/-.git", "eclipse", "-", null},
{"https://github.com/eclipse/-j.git", "eclipse", "-j", null, null}, {"https://github.com/eclipse/-j.git", "eclipse", "-j", null},
{"https://github.com/eclipse/-", "eclipse", "-", null, null}, {"https://github.com/eclipse/-", "eclipse", "-", null},
{"https://github.com/eclipse/che-with-hyphen", "eclipse", "che-with-hyphen", null, null}, {"https://github.com/eclipse/che-with-hyphen", "eclipse", "che-with-hyphen", null},
{"https://github.com/eclipse/che-with-hyphen.git", "eclipse", "che-with-hyphen", null, null}, {"https://github.com/eclipse/che-with-hyphen.git", "eclipse", "che-with-hyphen", null},
{"https://github.com/eclipse/che/", "eclipse", "che", null, null}, {"https://github.com/eclipse/che/", "eclipse", "che", null},
{"https://github.com/eclipse/repositorygit", "eclipse", "repositorygit", null, null}, {"https://github.com/eclipse/repositorygit", "eclipse", "repositorygit", null},
{"https://github.com/eclipse/che/tree/4.2.x", "eclipse", "che", "4.2.x", null}, {"https://github.com/eclipse/che/tree/4.2.x", "eclipse", "che", "4.2.x"},
{"https://github.com/eclipse/che/tree/master", "eclipse", "che", "master"},
{ {
"https://github.com/eclipse/che/tree/master/dashboard/", "https://github.com/eclipse/che/tree/branch/with/slash",
"eclipse", "eclipse",
"che", "che",
"master", "branch/with/slash"
"dashboard/"
},
{
"https://github.com/eclipse/che/tree/master/plugins/plugin-git/che-plugin-git-ext-git",
"eclipse",
"che",
"master",
"plugins/plugin-git/che-plugin-git-ext-git"
} }
}; };
} }

View File

@ -136,8 +136,7 @@ public class GitlabFactoryParametersResolver extends RawDevfileUrlFactoryParamet
newDto(SourceDto.class) newDto(SourceDto.class)
.withLocation(gitlabUrl.repositoryLocation()) .withLocation(gitlabUrl.repositoryLocation())
.withType("git") .withType("git")
.withBranch(gitlabUrl.getBranch()) .withBranch(gitlabUrl.getBranch()))
.withSparseCheckoutDir(gitlabUrl.getSubfolder()))
.withName(gitlabUrl.getProject()), .withName(gitlabUrl.getProject()),
project -> { project -> {
final String location = project.getSource().getLocation(); final String location = project.getSource().getLocation();

View File

@ -49,9 +49,6 @@ public class GitlabUrl extends DefaultFactoryUrl {
/** Branch name */ /** Branch name */
private String branch; private String branch;
/** Subfolder if any */
private String subfolder;
/** Devfile filenames list */ /** Devfile filenames list */
private final List<String> devfileFilenames = new ArrayList<>(); private final List<String> devfileFilenames = new ArrayList<>();
@ -129,26 +126,6 @@ public class GitlabUrl extends DefaultFactoryUrl {
return this; return this;
} }
/**
* Gets subfolder of this gitlab url
*
* @return the subfolder part
*/
public String getSubfolder() {
return this.subfolder;
}
/**
* Sets the subfolder represented by the URL.
*
* @param subfolder path inside the repository
* @return current gitlab URL instance
*/
protected GitlabUrl withSubfolder(String subfolder) {
this.subfolder = subfolder;
return this;
}
/** /**
* Provides list of configured devfile filenames with locations * Provides list of configured devfile filenames with locations
* *

View File

@ -46,7 +46,7 @@ public class GitlabUrlParser {
private final PersonalAccessTokenManager personalAccessTokenManager; private final PersonalAccessTokenManager personalAccessTokenManager;
private static final List<String> gitlabUrlPatternTemplates = private static final List<String> gitlabUrlPatternTemplates =
List.of( List.of(
"^(?<host>%s)/(?<subgroups>([^/]++/?)+)/-/tree/(?<branch>[^/]++)(/)?(?<subfolder>[^/]++)?", "^(?<host>%s)/(?<subgroups>([^/]++/?)+)/-/tree/(?<branch>.++)(/)?",
"^(?<host>%s)/(?<subgroups>.*)"); // a wider one, should be the last in the "^(?<host>%s)/(?<subgroups>.*)"); // a wider one, should be the last in the
// list // list
private final List<Pattern> gitlabUrlPatterns = new ArrayList<>(); private final List<Pattern> gitlabUrlPatterns = new ArrayList<>();
@ -93,7 +93,8 @@ public class GitlabUrlParser {
} }
public boolean isValid(@NotNull String url) { public boolean isValid(@NotNull String url) {
return gitlabUrlPatterns.stream().anyMatch(pattern -> pattern.matcher(url).matches()) return gitlabUrlPatterns.stream()
.anyMatch(pattern -> pattern.matcher(trimEnd(url, '/')).matches())
// If the Gitlab URL is not configured, try to find it in a manually added user namespace // If the Gitlab URL is not configured, try to find it in a manually added user namespace
// token. // token.
|| isUserTokenPresent(url) || isUserTokenPresent(url)
@ -144,15 +145,15 @@ public class GitlabUrlParser {
* {@link GitlabUrl} objects. * {@link GitlabUrl} objects.
*/ */
public GitlabUrl parse(String url) { public GitlabUrl parse(String url) {
String trimmedUrl = trimEnd(url, '/');
Optional<Matcher> matcherOptional = Optional<Matcher> matcherOptional =
gitlabUrlPatterns.stream() gitlabUrlPatterns.stream()
.map(pattern -> pattern.matcher(url)) .map(pattern -> pattern.matcher(trimmedUrl))
.filter(Matcher::matches) .filter(Matcher::matches)
.findFirst() .findFirst()
.or(() -> getPatternMatcherByUrl(url)); .or(() -> getPatternMatcherByUrl(trimmedUrl));
if (matcherOptional.isPresent()) { if (matcherOptional.isPresent()) {
return parse(matcherOptional.get()).withUrl(url); return parse(matcherOptional.get()).withUrl(trimmedUrl);
} else { } else {
throw new UnsupportedOperationException( throw new UnsupportedOperationException(
"The gitlab integration is not configured properly and cannot be used at this moment." "The gitlab integration is not configured properly and cannot be used at this moment."
@ -168,23 +169,16 @@ public class GitlabUrlParser {
} }
String branch = null; String branch = null;
String subfolder = null;
try { try {
branch = matcher.group("branch"); branch = matcher.group("branch");
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
// ok no such group // ok no such group
} }
try {
subfolder = matcher.group("subfolder");
} catch (IllegalArgumentException e) {
// ok no such group
}
return new GitlabUrl() return new GitlabUrl()
.withHostName(host) .withHostName(host)
.withSubGroups(subGroups) .withSubGroups(subGroups)
.withBranch(branch) .withBranch(branch)
.withSubfolder(subfolder)
.withDevfileFilenames(devfileFilenamesProvider.getConfiguredDevfileFilenames()); .withDevfileFilenames(devfileFilenamesProvider.getConfiguredDevfileFilenames());
} }
} }

View File

@ -71,14 +71,12 @@ public class GitlabUrlParserTest {
/** Compare parsing */ /** Compare parsing */
@Test(dataProvider = "parsing") @Test(dataProvider = "parsing")
public void checkParsing( public void checkParsing(String url, String project, String subGroups, String branch) {
String url, String project, String subGroups, String branch, String subfolder) {
GitlabUrl gitlabUrl = gitlabUrlParser.parse(url); GitlabUrl gitlabUrl = gitlabUrlParser.parse(url);
assertEquals(gitlabUrl.getProject(), project); assertEquals(gitlabUrl.getProject(), project);
assertEquals(gitlabUrl.getSubGroups(), subGroups); assertEquals(gitlabUrl.getSubGroups(), subGroups);
assertEquals(gitlabUrl.getBranch(), branch); assertEquals(gitlabUrl.getBranch(), branch);
assertEquals(gitlabUrl.getSubfolder(), subfolder);
} }
@Test @Test
@ -123,33 +121,29 @@ public class GitlabUrlParserTest {
@DataProvider(name = "parsing") @DataProvider(name = "parsing")
public Object[][] expectedParsing() { public Object[][] expectedParsing() {
return new Object[][] { return new Object[][] {
{"https://gitlab1.com/user/project1.git", "project1", "user/project1", null, null}, {"https://gitlab1.com/user/project1.git", "project1", "user/project1", null},
{"https://gitlab1.com/user/project/test1.git", "test1", "user/project/test1", null, null}, {"https://gitlab1.com/user/project/test1.git", "test1", "user/project/test1", null},
{ {
"https://gitlab1.com/user/project/group1/group2/test1.git", "https://gitlab1.com/user/project/group1/group2/test1.git",
"test1", "test1",
"user/project/group1/group2/test1", "user/project/group1/group2/test1",
null,
null null
}, },
{"https://gitlab1.com/user/project/", "project", "user/project", null, null}, {"https://gitlab1.com/user/project/", "project", "user/project", null},
{"https://gitlab1.com/user/project/repo/", "repo", "user/project/repo", null, null}, {"https://gitlab1.com/user/project/repo/", "repo", "user/project/repo", null},
{"https://gitlab1.com/user/project/-/tree/master/", "project", "user/project", "master"},
{"https://gitlab1.com/user/project/repo/-/tree/foo", "repo", "user/project/repo", "foo"},
{ {
"https://gitlab1.com/user/project/-/tree/master/", "project", "user/project", "master", null "https://gitlab1.com/user/project/repo/-/tree/branch/with/slash",
},
{
"https://gitlab1.com/user/project/repo/-/tree/foo/subfolder",
"repo", "repo",
"user/project/repo", "user/project/repo",
"foo", "branch/with/slash"
"subfolder"
}, },
{ {
"https://gitlab1.com/user/project/group1/group2/repo/-/tree/foo/subfolder", "https://gitlab1.com/user/project/group1/group2/repo/-/tree/foo/",
"repo", "repo",
"user/project/group1/group2/repo", "user/project/group1/group2/repo",
"foo", "foo"
"subfolder"
} }
}; };
} }

View File

@ -85,10 +85,6 @@ public class GitlabUrlTest {
"https://gitlab.net/eclipse/fooproj/che/-/tree/foobranch/", "https://gitlab.net/eclipse/fooproj/che/-/tree/foobranch/",
"https://gitlab.net/api/v4/projects/eclipse%%2Ffooproj%%2Fche/repository/files/%s/raw?ref=foobranch" "https://gitlab.net/api/v4/projects/eclipse%%2Ffooproj%%2Fche/repository/files/%s/raw?ref=foobranch"
}, },
{
"https://gitlab.net/eclipse/fooproj/che/-/tree/foobranch/subfolder",
"https://gitlab.net/api/v4/projects/eclipse%%2Ffooproj%%2Fche/repository/files/%s/raw?ref=foobranch"
},
}; };
} }