Add support to create manifest after branch/tag operation
Change-Id: I353beb5aaeb503e76cda44206fe5ad48609c7b58
diff --git a/src/main/java/com/amd/gerrit/plugins/manifestsubscription/BranchManifestCommand.java b/src/main/java/com/amd/gerrit/plugins/manifestsubscription/BranchManifestCommand.java
index b508589..0f3ce1f 100644
--- a/src/main/java/com/amd/gerrit/plugins/manifestsubscription/BranchManifestCommand.java
+++ b/src/main/java/com/amd/gerrit/plugins/manifestsubscription/BranchManifestCommand.java
@@ -14,22 +14,15 @@
package com.amd.gerrit.plugins.manifestsubscription;
-import com.amd.gerrit.plugins.manifestsubscription.manifest.Manifest;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.extensions.annotations.RequiresCapability;
-import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.git.GitRepositoryManager;
+import com.google.gerrit.server.git.MetaDataUpdate;
import com.google.gerrit.sshd.CommandMetaData;
import com.google.gerrit.sshd.SshCommand;
import com.google.inject.Inject;
-import org.eclipse.jgit.api.errors.GitAPIException;
-import org.eclipse.jgit.errors.ConfigInvalidException;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.Repository;
-import org.kohsuke.args4j.Option;
-import javax.xml.bind.JAXBException;
-import java.io.IOException;
+import org.kohsuke.args4j.Option;
@RequiresCapability(GlobalCapability.ADMINISTRATE_SERVER)
@CommandMetaData(name = "branch", description = "branch all projects described in a manifest on the server")
@@ -38,6 +31,9 @@
@Inject
private GitRepositoryManager gitRepoManager;
+ @Inject
+ private MetaDataUpdate.Server metaDataUpdateFactory;
+
@Option(name = "-r", aliases = {"--manifest-repo"},
usage = "", required = true)
private String manifestRepo;
@@ -58,6 +54,21 @@
usage = "", required = false)
private Utilities.OutputType outputType;
+ @Option(name = "-nr", aliases = {"--new-manifest-repo"},
+ depends = {"-nb", "-np"},
+ usage = "", required = false)
+ private String newManifestRepo;
+
+ @Option(name = "-nb", aliases = {"--new-manifest-branch"},
+ depends = {"-nr", "-np"},
+ usage = "", required = false)
+ private String newManifestBranch;
+
+ @Option(name = "-np", aliases = {"--new-manifest-path"},
+ depends = {"-nb", "-nr"},
+ usage = "", required = false)
+ private String newManifestPath;
+
@Override
protected void run() {
stdout.println("Branching manifest:");
@@ -65,8 +76,14 @@
stdout.println(manifestCommitish);
stdout.println(manifestPath);
- Utilities.branchManifest(gitRepoManager, manifestRepo, manifestCommitish,
- manifestPath, newBranch, stdout, stderr,
+ stdout.println(newManifestRepo);
+ stdout.println(newManifestBranch);
+ stdout.println(newManifestPath);
+
+ Utilities.branchManifest(gitRepoManager, metaDataUpdateFactory,
+ manifestRepo, manifestCommitish, manifestPath, newBranch,
+ newManifestRepo, newManifestBranch, newManifestPath,
+ stdout, stderr,
outputType==Utilities.OutputType.JSON);
}
diff --git a/src/main/java/com/amd/gerrit/plugins/manifestsubscription/BranchManifestServlet.java b/src/main/java/com/amd/gerrit/plugins/manifestsubscription/BranchManifestServlet.java
index 4245db1..68a198a 100644
--- a/src/main/java/com/amd/gerrit/plugins/manifestsubscription/BranchManifestServlet.java
+++ b/src/main/java/com/amd/gerrit/plugins/manifestsubscription/BranchManifestServlet.java
@@ -16,6 +16,7 @@
import com.google.gerrit.extensions.annotations.Export;
import com.google.gerrit.server.git.GitRepositoryManager;
+import com.google.gerrit.server.git.MetaDataUpdate;
import com.google.inject.Inject;
import com.google.inject.Singleton;
@@ -33,36 +34,41 @@
@Inject
private GitRepositoryManager gitRepoManager;
+ @Inject
+ private MetaDataUpdate.Server metaDataUpdateFactory;
+
protected void doPost(HttpServletRequest req, HttpServletResponse res)
throws IOException {
Map<String, String[]> input = req.getParameterMap();
- if (inputValid(req)) {
+ if (Utilities.httpInputValid(req)) {
res.setContentType("application/json");
res.setCharacterEncoding("UTF-8");
+ String newManifestRepo = null;
+ String newManifestBranch= null;
+ String newManifestPath = null;
+
+ if (input.containsKey("new-manifest-repo")) {
+ newManifestRepo = input.get("new-manifest-repo")[0];
+ newManifestBranch = input.get("new-manifest-branch")[0];
+ newManifestPath = input.get("new-manifest-path")[0];
+ }
+
Utilities.branchManifest(gitRepoManager,
+ metaDataUpdateFactory,
input.get("manifest-repo")[0],
input.get("manifest-commit-ish")[0],
input.get("manifest-path")[0],
input.get("new-branch")[0],
+ newManifestRepo,
+ newManifestBranch,
+ newManifestPath,
res.getWriter(), null, true);
} else {
res.setStatus(HttpServletResponse.SC_BAD_REQUEST);
}
}
-
- private boolean inputValid(HttpServletRequest request) {
- Map<String, String[]> input = request.getParameterMap();
- if(input.containsKey("manifest-repo") &&
- input.containsKey("manifest-commit-ish") &&
- input.containsKey("manifest-path") &&
- input.containsKey("new-branch")) {
- return true;
- }
-
- return false;
- }
}
diff --git a/src/main/java/com/amd/gerrit/plugins/manifestsubscription/TagManifestServlet.java b/src/main/java/com/amd/gerrit/plugins/manifestsubscription/TagManifestServlet.java
index 434d3c0..d8e4433 100644
--- a/src/main/java/com/amd/gerrit/plugins/manifestsubscription/TagManifestServlet.java
+++ b/src/main/java/com/amd/gerrit/plugins/manifestsubscription/TagManifestServlet.java
@@ -38,7 +38,17 @@
res.setCharacterEncoding("UTF-8");
Map<String, String[]> input = req.getParameterMap();
- if (inputValid(req)) {
+ String newManifestRepo = null;
+ String newManifestBranch= null;
+ String newManifestPath = null;
+
+ if (input.containsKey("new-manifest-repo")) {
+ newManifestRepo = input.get("new-manifest-repo")[0];
+ newManifestBranch = input.get("new-manifest-branch")[0];
+ newManifestPath = input.get("new-manifest-path")[0];
+ }
+
+ if (Utilities.httpInputValid(req)) {
res.setContentType("application/json");
res.setCharacterEncoding("UTF-8");
@@ -53,17 +63,4 @@
res.setStatus(HttpServletResponse.SC_BAD_REQUEST);
}
}
-
- private boolean inputValid(HttpServletRequest request) {
- Map<String, String[]> input = request.getParameterMap();
- if(input.containsKey("manifest-repo") &&
- input.containsKey("manifest-commit-ish") &&
- input.containsKey("manifest-path") &&
- input.containsKey("new-tag")) {
- return true;
- }
-
- return false;
- }
-
}
diff --git a/src/main/java/com/amd/gerrit/plugins/manifestsubscription/Utilities.java b/src/main/java/com/amd/gerrit/plugins/manifestsubscription/Utilities.java
index 8a8a2d8..fb6608b 100644
--- a/src/main/java/com/amd/gerrit/plugins/manifestsubscription/Utilities.java
+++ b/src/main/java/com/amd/gerrit/plugins/manifestsubscription/Utilities.java
@@ -18,16 +18,21 @@
import com.google.common.collect.Maps;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.git.GitRepositoryManager;
+import com.google.gerrit.server.git.MetaDataUpdate;
import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
+import com.amd.gerrit.plugins.manifestsubscription.manifest.Default;
import com.amd.gerrit.plugins.manifestsubscription.manifest.Manifest;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.PrintWriter;
@@ -35,15 +40,40 @@
import java.util.Map;
import java.util.Set;
+import javax.servlet.http.HttpServletRequest;
import javax.xml.bind.JAXBException;
public class Utilities {
+ private static final Logger log =
+ LoggerFactory.getLogger(Utilities.class);
private static Gson gson = new GsonBuilder()
.generateNonExecutableJson()
.setPrettyPrinting()
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
.create();
+ static boolean httpInputValid(HttpServletRequest request) {
+ Map<String, String[]> input = request.getParameterMap();
+ if (input.containsKey("manifest-repo") &&
+ input.containsKey("manifest-commit-ish") &&
+ input.containsKey("manifest-path") &&
+ (input.containsKey("new-branch") || input.containsKey("new-tag")) ) {
+
+ // these inputs are related. Either they are all present or all absent
+ if ((input.containsKey("new-manifest-repo") &&
+ input.containsKey("new-manifest-branch") &&
+ input.containsKey("new-manifest-path")) ||
+ (!input.containsKey("new-manifest-repo") &&
+ !input.containsKey("new-manifest-branch") &&
+ !input.containsKey("new-manifest-path"))) {
+
+ return true;
+ }
+ }
+
+ return false;
+ }
+
public enum OutputType {
TEXT,
JSON
@@ -56,7 +86,6 @@
JAXBException {
Project.NameKey p = new Project.NameKey(manifestRepo);
-
Repository repo = gitRepoManager.openRepository(p);
ObjectId commitId = repo.resolve(manifestCommitish);
VersionedManifests vManifests = new VersionedManifests(manifestCommitish);
@@ -66,6 +95,89 @@
return manifests.getCanonicalManifest(manifestPath);
}
+ static Manifest createNewManifestFromBase
+ (GitRepositoryManager gitRepoManager,
+ MetaDataUpdate.Server metaDataUpdateFactory,
+ String manifestRepo,
+ String manifestBranch,
+ String manifestPath,
+ String newRef,
+ Manifest base)
+ throws JAXBException, IOException, ConfigInvalidException, GitAPIException {
+
+ // Replace default ref with newly created branch or tag
+ Manifest manifest = (Manifest) base.clone();
+ final String defaultRef;
+ if (manifest.getDefault() != null) {
+ defaultRef = manifest.getDefault().getRevision();
+ } else {
+ defaultRef = null;
+ }
+
+ if (manifest.getDefault() != null) {
+ ManifestOp op = new ManifestOp() {
+ @Override
+ public boolean apply(com.amd.gerrit.plugins.manifestsubscription.manifest.Project project,
+ String hash, String name,
+ GitRepositoryManager gitRepoManager) throws
+ GitAPIException, IOException {
+
+ //This is assuming newRef points to the existing hash
+ if (project.getRevision() != null && project.getRevision().equals(hash)) {
+ project.setRevision(null);
+ } else {
+ project.setRevision(defaultRef);
+ }
+
+ return true;
+ }
+ };
+
+ VersionedManifests.traverseManifestAndApplyOp(gitRepoManager,
+ manifest.getProject(), defaultRef, op, null);
+ } else {
+ manifest.setDefault(new Default());
+ }
+
+ manifest.getDefault().setRevision(newRef);
+
+ Project.NameKey p = new Project.NameKey(manifestRepo);
+ Repository repo = gitRepoManager.openRepository(p);
+ ObjectId commitId = repo.resolve(manifestBranch);
+ VersionedManifests vManifests;
+ MetaDataUpdate update = metaDataUpdateFactory.create(p);
+ if (commitId == null) {
+ // TODO remove assumption that master branch always exists
+ vManifests = new VersionedManifests("master");
+ vManifests.load(update);
+ } else {
+ vManifests = new VersionedManifests(manifestBranch);
+ vManifests.load(repo, commitId);
+ }
+
+
+ Map<String, Manifest> entry = Maps.newHashMapWithExpectedSize(1);
+ entry.put(manifestPath, manifest);
+ vManifests.setManifests(entry);
+
+ RevCommit commit;
+ if (commitId == null) {
+ commit = vManifests.commitToNewRef(update, manifestBranch);
+ } else {
+ commit = vManifests.commit(update);
+ }
+
+ //TODO
+ //if (commit != null) {
+ // changeHooks.doRefUpdatedHook(new Branch.NameKey(p, refName),
+ // commit.getParent(0).getId(),
+ // commit.getId(), null);
+ //} else {
+ // log.warn("Failing to create new manifest");
+ //}
+ return manifest;
+ }
+
private static void outputError(Writer output, PrintWriter error,
boolean inJSON, Exception e) {
if (inJSON) {
@@ -105,8 +217,12 @@
}
static void branchManifest(GitRepositoryManager gitRepoManager,
+ MetaDataUpdate.Server metaDataUpdateFactory,
String manifestRepo, String manifestCommitish,
String manifestPath, String newBranch,
+ String newManifestRepo,
+ String newManifestBranch,
+ String newManifestPath,
Writer output, PrintWriter error, boolean inJSON) {
Manifest manifest;
@@ -115,6 +231,14 @@
manifestCommitish, manifestPath);
VersionedManifests.branchManifest(gitRepoManager, manifest, newBranch);
+ if (newManifestBranch != null &&
+ newManifestPath != null &&
+ newManifestRepo != null) {
+ createNewManifestFromBase(gitRepoManager, metaDataUpdateFactory,
+ newManifestRepo, newManifestBranch, newManifestPath,
+ newBranch, manifest);
+ }
+
} catch (IOException | ConfigInvalidException | ManifestReadException |
JAXBException | GitAPIException e) {
outputError(output, error, inJSON, e);
diff --git a/src/main/java/com/amd/gerrit/plugins/manifestsubscription/VersionedManifests.java b/src/main/java/com/amd/gerrit/plugins/manifestsubscription/VersionedManifests.java
index 3e1f8d3..cc3dbb1 100644
--- a/src/main/java/com/amd/gerrit/plugins/manifestsubscription/VersionedManifests.java
+++ b/src/main/java/com/amd/gerrit/plugins/manifestsubscription/VersionedManifests.java
@@ -31,6 +31,8 @@
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.treewalk.TreeWalk;
import org.eclipse.jgit.treewalk.filter.PathSuffixFilter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
@@ -42,6 +44,8 @@
import java.util.*;
public class VersionedManifests extends VersionedMetaData implements ManifestProvider {
+ private static final Logger log =
+ LoggerFactory.getLogger(VersionedManifests.class);
private String refName;
private Unmarshaller manifestUnmarshaller;
private Marshaller manifestMarshaller;
@@ -306,7 +310,7 @@
traverseManifestAndApplyOp(gitRepoManager, manifest.getProject(), defaultRef, op, lookup);
}
- private static void traverseManifestAndApplyOp(
+ static void traverseManifestAndApplyOp(
GitRepositoryManager gitRepoManager,
List<com.amd.gerrit.plugins.manifestsubscription.manifest.Project> projects,
String defaultRef,
@@ -324,7 +328,11 @@
ref = (ref == null) ? defaultRef : ref;
if (ref != null) {
- hash = lookup.get(projectName, ref);
+ if (lookup != null) {
+ hash = lookup.get(projectName, ref);
+ } else {
+ hash = null;
+ }
if (hash == null) {
p = new Project.NameKey(projectName);
@@ -339,7 +347,7 @@
}
if (hash != null) {
- lookup.put(projectName, ref, hash);
+ if (lookup != null) lookup.put(projectName, ref, hash);
op.apply(project, hash, ref, gitRepoManager);
}
}
diff --git a/src/main/resources/Documentation/cmd-branch.md b/src/main/resources/Documentation/cmd-branch.md
index acf913b..d22bbda 100644
--- a/src/main/resources/Documentation/cmd-branch.md
+++ b/src/main/resources/Documentation/cmd-branch.md
@@ -14,6 +14,10 @@
{-c/--manifest-commit-ish <manifest commit-ish>}
{-p/--manifest-path <manifest path>}
{-b/--new-branch <new branch name>}
+ [-o/--output-type]
+ [-nr/--new-manifest-repo <new manifest repo>]
+ [-nc/--new-manifest-branch <new manifest branch>]
+ [-np/--new-manifest-path <new manifest path>]
[--help]
```
@@ -32,6 +36,11 @@
`-b/--new-branch <new branch name>`
: The name of the branch that will be created on all projects in the manifest specified above
+`-nr/--new-manifest-repo <new manifest repo>`
+`-nb/--new-manifest-branch <new manifest branch>`
+`-np/--new-manifest-path <new manifest path>`
+: (optional) A new manifest (to be created) that points to the new branch
+
EXAMPLES
--------
Branch all projects on the server described in the `default.xml` manifest in commit 5f51acb585b6a of repo `demo/build_manifest` to branch `releases/1.0.0`