Browse Source
Currently the repo sub-command only "works", but the submodules will have .git directories themselves, and lacks group support. Change-Id: I88a6ee07109187c6c9bfd92a044775fcfb5befa6 Signed-off-by: Yuxuan 'fishy' Wang <fishywang@google.com>stable-3.4
Yuxuan 'fishy' Wang
11 years ago
5 changed files with 410 additions and 0 deletions
@ -0,0 +1,93 @@
|
||||
/* |
||||
* Copyright (C) 2014, Google Inc. |
||||
* and other copyright owners as documented in the project's IP log. |
||||
* |
||||
* This program and the accompanying materials are made available |
||||
* under the terms of the Eclipse Distribution License v1.0 which |
||||
* accompanies this distribution, is reproduced below, and is |
||||
* available at http://www.eclipse.org/org/documents/edl-v10.php
|
||||
* |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or |
||||
* without modification, are permitted provided that the following |
||||
* conditions are met: |
||||
* |
||||
* - Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* |
||||
* - Redistributions in binary form must reproduce the above |
||||
* copyright notice, this list of conditions and the following |
||||
* disclaimer in the documentation and/or other materials provided |
||||
* with the distribution. |
||||
* |
||||
* - Neither the name of the Eclipse Foundation, Inc. nor the |
||||
* names of its contributors may be used to endorse or promote |
||||
* products derived from this software without specific prior |
||||
* written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND |
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, |
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
package org.eclipse.jgit.gitrepo; |
||||
|
||||
import static org.junit.Assert.assertEquals; |
||||
import static org.junit.Assert.assertTrue; |
||||
|
||||
import java.io.BufferedReader; |
||||
import java.io.File; |
||||
import java.io.FileReader; |
||||
|
||||
import org.eclipse.jgit.api.Git; |
||||
import org.eclipse.jgit.junit.JGitTestUtil; |
||||
import org.eclipse.jgit.junit.RepositoryTestCase; |
||||
import org.eclipse.jgit.lib.Repository; |
||||
import org.junit.Test; |
||||
|
||||
public class RepoCommandTest extends RepositoryTestCase { |
||||
|
||||
private Repository remoteDb; |
||||
|
||||
public void setUp() throws Exception { |
||||
super.setUp(); |
||||
|
||||
remoteDb = createWorkRepository(); |
||||
Git git = new Git(remoteDb); |
||||
JGitTestUtil.writeTrashFile(remoteDb, "hello.txt", "world"); |
||||
git.add().addFilepattern("hello.txt").call(); |
||||
git.commit().setMessage("Initial commit").call(); |
||||
} |
||||
|
||||
@Test |
||||
public void testAddRepoManifest() 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("</manifest>"); |
||||
writeTrashFile("manifest.xml", xmlContent.toString()); |
||||
RepoCommand command = new RepoCommand(db); |
||||
command.setPath(db.getWorkTree().getAbsolutePath() + "/manifest.xml") |
||||
.setURI(remoteDb.getDirectory().toURI().toString()) |
||||
.call(); |
||||
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); |
||||
} |
||||
} |
@ -0,0 +1,3 @@
|
||||
errorNoDefault=Error: no default remote in file {0}. |
||||
errorParsingManifestFile=Error occurred during parsing manifest file {0}. |
||||
invalidManifest=Invalid manifest. |
@ -0,0 +1,248 @@
|
||||
/* |
||||
* Copyright (C) 2014, Google Inc. |
||||
* and other copyright owners as documented in the project's IP log. |
||||
* |
||||
* This program and the accompanying materials are made available |
||||
* under the terms of the Eclipse Distribution License v1.0 which |
||||
* accompanies this distribution, is reproduced below, and is |
||||
* available at http://www.eclipse.org/org/documents/edl-v10.php
|
||||
* |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or |
||||
* without modification, are permitted provided that the following |
||||
* conditions are met: |
||||
* |
||||
* - Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* |
||||
* - Redistributions in binary form must reproduce the above |
||||
* copyright notice, this list of conditions and the following |
||||
* disclaimer in the documentation and/or other materials provided |
||||
* with the distribution. |
||||
* |
||||
* - Neither the name of the Eclipse Foundation, Inc. nor the |
||||
* names of its contributors may be used to endorse or promote |
||||
* products derived from this software without specific prior |
||||
* written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND |
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, |
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
package org.eclipse.jgit.gitrepo; |
||||
|
||||
import java.io.FileInputStream; |
||||
import java.io.IOException; |
||||
import java.net.URI; |
||||
import java.net.URISyntaxException; |
||||
import java.text.MessageFormat; |
||||
import java.util.ArrayList; |
||||
import java.util.HashMap; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
import org.eclipse.jgit.api.GitCommand; |
||||
import org.eclipse.jgit.api.SubmoduleAddCommand; |
||||
import org.eclipse.jgit.api.errors.GitAPIException; |
||||
import org.eclipse.jgit.gitrepo.internal.RepoText; |
||||
import org.eclipse.jgit.internal.JGitText; |
||||
import org.eclipse.jgit.lib.ProgressMonitor; |
||||
import org.eclipse.jgit.lib.Repository; |
||||
|
||||
import org.xml.sax.Attributes; |
||||
import org.xml.sax.InputSource; |
||||
import org.xml.sax.SAXException; |
||||
import org.xml.sax.XMLReader; |
||||
import org.xml.sax.helpers.DefaultHandler; |
||||
import org.xml.sax.helpers.XMLReaderFactory; |
||||
|
||||
/** |
||||
* A class used to execute a repo command. |
||||
* |
||||
* This will parse a repo XML manifest, convert it into .gitmodules file and the |
||||
* repository config file. |
||||
* |
||||
* @see <a href="https://code.google.com/p/git-repo/">git-repo project page</a> |
||||
* @since 3.4 |
||||
*/ |
||||
public class RepoCommand extends GitCommand<Void> { |
||||
|
||||
private String path; |
||||
|
||||
private String uri; |
||||
|
||||
private ProgressMonitor monitor; |
||||
|
||||
private static class Project { |
||||
final String name; |
||||
final String path; |
||||
|
||||
Project(String name, String path) { |
||||
this.name = name; |
||||
this.path = path; |
||||
} |
||||
} |
||||
|
||||
private static class XmlManifest extends DefaultHandler { |
||||
private final RepoCommand command; |
||||
private final String filename; |
||||
private final String baseUrl; |
||||
private final Map<String, String> remotes; |
||||
private final List<Project> projects; |
||||
private String defaultRemote; |
||||
|
||||
XmlManifest(RepoCommand command, String filename, String baseUrl) { |
||||
this.command = command; |
||||
this.filename = filename; |
||||
this.baseUrl = baseUrl; |
||||
remotes = new HashMap<String, String>(); |
||||
projects = new ArrayList<Project>(); |
||||
} |
||||
|
||||
void read() throws IOException { |
||||
final XMLReader xr; |
||||
try { |
||||
xr = XMLReaderFactory.createXMLReader(); |
||||
} catch (SAXException e) { |
||||
throw new IOException(JGitText.get().noXMLParserAvailable); |
||||
} |
||||
xr.setContentHandler(this); |
||||
final FileInputStream in = new FileInputStream(filename); |
||||
try { |
||||
xr.parse(new InputSource(in)); |
||||
} catch (SAXException e) { |
||||
IOException error = new IOException(MessageFormat.format( |
||||
RepoText.get().errorParsingManifestFile, filename)); |
||||
error.initCause(e); |
||||
throw error; |
||||
} finally { |
||||
in.close(); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void startElement( |
||||
String uri, |
||||
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$
|
||||
defaultRemote = attributes.getValue("remote"); //$NON-NLS-1$
|
||||
else if ("copyfile".equals(qName)) { //$NON-NLS-1$
|
||||
// TODO(fishywang): Handle copyfile. Do nothing for now.
|
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void endDocument() throws SAXException { |
||||
if (defaultRemote == null) { |
||||
throw new SAXException(MessageFormat.format( |
||||
RepoText.get().errorNoDefault, filename)); |
||||
} |
||||
final String remoteUrl; |
||||
try { |
||||
URI uri = new URI(String.format("%s/%s/", baseUrl, remotes.get(defaultRemote))); //$NON-NLS-1$
|
||||
remoteUrl = uri.normalize().toString(); |
||||
} catch (URISyntaxException e) { |
||||
throw new SAXException(e); |
||||
} |
||||
for (Project proj : projects) { |
||||
String url = remoteUrl + proj.name; |
||||
command.addSubmodule(url, proj.path); |
||||
} |
||||
} |
||||
} |
||||
|
||||
private static class ManifestErrorException extends GitAPIException { |
||||
ManifestErrorException(Throwable cause) { |
||||
super(RepoText.get().invalidManifest, cause); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* @param repo |
||||
*/ |
||||
public RepoCommand(final Repository repo) { |
||||
super(repo); |
||||
} |
||||
|
||||
/** |
||||
* Set path to the manifest XML file |
||||
* |
||||
* @param path |
||||
* (with <code>/</code> as separator) |
||||
* @return this command |
||||
*/ |
||||
public RepoCommand setPath(final String path) { |
||||
this.path = path; |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* Set base URI of the pathes inside the XML |
||||
* |
||||
* @param uri |
||||
* @return this command |
||||
*/ |
||||
public RepoCommand setURI(final String uri) { |
||||
this.uri = uri; |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* The progress monitor associated with the clone operation. By default, |
||||
* this is set to <code>NullProgressMonitor</code> |
||||
* |
||||
* @see org.eclipse.jgit.lib.NullProgressMonitor |
||||
* @param monitor |
||||
* @return this command |
||||
*/ |
||||
public RepoCommand setProgressMonitor(final ProgressMonitor monitor) { |
||||
this.monitor = monitor; |
||||
return this; |
||||
} |
||||
|
||||
@Override |
||||
public Void call() throws GitAPIException { |
||||
checkCallable(); |
||||
if (path == null || path.length() == 0) |
||||
throw new IllegalArgumentException(JGitText.get().pathNotConfigured); |
||||
if (uri == null || uri.length() == 0) |
||||
throw new IllegalArgumentException(JGitText.get().uriNotConfigured); |
||||
|
||||
XmlManifest manifest = new XmlManifest(this, path, uri); |
||||
try { |
||||
manifest.read(); |
||||
} catch (IOException e) { |
||||
throw new ManifestErrorException(e); |
||||
} |
||||
|
||||
return null; |
||||
} |
||||
|
||||
private void addSubmodule(String url, String name) throws SAXException { |
||||
SubmoduleAddCommand add = new SubmoduleAddCommand(repo); |
||||
if (monitor != null) |
||||
add.setProgressMonitor(monitor); |
||||
try { |
||||
add.setPath(name).setURI(url).call(); |
||||
} catch (GitAPIException e) { |
||||
throw new SAXException(e); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,65 @@
|
||||
/* |
||||
* Copyright (C) 2014, Google Inc. |
||||
* and other copyright owners as documented in the project's IP log. |
||||
* |
||||
* This program and the accompanying materials are made available |
||||
* under the terms of the Eclipse Distribution License v1.0 which |
||||
* accompanies this distribution, is reproduced below, and is |
||||
* available at http://www.eclipse.org/org/documents/edl-v10.php
|
||||
* |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or |
||||
* without modification, are permitted provided that the following |
||||
* conditions are met: |
||||
* |
||||
* - Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* |
||||
* - Redistributions in binary form must reproduce the above |
||||
* copyright notice, this list of conditions and the following |
||||
* disclaimer in the documentation and/or other materials provided |
||||
* with the distribution. |
||||
* |
||||
* - Neither the name of the Eclipse Foundation, Inc. nor the |
||||
* names of its contributors may be used to endorse or promote |
||||
* products derived from this software without specific prior |
||||
* written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND |
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, |
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
|
||||
package org.eclipse.jgit.gitrepo.internal; |
||||
|
||||
import org.eclipse.jgit.nls.NLS; |
||||
import org.eclipse.jgit.nls.TranslationBundle; |
||||
|
||||
/** |
||||
* Translation bundle for repo command |
||||
*/ |
||||
public class RepoText extends TranslationBundle { |
||||
|
||||
/** |
||||
* @return an instance of this translation bundle |
||||
*/ |
||||
public static RepoText get() { |
||||
return NLS.getBundleFor(RepoText.class); |
||||
} |
||||
|
||||
// @formatter:off
|
||||
/***/ public String errorNoDefault; |
||||
/***/ public String errorParsingManifestFile; |
||||
/***/ public String invalidManifest; |
||||
} |
Loading…
Reference in new issue