Add support for multiple local manifests

Add support for multiple local manifests stored in the local_manifests
folder under the .repo home directory.

Local manifests will be processed in addition to local_manifest.xml.

Change-Id: Ia0569cea7e9ae0fe3208a8ffef5d9679e14db03b
diff --git a/docs/manifest-format.txt b/docs/manifest-format.txt
index f499868..c51b84b 100644
--- a/docs/manifest-format.txt
+++ b/docs/manifest-format.txt
@@ -224,15 +224,19 @@
 the manifest repositories root.
 
 
-Local Manifest
-==============
+Local Manifests
+===============
 
-Additional remotes and projects may be added through a local
-manifest, stored in `$TOP_DIR/.repo/local_manifest.xml`.
+Additional remotes and projects may be added through local manifest
+files stored in `$TOP_DIR/.repo/local_manifests/*.xml`.
 
 For example:
 
-  $ cat .repo/local_manifest.xml
+  $ ls .repo/local_manifests
+  local_manifest.xml
+  another_local_manifest.xml
+
+  $ cat .repo/local_manifests/local_manifest.xml
   <?xml version="1.0" encoding="UTF-8"?>
   <manifest>
     <project path="manifest"
@@ -241,6 +245,9 @@
              name="platform/manifest" />
   </manifest>
 
-Users may add projects to the local manifest prior to a `repo sync`
+Users may add projects to the local manifest(s) prior to a `repo sync`
 invocation, instructing repo to automatically download and manage
 these extra projects.
+
+Additional remotes and projects may also be added through a local
+manifest, stored in `$TOP_DIR/.repo/local_manifest.xml`.
diff --git a/manifest_xml.py b/manifest_xml.py
index bf981f0..4e47679 100644
--- a/manifest_xml.py
+++ b/manifest_xml.py
@@ -27,6 +27,7 @@
 
 MANIFEST_FILE_NAME = 'manifest.xml'
 LOCAL_MANIFEST_NAME = 'local_manifest.xml'
+LOCAL_MANIFESTS_DIR_NAME = 'local_manifests'
 
 urlparse.uses_relative.extend(['ssh', 'git'])
 urlparse.uses_netloc.extend(['ssh', 'git'])
@@ -301,6 +302,17 @@
       if os.path.exists(local):
         nodes.append(self._ParseManifestXml(local, self.repodir))
 
+      local_dir = os.path.abspath(os.path.join(self.repodir, LOCAL_MANIFESTS_DIR_NAME))
+      try:
+        for local_file in os.listdir(local_dir):
+          if local_file.endswith('.xml'):
+            try:
+              nodes.append(self._ParseManifestXml(local_file, self.repodir))
+            except ManifestParseError as e:
+              print >>sys.stderr, '%s' % str(e)
+      except OSError:
+        pass
+
       self._ParseManifest(nodes)
 
       if self.IsMirror:
@@ -312,7 +324,7 @@
   def _ParseManifestXml(self, path, include_root):
     try:
       root = xml.dom.minidom.parse(path)
-    except (OSError, xml.parsers.expat.ExpatError), e:
+    except (OSError, xml.parsers.expat.ExpatError) as e:
       raise ManifestParseError("error parsing manifest %s: %s" % (path, e))
 
     if not root or not root.childNodes: