Index: gclient.py |
=================================================================== |
--- gclient.py (revision 41071) |
+++ gclient.py (working copy) |
@@ -279,7 +279,33 @@ |
] |
""") |
+DEFAULT_SNAPSHOT_SOLUTION_TEXT = ("""\ |
+ { "name" : "%(solution_name)s", |
+ "url" : "%(solution_url)s", |
+ "custom_deps" : { |
+ %(solution_deps)s, |
+ }, |
+ "safesync_url": "%(safesync_url)s" |
+ }, |
+""") |
+DEFAULT_SNAPSHOT_FILE_TEXT = ("""\ |
+# An element of this array (a "solution") describes a repository directory |
+# that will be checked out into your working copy. Each solution may |
+# optionally define additional dependencies (via its DEPS file) to be |
+# checked out alongside the solution's directory. A solution may also |
+# specify custom dependencies (via the "custom_deps" property) that |
+# override or augment the dependencies specified by the DEPS file. |
+# If a "safesync_url" is specified, it is assumed to reference the location of |
+# a text file which contains nothing but the last known good SCM revision to |
+# sync against. It is fetched if specified and used unless --head is passed |
+ |
+solutions = [ |
+%(solution_list)s |
+] |
+""") |
+ |
+ |
## GClient implementation. |
@@ -801,9 +827,6 @@ |
if not solutions: |
raise gclient_utils.Error("No solution specified") |
- entries = {} |
- entries_deps_content = {} |
- |
# Inner helper to generate base url and rev tuple (including honoring |
# |revision_overrides|) |
def GetURLAndRev(name, original_url): |
@@ -820,13 +843,21 @@ |
else: |
return (url, revision) |
+ # text of the snapshot gclient file |
+ new_gclient = "" |
+ # Dictionary of { path : SCM url } to ensure no duplicate solutions |
+ solution_names = {} |
# Run on the base solutions first. |
for solution in solutions: |
+ # Dictionary of { path : SCM url } to describe the gclient checkout |
+ entries = {} |
+ entries_deps_content = {} |
name = solution["name"] |
- if name in entries: |
+ if name in solution_names: |
raise gclient_utils.Error("solution %s specified more than once" % name) |
(url, rev) = GetURLAndRev(name, solution["url"]) |
entries[name] = "%s@%s" % (url, rev) |
+ solution_names[name] = "%s@%s" % (url, rev) |
deps_file = solution.get("deps_file", self._options.deps_file) |
if '/' in deps_file or '\\' in deps_file: |
raise gclient_utils.Error('deps_file name must not be a path, just a ' |
@@ -840,35 +871,57 @@ |
deps_content = "" |
entries_deps_content[name] = deps_content |
- # Process the dependencies next (sort alphanumerically to ensure that |
- # containing directories get populated first and for readability) |
- deps = self._ParseAllDeps(entries, entries_deps_content) |
- deps_to_process = deps.keys() |
- deps_to_process.sort() |
+ # Process the dependencies next (sort alphanumerically to ensure that |
+ # containing directories get populated first and for readability) |
+ deps = self._ParseAllDeps(entries, entries_deps_content) |
+ deps_to_process = deps.keys() |
+ deps_to_process.sort() |
- # First pass for direct dependencies. |
- for d in deps_to_process: |
- if type(deps[d]) == str: |
- (url, rev) = GetURLAndRev(d, deps[d]) |
- entries[d] = "%s@%s" % (url, rev) |
+ # First pass for direct dependencies. |
+ for d in deps_to_process: |
+ if type(deps[d]) == str: |
+ (url, rev) = GetURLAndRev(d, deps[d]) |
+ entries[d] = "%s@%s" % (url, rev) |
- # Second pass for inherited deps (via the From keyword) |
- for d in deps_to_process: |
- if type(deps[d]) != str: |
- deps_parent_url = entries[deps[d].module_name] |
- if deps_parent_url.find("@") < 0: |
- raise gclient_utils.Error("From %s missing revisioned url" % |
- deps[d].module_name) |
- content = gclient_utils.FileRead(os.path.join(self._root_dir, |
- deps[d].module_name, |
- self._options.deps_file)) |
- sub_deps = self._ParseSolutionDeps(deps[d].module_name, content, {}) |
- (url, rev) = GetURLAndRev(d, sub_deps[d]) |
- entries[d] = "%s@%s" % (url, rev) |
- print(";\n".join(["%s: %s" % (x, entries[x]) |
- for x in sorted(entries.keys())])) |
- |
- |
+ # Second pass for inherited deps (via the From keyword) |
+ for d in deps_to_process: |
+ if type(deps[d]) != str: |
+ deps_parent_url = entries[deps[d].module_name] |
+ if deps_parent_url.find("@") < 0: |
+ raise gclient_utils.Error("From %s missing revisioned url" % |
+ deps[d].module_name) |
+ content = gclient_utils.FileRead(os.path.join( |
+ self._root_dir, |
+ deps[d].module_name, |
+ self._options.deps_file)) |
+ sub_deps = self._ParseSolutionDeps(deps[d].module_name, content, {}) |
+ (url, rev) = GetURLAndRev(d, sub_deps[d]) |
+ entries[d] = "%s@%s" % (url, rev) |
+ |
+ # Build the snapshot configuration string |
+ if self._options.snapshot: |
+ url = entries.pop(name) |
+ custom_deps = ",\n ".join(["\"%s\": \"%s\"" % (x, entries[x]) |
+ for x in sorted(entries.keys())]) |
+ |
+ new_gclient += DEFAULT_SNAPSHOT_SOLUTION_TEXT % { |
+ 'solution_name': name, |
+ 'solution_url': url, |
+ 'safesync_url' : "", |
+ 'solution_deps': custom_deps, |
+ } |
+ else: |
+ print(";\n".join(["%s: %s" % (x, entries[x]) |
+ for x in sorted(entries.keys())])) |
+ |
+ # Print the snapshot configuration file |
+ if self._options.snapshot: |
+ config = DEFAULT_SNAPSHOT_FILE_TEXT % {'solution_list': new_gclient} |
+ snapclient = GClient(self._root_dir, self._options) |
+ snapclient.SetConfig(config) |
+ print(snapclient._config_content) |
+ |
+ |
## gclient commands. |
@@ -1151,6 +1204,12 @@ |
action="store_true", default=False, |
help=("on update, delete any unexpected " |
"unversioned trees that are in the checkout")) |
+ option_parser.add_option("", "--snapshot", action="store_true", default=False, |
+ help=("(revinfo only), create a snapshot file " |
+ "of the current version of all repositories")) |
+ option_parser.add_option("", "--gclientfile", default=None, |
+ metavar="FILENAME", |
+ help=("specify an alternate .gclient file")) |
if len(argv) < 2: |
# Users don't need to be told to use the 'help' command. |
@@ -1177,7 +1236,9 @@ |
# Files used for configuration and state saving. |
options.config_filename = os.environ.get("GCLIENT_FILE", ".gclient") |
- options.entries_filename = ".gclient_entries" |
+ if options.gclientfile: |
+ options.config_filename = options.gclientfile |
+ options.entries_filename = options.config_filename + "_entries" |
options.deps_file = "DEPS" |
options.platform = sys.platform |