Browse Source

Added groups support to repo subcommand.

Change-Id: Id0e7663b6ac4f6938fdcacaf2158107b6285fc25
Signed-off-by: Yuxuan 'fishy' Wang <fishywang@google.com>
tags/v3.4.0.201405051725-m7
Yuxuan 'fishy' Wang 10 years ago
parent
commit
a44a687fed

+ 83
- 13
org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/RepoTest.java View File

@@ -43,6 +43,7 @@
package org.eclipse.jgit.pgm;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.io.BufferedReader;
@@ -57,17 +58,47 @@ import org.junit.Before;
import org.junit.Test;

public class RepoTest extends CLIRepositoryTestCase {
private Repository remoteDb;
private Repository defaultDb;
private Repository notDefaultDb;
private Repository groupADb;
private Repository groupBDb;

private String rootUri;
private String defaultUri;
private String notDefaultUri;
private String groupAUri;
private String groupBUri;

@Override
@Before
public void setUp() throws Exception {
super.setUp();
remoteDb = createWorkRepository();
Git git = new Git(remoteDb);
JGitTestUtil.writeTrashFile(remoteDb, "hello.txt", "world");

defaultDb = createWorkRepository();
Git git = new Git(defaultDb);
JGitTestUtil.writeTrashFile(defaultDb, "hello.txt", "world");
git.add().addFilepattern("hello.txt").call();
git.commit().setMessage("Initial commit").call();

notDefaultDb = createWorkRepository();
git = new Git(notDefaultDb);
JGitTestUtil.writeTrashFile(notDefaultDb, "world.txt", "hello");
git.add().addFilepattern("world.txt").call();
git.commit().setMessage("Initial commit").call();

groupADb = createWorkRepository();
git = new Git(groupADb);
JGitTestUtil.writeTrashFile(groupADb, "a.txt", "world");
git.add().addFilepattern("a.txt").call();
git.commit().setMessage("Initial commit").call();

groupBDb = createWorkRepository();
git = new Git(groupBDb);
JGitTestUtil.writeTrashFile(groupBDb, "b.txt", "world");
git.add().addFilepattern("b.txt").call();
git.commit().setMessage("Initial commit").call();

resolveRelativeUris();
}

@Test
@@ -77,20 +108,59 @@ public class RepoTest extends CLIRepositoryTestCase {
.append("<manifest>")
.append("<remote name=\"remote1\" fetch=\".\" />")
.append("<default revision=\"master\" remote=\"remote1\" />")
.append("<project path=\"foo\" name=\".\" />")
.append("<project path=\"foo\" name=\"")
.append(defaultUri)
.append("\" groups=\"a,test\" />")
.append("<project path=\"bar\" name=\"")
.append(notDefaultUri)
.append("\" groups=\"notdefault\" />")
.append("<project path=\"a\" name=\"")
.append(groupAUri)
.append("\" groups=\"a\" />")
.append("<project path=\"b\" name=\"")
.append(groupBUri)
.append("\" groups=\"b\" />")
.append("</manifest>");
writeTrashFile("manifest.xml", xmlContent.toString());
StringBuilder cmd = new StringBuilder("git repo --base-uri=\"")
.append(remoteDb.getDirectory().toURI().toString())
.append("\" \"")
.append(rootUri)
.append("\" --groups=\"all,-a\" \"")
.append(db.getWorkTree().getAbsolutePath())
.append("/manifest.xml\"");
execute(cmd.toString());
File hello = new File(db.getWorkTree(), "foo/hello.txt");
assertTrue("submodule was checked out.", hello.exists());
BufferedReader reader = new BufferedReader(new FileReader(hello));
String content = reader.readLine();
reader.close();
assertEquals("submodule content is as expected.", "world", content);

File file = new File(db.getWorkTree(), "foo/hello.txt");
assertFalse("\"all,-a\" doesn't have foo", file.exists());
file = new File(db.getWorkTree(), "bar/world.txt");
assertTrue("\"all,-a\" has bar", file.exists());
file = new File(db.getWorkTree(), "a/a.txt");
assertFalse("\"all,-a\" doesn't have a", file.exists());
file = new File(db.getWorkTree(), "b/b.txt");
assertTrue("\"all,-a\" has have b", file.exists());
}

private void resolveRelativeUris() {
// Find the longest common prefix ends with "/" as rootUri.
defaultUri = defaultDb.getDirectory().toURI().toString();
notDefaultUri = notDefaultDb.getDirectory().toURI().toString();
groupAUri = groupADb.getDirectory().toURI().toString();
groupBUri = groupBDb.getDirectory().toURI().toString();
int start = 0;
while (start <= defaultUri.length()) {
int newStart = defaultUri.indexOf('/', start + 1);
String prefix = defaultUri.substring(0, newStart);
if (!notDefaultUri.startsWith(prefix) ||
!groupAUri.startsWith(prefix) ||
!groupBUri.startsWith(prefix)) {
start++;
rootUri = defaultUri.substring(0, start);
defaultUri = defaultUri.substring(start);
notDefaultUri = notDefaultUri.substring(start);
groupAUri = groupAUri.substring(start);
groupBUri = groupBUri.substring(start);
return;
}
start = newStart;
}
}
}

+ 1
- 0
org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties View File

@@ -278,6 +278,7 @@ usage_forceCheckout=when switching branches, proceed even if the index or the wo
usage_forceCreateBranchEvenExists=force create branch even exists
usage_forceReplacingAnExistingTag=force replacing an existing tag
usage_getAndSetOptions=Get and set repository or global options
usage_groups=Restrict manifest projects to ones with specified group(s), use "-" for excluding [default|all|G1,G2,G3|G4,-G5,-G6]
usage_hostnameOrIpToListenOn=hostname (or ip) to listen on
usage_indexFileFormatToCreate=index file format to create
usage_ignoreWhitespace=ignore all whitespace

+ 4
- 0
org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Repo.java View File

@@ -52,6 +52,9 @@ class Repo extends TextBuiltin {
@Option(name = "--base-uri", aliases = { "-u" }, usage = "usage_baseUri")
private String uri;

@Option(name = "--groups", aliases = { "-g" }, usage = "usage_groups")
private String groups = "default"; //$NON-NLS-1$

@Argument(required = true, usage = "usage_pathToXml")
private String path;

@@ -60,6 +63,7 @@ class Repo extends TextBuiltin {
new RepoCommand(db)
.setURI(uri)
.setPath(path)
.setGroups(groups)
.call();
}
}

+ 118
- 6
org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java View File

@@ -43,6 +43,7 @@
package org.eclipse.jgit.gitrepo;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.io.BufferedReader;
@@ -57,16 +58,45 @@ import org.junit.Test;

public class RepoCommandTest extends RepositoryTestCase {

private Repository remoteDb;
private Repository defaultDb;
private Repository notDefaultDb;
private Repository groupADb;
private Repository groupBDb;

private String rootUri;
private String defaultUri;
private String notDefaultUri;
private String groupAUri;
private String groupBUri;

public void setUp() throws Exception {
super.setUp();

remoteDb = createWorkRepository();
Git git = new Git(remoteDb);
JGitTestUtil.writeTrashFile(remoteDb, "hello.txt", "world");
defaultDb = createWorkRepository();
Git git = new Git(defaultDb);
JGitTestUtil.writeTrashFile(defaultDb, "hello.txt", "world");
git.add().addFilepattern("hello.txt").call();
git.commit().setMessage("Initial commit").call();

notDefaultDb = createWorkRepository();
git = new Git(notDefaultDb);
JGitTestUtil.writeTrashFile(notDefaultDb, "world.txt", "hello");
git.add().addFilepattern("world.txt").call();
git.commit().setMessage("Initial commit").call();

groupADb = createWorkRepository();
git = new Git(groupADb);
JGitTestUtil.writeTrashFile(groupADb, "a.txt", "world");
git.add().addFilepattern("a.txt").call();
git.commit().setMessage("Initial commit").call();

groupBDb = createWorkRepository();
git = new Git(groupBDb);
JGitTestUtil.writeTrashFile(groupBDb, "b.txt", "world");
git.add().addFilepattern("b.txt").call();
git.commit().setMessage("Initial commit").call();

resolveRelativeUris();
}

@Test
@@ -76,12 +106,14 @@ public class RepoCommandTest extends RepositoryTestCase {
.append("<manifest>")
.append("<remote name=\"remote1\" fetch=\".\" />")
.append("<default revision=\"master\" remote=\"remote1\" />")
.append("<project path=\"foo\" name=\".\" />")
.append("<project path=\"foo\" name=\"")
.append(defaultUri)
.append("\" />")
.append("</manifest>");
writeTrashFile("manifest.xml", xmlContent.toString());
RepoCommand command = new RepoCommand(db);
command.setPath(db.getWorkTree().getAbsolutePath() + "/manifest.xml")
.setURI(remoteDb.getDirectory().toURI().toString())
.setURI(rootUri)
.call();
File hello = new File(db.getWorkTree(), "foo/hello.txt");
assertTrue("submodule was checked out", hello.exists());
@@ -90,4 +122,84 @@ public class RepoCommandTest extends RepositoryTestCase {
reader.close();
assertEquals("submodule content is as expected.", "world", content);
}

@Test
public void testRepoManifestGroups() throws Exception {
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\" />")
.append("<project path=\"foo\" name=\"")
.append(defaultUri)
.append("\" groups=\"a,test\" />")
.append("<project path=\"bar\" name=\"")
.append(notDefaultUri)
.append("\" groups=\"notdefault\" />")
.append("<project path=\"a\" name=\"")
.append(groupAUri)
.append("\" groups=\"a\" />")
.append("<project path=\"b\" name=\"")
.append(groupBUri)
.append("\" groups=\"b\" />")
.append("</manifest>");

// default should have foo, a & b
Repository localDb = createWorkRepository();
JGitTestUtil.writeTrashFile(localDb, "manifest.xml", xmlContent.toString());
RepoCommand command = new RepoCommand(localDb);
command.setPath(localDb.getWorkTree().getAbsolutePath() + "/manifest.xml")
.setURI(rootUri)
.call();
File file = new File(localDb.getWorkTree(), "foo/hello.txt");
assertTrue("default has foo", file.exists());
file = new File(localDb.getWorkTree(), "bar/world.txt");
assertFalse("default doesn't have bar", file.exists());
file = new File(localDb.getWorkTree(), "a/a.txt");
assertTrue("default has a", file.exists());
file = new File(localDb.getWorkTree(), "b/b.txt");
assertTrue("default has b", file.exists());

// all,-a should have bar & b
localDb = createWorkRepository();
JGitTestUtil.writeTrashFile(localDb, "manifest.xml", xmlContent.toString());
command = new RepoCommand(localDb);
command.setPath(localDb.getWorkTree().getAbsolutePath() + "/manifest.xml")
.setURI(rootUri)
.setGroups("all,-a")
.call();
file = new File(localDb.getWorkTree(), "foo/hello.txt");
assertFalse("\"all,-a\" doesn't have foo", file.exists());
file = new File(localDb.getWorkTree(), "bar/world.txt");
assertTrue("\"all,-a\" has bar", file.exists());
file = new File(localDb.getWorkTree(), "a/a.txt");
assertFalse("\"all,-a\" doesn't have a", file.exists());
file = new File(localDb.getWorkTree(), "b/b.txt");
assertTrue("\"all,-a\" has have b", file.exists());
}

private void resolveRelativeUris() {
// Find the longest common prefix ends with "/" as rootUri.
defaultUri = defaultDb.getDirectory().toURI().toString();
notDefaultUri = notDefaultDb.getDirectory().toURI().toString();
groupAUri = groupADb.getDirectory().toURI().toString();
groupBUri = groupBDb.getDirectory().toURI().toString();
int start = 0;
while (start <= defaultUri.length()) {
int newStart = defaultUri.indexOf('/', start + 1);
String prefix = defaultUri.substring(0, newStart);
if (!notDefaultUri.startsWith(prefix) ||
!groupAUri.startsWith(prefix) ||
!groupBUri.startsWith(prefix)) {
start++;
rootUri = defaultUri.substring(0, start);
defaultUri = defaultUri.substring(start);
notDefaultUri = notDefaultUri.substring(start);
groupAUri = groupAUri.substring(start);
groupBUri = groupBUri.substring(start);
return;
}
start = newStart;
}
}
}

+ 73
- 14
org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java View File

@@ -48,9 +48,12 @@ import java.net.URI;
import java.net.URISyntaxException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.jgit.api.GitCommand;
import org.eclipse.jgit.api.SubmoduleAddCommand;
@@ -79,18 +82,22 @@ import org.xml.sax.helpers.XMLReaderFactory;
public class RepoCommand extends GitCommand<Void> {

private String path;

private String uri;
private String groups;

private ProgressMonitor monitor;

private static class Project {
final String name;
final String path;
final Set<String> groups;

Project(String name, String path) {
Project(String name, String path, String groups) {
this.name = name;
this.path = path;
this.groups = new HashSet<String>();
if (groups != null && groups.length() > 0)
this.groups.addAll(Arrays.asList(groups.split(","))); //$NON-NLS-1$
}
}

@@ -100,14 +107,29 @@ public class RepoCommand extends GitCommand<Void> {
private final String baseUrl;
private final Map<String, String> remotes;
private final List<Project> projects;
private final Set<String> plusGroups;
private final Set<String> minusGroups;
private String defaultRemote;

XmlManifest(RepoCommand command, String filename, String baseUrl) {
XmlManifest(RepoCommand command, String filename, String baseUrl, String groups) {
this.command = command;
this.filename = filename;
this.baseUrl = baseUrl;
remotes = new HashMap<String, String>();
projects = new ArrayList<Project>();
plusGroups = new HashSet<String>();
minusGroups = new HashSet<String>();
if (groups == null || groups.length() == 0 || groups.equals("default")) { //$NON-NLS-1$
// default means "all,-notdefault"
minusGroups.add("notdefault"); //$NON-NLS-1$
} else {
for (String group : groups.split(",")) { //$NON-NLS-1$
if (group.startsWith("-")) //$NON-NLS-1$
minusGroups.add(group.substring(1));
else
plusGroups.add(group);
}
}
}

void read() throws IOException {
@@ -137,13 +159,17 @@ public class RepoCommand extends GitCommand<Void> {
String localName,
String qName,
Attributes attributes) throws SAXException {
if ("project".equals(qName)) //$NON-NLS-1$
projects.add(new Project(attributes.getValue("name"), attributes.getValue("path"))); //$NON-NLS-1$ //$NON-NLS-2$
else if ("remote".equals(qName)) //$NON-NLS-1$
remotes.put(attributes.getValue("name"), attributes.getValue("fetch")); //$NON-NLS-1$ //$NON-NLS-2$
else if ("default".equals(qName)) //$NON-NLS-1$
if ("project".equals(qName)) { //$NON-NLS-1$
projects.add(new Project( //$NON-NLS-1$
attributes.getValue("name"), //$NON-NLS-1$
attributes.getValue("path"), //$NON-NLS-1$
attributes.getValue("groups"))); //$NON-NLS-1$
} else if ("remote".equals(qName)) { //$NON-NLS-1$
remotes.put(attributes.getValue("name"), //$NON-NLS-1$
attributes.getValue("fetch")); //$NON-NLS-1$
} else if ("default".equals(qName)) { //$NON-NLS-1$
defaultRemote = attributes.getValue("remote"); //$NON-NLS-1$
else if ("copyfile".equals(qName)) { //$NON-NLS-1$
} else if ("copyfile".equals(qName)) { //$NON-NLS-1$
// TODO(fishywang): Handle copyfile. Do nothing for now.
}
}
@@ -162,9 +188,29 @@ public class RepoCommand extends GitCommand<Void> {
throw new SAXException(e);
}
for (Project proj : projects) {
String url = remoteUrl + proj.name;
command.addSubmodule(url, proj.path);
if (inGroups(proj)) {
String url = remoteUrl + proj.name;
command.addSubmodule(url, proj.path);
}
}
}

boolean inGroups(Project proj) {
for (String group : minusGroups) {
if (proj.groups.contains(group)) {
// minus groups have highest priority.
return false;
}
}
if (plusGroups.isEmpty() || plusGroups.contains("all")) { //$NON-NLS-1$
// empty plus groups means "all"
return true;
}
for (String group : plusGroups) {
if (proj.groups.contains(group))
return true;
}
return false;
}
}

@@ -204,6 +250,17 @@ public class RepoCommand extends GitCommand<Void> {
return this;
}

/**
* Set groups to sync
*
* @param groups groups separated by comma, examples: default|all|G1,-G2,-G3
* @return this command
*/
public RepoCommand setGroups(final String groups) {
this.groups = groups;
return this;
}

/**
* The progress monitor associated with the clone operation. By default,
* this is set to <code>NullProgressMonitor</code>
@@ -225,7 +282,7 @@ public class RepoCommand extends GitCommand<Void> {
if (uri == null || uri.length() == 0)
throw new IllegalArgumentException(JGitText.get().uriNotConfigured);

XmlManifest manifest = new XmlManifest(this, path, uri);
XmlManifest manifest = new XmlManifest(this, path, uri, groups);
try {
manifest.read();
} catch (IOException e) {
@@ -236,11 +293,13 @@ public class RepoCommand extends GitCommand<Void> {
}

private void addSubmodule(String url, String name) throws SAXException {
SubmoduleAddCommand add = new SubmoduleAddCommand(repo);
SubmoduleAddCommand add = new SubmoduleAddCommand(repo)
.setPath(name)
.setURI(url);
if (monitor != null)
add.setProgressMonitor(monitor);
try {
add.setPath(name).setURI(url).call();
add.call();
} catch (GitAPIException e) {
throw new SAXException(e);
}

Loading…
Cancel
Save