]> source.dussan.org Git - jgit.git/commitdiff
Add support to <include> tag in repo manifest xml. 50/31150/4
authorYuxuan 'fishy' Wang <fishywang@google.com>
Thu, 7 Aug 2014 05:01:08 +0000 (22:01 -0700)
committerYuxuan 'fishy' Wang <fishywang@google.com>
Wed, 13 Aug 2014 20:04:28 +0000 (13:04 -0700)
Change-Id: I32d468f92e24701ea680435bf3417e3850857303
Signed-off-by: Yuxuan 'fishy' Wang <fishywang@google.com>
org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java
org.eclipse.jgit/resources/org/eclipse/jgit/gitrepo/internal/RepoText.properties
org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java
org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/internal/RepoText.java

index 3e5ef027381aceb0dba8abd61a211978fbc55cdc..41a086f6bebcc5c51620c3a4956ddf037557ae94 100644 (file)
@@ -571,6 +571,46 @@ public class RepoCommandTest extends RepositoryTestCase {
                assertTrue("The a submodule should exist", a);
        }
 
+       @Test
+       public void testIncludeTag() throws Exception {
+               Repository localDb = createWorkRepository();
+               Repository tempDb = createWorkRepository();
+
+               StringBuilder xmlContent = new StringBuilder();
+               xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
+                       .append("<manifest>")
+                       .append("<include name=\"_include.xml\" />")
+                       .append("<default revision=\"master\" remote=\"remote1\" />")
+                       .append("</manifest>");
+               JGitTestUtil.writeTrashFile(
+                               tempDb, "manifest.xml", xmlContent.toString());
+
+               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("\" />")
+                       .append("</manifest>");
+               JGitTestUtil.writeTrashFile(
+                               tempDb, "_include.xml", xmlContent.toString());
+
+               RepoCommand command = new RepoCommand(localDb);
+               command
+                       .setPath(tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml")
+                       .setURI(rootUri)
+                       .call();
+               File hello = new File(localDb.getWorkTree(), "foo/hello.txt");
+               assertTrue("submodule should be checked out", hello.exists());
+               BufferedReader reader = new BufferedReader(new FileReader(hello));
+               String content = reader.readLine();
+               reader.close();
+               assertEquals("submodule content should be as expected",
+                               "master world", content);
+       }
+
        private void resolveRelativeUris() {
                // Find the longest common prefix ends with "/" as rootUri.
                defaultUri = defaultDb.getDirectory().toURI().toString();
index 256dd7f085e0fdb8a211c098cc4033f299d6dc00..7443ad32f03c74ffcadbd1c94be58d0ef6cb3294 100644 (file)
@@ -1,4 +1,6 @@
 copyFileFailed=Error occurred during execution of copyfile rule.
+errorIncludeFile=Error: unable to read include file {0}
+errorIncludeNotImplemented=Error: <include> tag not supported as no callback defined.
 errorNoDefault=Error: no default remote in manifest file.
 errorNoDefaultFilename=Error: no default remote in manifest file {0}.
 errorParsingManifestFile=Error occurred during parsing manifest file.
index 57514a203d6c36a907bdfe4e9b84a5270eac89f2..52710d1d61de5ccceeec30f11807e8e8bfddbd4e 100644 (file)
@@ -123,6 +123,7 @@ public class RepoCommand extends GitCommand<RevCommit> {
        private PersonIdent author;
        private RemoteReader callback;
        private InputStream inputStream;
+       private IncludedFileReader includedReader;
 
        private List<Project> bareProjects;
        private Git git;
@@ -163,6 +164,7 @@ public class RepoCommand extends GitCommand<RevCommit> {
                 * @return the file content.
                 * @throws GitAPIException
                 * @throws IOException
+                * @since 3.5
                 */
                public byte[] readFile(String uri, String ref, String path)
                                throws GitAPIException, IOException;
@@ -224,6 +226,25 @@ public class RepoCommand extends GitCommand<RevCommit> {
                }
        }
 
+       /**
+        * A callback to read included xml files.
+        *
+        * @since 3.5
+        */
+       public interface IncludedFileReader {
+               /**
+                * Read a file from the same base dir of the manifest xml file.
+                *
+                * @param path
+                *            The relative path to the file to read
+                * @return the {@code InputStream} of the file.
+                * @throws GitAPIException
+                * @throws IOException
+                */
+               public InputStream readIncludeFile(String path)
+                               throws GitAPIException, IOException;
+       }
+
        private static class CopyFile {
                final Repository repo;
                final String path;
@@ -309,7 +330,6 @@ public class RepoCommand extends GitCommand<RevCommit> {
 
        private static class XmlManifest extends DefaultHandler {
                private final RepoCommand command;
-               private final InputStream inputStream;
                private final String filename;
                private final String baseUrl;
                private final Map<String, String> remotes;
@@ -318,12 +338,14 @@ public class RepoCommand extends GitCommand<RevCommit> {
                private List<Project> projects;
                private String defaultRemote;
                private String defaultRevision;
+               private IncludedFileReader includedReader;
+               private int xmlInRead;
                private Project currentProject;
 
-               XmlManifest(RepoCommand command, InputStream inputStream,
+               XmlManifest(RepoCommand command, IncludedFileReader includedReader,
                                String filename, String baseUrl, String groups) {
                        this.command = command;
-                       this.inputStream = inputStream;
+                       this.includedReader = includedReader;
                        this.filename = filename;
 
                        // Strip trailing /s to match repo behavior.
@@ -349,7 +371,8 @@ public class RepoCommand extends GitCommand<RevCommit> {
                        }
                }
 
-               void read() throws IOException {
+               void read(InputStream inputStream) throws IOException {
+                       xmlInRead++;
                        final XMLReader xr;
                        try {
                                xr = XMLReaderFactory.createXMLReader();
@@ -395,6 +418,35 @@ public class RepoCommand extends GitCommand<RevCommit> {
                                                        currentProject.path,
                                                        attributes.getValue("src"), //$NON-NLS-1$
                                                        attributes.getValue("dest"))); //$NON-NLS-1$
+                       } else if ("include".equals(qName)) { //$NON_NLS-1$
+                               String name = attributes.getValue("name");
+                               InputStream is = null;
+                               if (includedReader != null) {
+                                       try {
+                                               is = includedReader.readIncludeFile(name);
+                                       } catch (Exception e) {
+                                               throw new SAXException(MessageFormat.format(
+                                                               RepoText.get().errorIncludeFile, name), e);
+                                       }
+                               } else if (filename != null) {
+                                       int index = filename.lastIndexOf('/');
+                                       String path = filename.substring(0, index + 1) + name;
+                                       try {
+                                               is = new FileInputStream(path);
+                                       } catch (IOException e) {
+                                               throw new SAXException(MessageFormat.format(
+                                                               RepoText.get().errorIncludeFile, path), e);
+                                       }
+                               }
+                               if (is == null) {
+                                       throw new SAXException(
+                                                       RepoText.get().errorIncludeNotImplemented);
+                               }
+                               try {
+                                       read(is);
+                               } catch (IOException e) {
+                                       throw new SAXException(e);
+                               }
                        }
                }
 
@@ -411,6 +463,10 @@ public class RepoCommand extends GitCommand<RevCommit> {
 
                @Override
                public void endDocument() throws SAXException {
+                       xmlInRead--;
+                       if (xmlInRead != 0)
+                               return;
+                       // Only do the following after we finished reading everything.
                        if (defaultRemote == null) {
                                if (filename != null)
                                        throw new SAXException(MessageFormat.format(
@@ -606,6 +662,17 @@ public class RepoCommand extends GitCommand<RevCommit> {
                return this;
        }
 
+       /**
+        * Set the IncludedFileReader callback.
+        *
+        * @param reader
+        * @return this command
+        */
+       public RepoCommand setIncludedFileReader(IncludedFileReader reader) {
+               this.includedReader = reader;
+               return this;
+       }
+
        @Override
        public RevCommit call() throws GitAPIException {
                try {
@@ -635,9 +702,9 @@ public class RepoCommand extends GitCommand<RevCommit> {
                                git = new Git(repo);
 
                        XmlManifest manifest = new XmlManifest(
-                                       this, inputStream, path, uri, groups);
+                                       this, includedReader, path, uri, groups);
                        try {
-                               manifest.read();
+                               manifest.read(inputStream);
                        } catch (IOException e) {
                                throw new ManifestErrorException(e);
                        }
index 1f9d5d863addc889a6d606406e04dea239c9c5bd..36b6e3aac4559d910ec12887bcd2ca0165d3489c 100644 (file)
@@ -60,6 +60,8 @@ public class RepoText extends TranslationBundle {
 
        // @formatter:off
        /***/ public String copyFileFailed;
+       /***/ public String errorIncludeFile;
+       /***/ public String errorIncludeNotImplemented;
        /***/ public String errorNoDefault;
        /***/ public String errorNoDefaultFilename;
        /***/ public String errorParsingManifestFile;