diff --git a/.gitignore b/.gitignore
index 17874aa0..b2ef4c4a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -27,6 +27,7 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# Ignore other VCSs.
+.repo/
.svn/
# Ignore common compiled artifacts.
diff --git a/DEPS b/DEPS
index 2de510a5..0a06f1bb 100644
--- a/DEPS
+++ b/DEPS
@@ -72,4 +72,9 @@ hooks = [
"--no-circular-check",
"src/src/client/windows/breakpad_client.gyp"],
},
+ {
+ # Keep the manifest up to date.
+ "action": ["python", "src/src/tools/python/deps-to-manifest.py",
+ "src/DEPS", "src/default.xml"],
+ },
]
diff --git a/default.xml b/default.xml
new file mode 100644
index 00000000..77aea228
--- /dev/null
+++ b/default.xml
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/tools/python/deps-to-manifest.py b/src/tools/python/deps-to-manifest.py
new file mode 100755
index 00000000..b4562854
--- /dev/null
+++ b/src/tools/python/deps-to-manifest.py
@@ -0,0 +1,167 @@
+#!/usr/bin/python
+# Copyright 2016 Google Inc.
+# 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 Google 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.
+
+"""Convert gclient's DEPS file to repo's manifest xml file."""
+
+from __future__ import print_function
+
+import argparse
+import os
+import sys
+
+
+REMOTES = {
+ 'chromium': 'https://chromium.googlesource.com/',
+ 'github': 'https://github.com/',
+}
+REVIEWS = {
+ 'chromium': 'https://chromium-review.googlesource.com',
+}
+
+MANIFEST_HEAD = """
+
+
+
+
+"""
+
+MANIFEST_REMOTE = """
+
+"""
+
+MANIFEST_PROJECT = """
+
+"""
+
+MANIFEST_TAIL = """
+
+"""
+
+
+def ConvertDepsToManifest(deps, manifest):
+ """Convert the |deps| file to the |manifest|."""
+ # Load the DEPS file data.
+ ctx = {}
+ execfile(deps, ctx)
+
+ new_contents = ''
+
+ # Write out the common header.
+ data = {
+ 'prog': os.path.basename(__file__),
+ }
+ new_contents += MANIFEST_HEAD % data
+
+ # Write out the sections.
+ for name, fetch in REMOTES.items():
+ data = {
+ 'name': name,
+ 'fetch': fetch,
+ 'review': REVIEWS.get(name, ''),
+ }
+ new_contents += MANIFEST_REMOTE % data
+
+ # Write out the main repo itself.
+ data = {
+ 'path': 'src',
+ 'name': 'breakpad/breakpad',
+ 'revision': 'refs/heads/master',
+ 'remote': 'chromium',
+ }
+ new_contents += MANIFEST_PROJECT % data
+
+ # Write out the sections.
+ for path, url in ctx['deps'].items():
+ for name, fetch in REMOTES.items():
+ if url.startswith(fetch):
+ remote = name
+ break
+ else:
+ raise ValueError('Unknown DEPS remote: %s: %s' % (path, url))
+
+ # The DEPS url will look like:
+ # https://chromium.googlesource.com/external/gyp/@e8ab0833a42691cd2
+ remote_path, rev = url.split('@')
+ remote_path = remote_path[len(fetch):]
+
+ # If it's not a revision, assume it's a tag. Repo wants full ref names.
+ if len(rev) != 40:
+ rev = 'refs/tags/%s' % rev
+
+ data = {
+ 'path': path,
+ 'name': remote_path,
+ 'revision': rev,
+ 'remote': remote,
+ }
+ new_contents += MANIFEST_PROJECT % data
+
+ # Write out the common footer.
+ new_contents += MANIFEST_TAIL
+
+ # See if the manifest has actually changed contents to avoid thrashing.
+ try:
+ old_contents = open(manifest).read()
+ except IOError:
+ # In case the file doesn't exist yet.
+ old_contents = ''
+ if old_contents != new_contents:
+ print('Updating %s due to changed %s' % (manifest, deps))
+ with open(manifest, 'w') as fp:
+ fp.write(new_contents)
+
+
+def GetParser():
+ """Return a CLI parser."""
+ parser = argparse.ArgumentParser(description=__doc__)
+ parser.add_argument('deps',
+ help='The DEPS file to convert')
+ parser.add_argument('manifest',
+ help='The manifest xml to generate')
+ return parser
+
+
+def main(argv):
+ """The main func!"""
+ parser = GetParser()
+ opts = parser.parse_args(argv)
+ ConvertDepsToManifest(opts.deps, opts.manifest)
+
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv[1:]))