Merge "Parse and record remote review host in .gitattributes"
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/ManifestParserTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/ManifestParserTest.java
index 0949d04..d8ac28c 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/ManifestParserTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/ManifestParserTest.java
@@ -254,4 +254,26 @@ public void testXXE() throws Exception {
assertTrue(e.getCause().getMessage().contains("DOCTYPE"));
}
+ @Test
+ public void testManifestParserWithReview() throws Exception {
+ String baseUrl = "https://git.google.com/";
+ StringBuilder xmlContent = new StringBuilder();
+ xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
+ .append("<manifest>")
+ .append("<remote name=\"remote1\" fetch=\".\" review=\"https://review-1.com\" />")
+ .append("<remote name=\"remote2\" fetch=\".\" review=\"https://review-2.com\" />")
+ .append("<default revision=\"master\" remote=\"remote1\" />")
+ .append("<project path=\"foo\" name=\"foo\" />")
+ .append("<project path=\"bar\" name=\"bar\" remote=\"remote2\" />")
+ .append("</manifest>");
+
+ ManifestParser parser = new ManifestParser(null, null, "master", baseUrl, null, null);
+ parser.read(new ByteArrayInputStream(xmlContent.toString().getBytes(UTF_8)));
+
+ Map<String, RepoProject> map = parser.getProjects().stream()
+ .collect(Collectors.toMap(RepoProject::getPath, Function.identity()));
+ assertEquals("https://review-1.com", map.get("foo").getReview());
+ assertEquals("https://review-2.com", map.get("bar").getReview());
+ }
+
}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java
index 3162e79..ceb18e6 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java
@@ -1302,6 +1302,104 @@ public void testRecordSubmoduleLabels() throws Exception {
}
@Test
+ public void testRecordSubmoduleLabelsWithRemoteReview() throws Exception {
+ Repository remoteDb = createBareRepository();
+ Repository tempDb = createWorkRepository();
+
+ StringBuilder xmlContent = new StringBuilder();
+ xmlContent
+ .append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
+ .append("<manifest>")
+ .append(
+ "<remote name=\"remote1\" fetch=\".\""
+ + " review=\"https://googleplex-android-review.git.corp.google.com\" />")
+ .append("<default revision=\"master\" remote=\"remote1\" />")
+ .append("<project path=\"test\" ")
+ .append("revision=\"master\" ")
+ .append("name=\"")
+ .append(notDefaultUri)
+ .append("\" ")
+ .append("groups=\"a1,a2\" />")
+ .append("</manifest>");
+ JGitTestUtil.writeTrashFile(tempDb, "manifest.xml", xmlContent.toString());
+
+ RepoCommand command = new RepoCommand(remoteDb);
+ command
+ .setPath(tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml")
+ .setURI(rootUri)
+ .setRecordSubmoduleLabels(true)
+ .call();
+ // Clone it
+ File directory = createTempDirectory("testBareRepo");
+ try (Repository localDb =
+ Git.cloneRepository()
+ .setDirectory(directory)
+ .setURI(remoteDb.getDirectory().toURI().toString())
+ .call()
+ .getRepository(); ) {
+ // The .gitattributes file should exist
+ File gitattributes = new File(localDb.getWorkTree(), ".gitattributes");
+ assertTrue("The .gitattributes file should exist", gitattributes.exists());
+ try (BufferedReader reader = Files.newBufferedReader(gitattributes.toPath(), UTF_8)) {
+ String content = reader.readLine();
+ assertEquals(
+ ".gitattributes content should be as expected",
+ "/test a1 a2 remote-review=googleplex-android",
+ content);
+ }
+ }
+ }
+
+ @Test
+ public void testRecordSubmoduleLabelsWithDefaultReview() throws Exception {
+ Repository remoteDb = createBareRepository();
+ Repository tempDb = createWorkRepository();
+
+ StringBuilder xmlContent = new StringBuilder();
+ xmlContent
+ .append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
+ .append("<manifest>")
+ .append("<remote name=\"remote1\" fetch=\".\" />")
+ .append(
+ "<default revision=\"master\" remote=\"remote1\""
+ + " review=\"https://googleplex-android-review.git.corp.google.com\" />")
+ .append("<project path=\"test\" ")
+ .append("revision=\"master\" ")
+ .append("name=\"")
+ .append(notDefaultUri)
+ .append("\" ")
+ .append("groups=\"a1,a2\" />")
+ .append("</manifest>");
+ JGitTestUtil.writeTrashFile(tempDb, "manifest.xml", xmlContent.toString());
+
+ RepoCommand command = new RepoCommand(remoteDb);
+ command
+ .setPath(tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml")
+ .setURI(rootUri)
+ .setRecordSubmoduleLabels(true)
+ .call();
+ // Clone it
+ File directory = createTempDirectory("testBareRepo");
+ try (Repository localDb =
+ Git.cloneRepository()
+ .setDirectory(directory)
+ .setURI(remoteDb.getDirectory().toURI().toString())
+ .call()
+ .getRepository(); ) {
+ // The .gitattributes file should exist
+ File gitattributes = new File(localDb.getWorkTree(), ".gitattributes");
+ assertTrue("The .gitattributes file should exist", gitattributes.exists());
+ try (BufferedReader reader = Files.newBufferedReader(gitattributes.toPath(), UTF_8)) {
+ String content = reader.readLine();
+ assertEquals(
+ ".gitattributes content should be as expected",
+ "/test a1 a2 remote-review=googleplex-android",
+ content);
+ }
+ }
+ }
+
+ @Test
public void testRecordShallowRecommendation() throws Exception {
Repository remoteDb = createBareRepository();
Repository tempDb = createWorkRepository();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/BareSuperprojectWriter.java b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/BareSuperprojectWriter.java
index e511a68..bfc7c9c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/BareSuperprojectWriter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/BareSuperprojectWriter.java
@@ -192,6 +192,11 @@ private void prepareIndex(List<RepoProject> projects, DirCache index,
rec.append(" "); //$NON-NLS-1$
rec.append(group);
}
+ String reviewHost = getPlainHost(proj.getReview());
+ if (reviewHost != null && !reviewHost.isEmpty()) {
+ rec.append(" remote-review="); //$NON-NLS-1$
+ rec.append(reviewHost);
+ }
rec.append("\n"); //$NON-NLS-1$
attributes.append(rec.toString());
}
@@ -320,4 +325,37 @@ private RevCommit commitTreeOnCurrentTip(ObjectInserter inserter,
return rw.parseCommit(commitId);
}
+
+ private static String getReviewHost(String reviewUrl) {
+ if (reviewUrl == null) {
+ return null;
+ }
+ try {
+ if (!reviewUrl.contains("://")) { //$NON-NLS-1$
+ reviewUrl = "https://" + reviewUrl; //$NON-NLS-1$
+ }
+ return URI.create(reviewUrl).getHost();
+ } catch (IllegalArgumentException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Return the host name without "-review" suffix.
+ *
+ * @param reviewUrl
+ * the review URL
+ * @return host name without "-review" suffix
+ */
+ private static String getPlainHost(String reviewUrl) {
+ String host = getReviewHost(reviewUrl);
+ if (host == null) {
+ return null;
+ }
+ int reviewIdx = host.indexOf("-review"); //$NON-NLS-1$
+ if (reviewIdx != -1) {
+ return host.substring(0, reviewIdx);
+ }
+ return host;
+ }
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/ManifestParser.java b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/ManifestParser.java
index 12ba893..32234a0 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/ManifestParser.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/ManifestParser.java
@@ -61,6 +61,7 @@ public class ManifestParser extends DefaultHandler {
private String defaultRemote;
private String defaultRevision;
+ private String defaultReview;
private int xmlInRead;
private RepoProject currentProject;
@@ -195,7 +196,8 @@ public void startElement(
String alias = attributes.getValue("alias");
String fetch = attributes.getValue("fetch");
String revision = attributes.getValue("revision");
- Remote remote = new Remote(fetch, revision);
+ String review = attributes.getValue("review");
+ Remote remote = new Remote(fetch, revision, review);
remotes.put(attributes.getValue("name"), remote);
if (alias != null) {
remotes.put(alias, remote);
@@ -204,6 +206,7 @@ public void startElement(
case "default":
defaultRemote = attributes.getValue("remote");
defaultRevision = attributes.getValue("revision");
+ defaultReview = attributes.getValue("review");
break;
case "copyfile":
if (currentProject == null) {
@@ -314,6 +317,12 @@ public void endDocument() throws SAXException {
}
proj.setUrl(remoteUrl.resolve(proj.getName()).toString())
.setDefaultRevision(revision);
+ Remote r = remotes.get(remote);
+ if (r != null && r.review != null) {
+ proj.setReview(r.review);
+ } else if (defaultReview != null) {
+ proj.setReview(defaultReview);
+ }
}
filteredProjects.addAll(projects);
@@ -440,10 +449,12 @@ private boolean isNestedReferencefile(ReferenceFile referencefile) {
private static class Remote {
final String fetch;
final String revision;
+ final String review;
- Remote(String fetch, String revision) {
+ Remote(String fetch, String revision, String review) {
this.fetch = fetch;
this.revision = revision;
+ this.review = review;
}
}
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java
index 392ca92..32f2ad1 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java
@@ -591,6 +591,7 @@ private List<RepoProject> renameProjects(List<RepoProject> projects) {
p.addCopyFiles(proj.getCopyFiles());
p.addLinkFiles(proj.getLinkFiles());
p.setUpstream(proj.getUpstream());
+ p.setReview(proj.getReview());
ret.add(p);
}
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoProject.java b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoProject.java
index 07eb12d..97f461c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoProject.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoProject.java
@@ -41,6 +41,7 @@ public class RepoProject implements Comparable<RepoProject> {
private String upstream;
private String destBranch;
private String recommendShallow;
+ private String review;
private String url;
private String defaultRevision;
@@ -333,6 +334,27 @@ public void setRecommendShallow(String recommendShallow) {
}
/**
+ * Return the Gerrit review server URL defined by the project's remote.
+ *
+ * @return the review server URL
+ * @since 7.8
+ */
+ public String getReview() {
+ return review;
+ }
+
+ /**
+ * Sets the Gerrit review server URL.
+ *
+ * @param review the review server URL
+ * @since 7.8
+ */
+ public void setReview(String review) {
+ this.review = review;
+ }
+
+
+ /**
* Add a copy file configuration.
*
* @param copyfile a {@link org.eclipse.jgit.gitrepo.RepoProject.CopyFile} object.