Skip to content

Commit 694ee90

Browse files
committed
Introduce support for reference repository paths ending with /${GIT_URL} to replace by url => funny dir subtree in filesystem
1 parent cf116df commit 694ee90

3 files changed

Lines changed: 69 additions & 0 deletions

File tree

src/main/java/org/jenkinsci/plugins/gitclient/CliGitAPIImpl.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -762,6 +762,39 @@ public void execute() throws GitException, InterruptedException {
762762

763763
if (reference != null && !reference.isEmpty()) {
764764
File referencePath = new File(reference);
765+
if (!referencePath.exists()) {
766+
if (reference.endsWith("/${GIT_URL}")) {
767+
// See also JGitAPIImpl.java and keep the two blocks in
768+
// sync (TODO: refactor into a method both would use?)
769+
// For mass-configured jobs, like Organization Folders,
770+
// allow to support parameterized paths to many refrepos.
771+
// End-users can set up webs of symlinks to same repos
772+
// known by different URLs (and/or including their forks
773+
// also cached in same index). Luckily all URL chars are
774+
// valid parts of path name... in Unix... Maybe parse or
775+
// escape chars for URLs=>paths with Windows in mind?
776+
// https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file#naming-conventions
777+
// Further ideas: beside "GIT_URL" other meta variables
778+
// can be introduced, e.g. to escape non-ascii chars for
779+
// portability? Support SHA or MD5 hashes of URLs as
780+
// pathnames?
781+
reference = reference.replaceAll("\\$\\{GIT_URL\\}$", url).replaceAll("/*$", "").replaceAll(".git$", "");
782+
referencePath = new File(reference);
783+
if (!referencePath.exists()) {
784+
// Normalize the URLs with or without .git suffix to
785+
// be served by same dir with the refrepo contents
786+
reference += ".git";
787+
referencePath = new File(reference);
788+
}
789+
// Note: both these logs are needed, they are used in selftest
790+
if (referencePath.exists()) {
791+
listener.getLogger().println("[WARNING] Parameterized reference path replaced with: " + reference);
792+
} else {
793+
listener.getLogger().println("[WARNING] Parameterized reference path replaced with: " + reference + " was not found");
794+
}
795+
}
796+
}
797+
765798
if (!referencePath.exists())
766799
listener.getLogger().println("[WARNING] Reference path does not exist: " + reference);
767800
else if (!referencePath.isDirectory())

src/main/java/org/jenkinsci/plugins/gitclient/JGitAPIImpl.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1434,6 +1434,27 @@ public void execute() throws GitException, InterruptedException {
14341434
// the repository builder does not create the alternates file
14351435
if (reference != null && !reference.isEmpty()) {
14361436
File referencePath = new File(reference);
1437+
if (!referencePath.exists()) {
1438+
if (reference.endsWith("/${GIT_URL}")) {
1439+
// See comments in CliGitAPIImpl.java for details
1440+
// Keep the two blocks in sync (refactor into method?)
1441+
reference = reference.replaceAll("\\$\\{GIT_URL\\}$", url).replaceAll("/*$", "").replaceAll(".git$", "");
1442+
referencePath = new File(reference);
1443+
if (!referencePath.exists()) {
1444+
// Normalize the URLs with or without .git suffix to
1445+
// be served by same dir with the refrepo contents
1446+
reference += ".git";
1447+
referencePath = new File(reference);
1448+
}
1449+
// Note: both these logs are needed, they are used in selftest
1450+
if (referencePath.exists()) {
1451+
listener.getLogger().println("[WARNING] Parameterized reference path replaced with: " + reference);
1452+
} else {
1453+
listener.getLogger().println("[WARNING] Parameterized reference path replaced with: " + reference + " was not found");
1454+
}
1455+
}
1456+
}
1457+
14371458
if (!referencePath.exists())
14381459
listener.getLogger().println("[WARNING] Reference path does not exist: " + reference);
14391460
else if (!referencePath.isDirectory())

src/test/java/org/jenkinsci/plugins/gitclient/GitClientCloneTest.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,21 @@ public void test_clone_reference() throws Exception, IOException, InterruptedExc
238238
assertThat("Reference repo logged in: " + messages, handler.containsMessageSubstring("Using reference repository: "), is(true));
239239
}
240240

241+
@Test
242+
public void test_clone_reference_parameterized() throws Exception, IOException, InterruptedException {
243+
testGitClient.clone_().url(workspace.localMirror()).repositoryName("origin").reference(workspace.localMirror() + "/${GIT_URL}").execute();
244+
testGitClient.checkout().ref("origin/master").branch("master").execute();
245+
check_remote_url(workspace, testGitClient, "origin");
246+
// Verify JENKINS-46737 expected log message is written
247+
String messages = StringUtils.join(handler.getMessages(), ";");
248+
assertThat("Reference repo name-parsing logged in: " + messages, handler.containsMessageSubstring("Parameterized reference path replaced with: "), is(true));
249+
// Skip: Missing if clone failed - currently would, with bogus path above and not pre-created path structure
250+
//assertThat("Reference repo logged in: " + messages, handler.containsMessageSubstring("Using reference repository: "), is(true));
251+
//assertAlternateFilePointsToLocalMirror();
252+
//assertBranchesExist(testGitClient.getBranches(), "master");
253+
//assertNoObjectsInRepository();
254+
}
255+
241256
private static final String SRC_DIR = (new File(".")).getAbsolutePath();
242257

243258
@Test

0 commit comments

Comments
 (0)