Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 # | 2 # |
| 3 # Copyright 2008 Google Inc. All Rights Reserved. | 3 # Copyright 2008 Google Inc. All Rights Reserved. |
| 4 # | 4 # |
| 5 # Licensed under the Apache License, Version 2.0 (the "License"); | 5 # Licensed under the Apache License, Version 2.0 (the "License"); |
| 6 # you may not use this file except in compliance with the License. | 6 # you may not use this file except in compliance with the License. |
| 7 # You may obtain a copy of the License at | 7 # You may obtain a copy of the License at |
| 8 # | 8 # |
| 9 # http://www.apache.org/licenses/LICENSE-2.0 | 9 # http://www.apache.org/licenses/LICENSE-2.0 |
| 10 # | 10 # |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 48 "pattern" The associated value is a string containing a regular | 48 "pattern" The associated value is a string containing a regular |
| 49 expression. When a file whose pathname matches the expression | 49 expression. When a file whose pathname matches the expression |
| 50 is checked out, updated, or reverted, the hook's "action" will | 50 is checked out, updated, or reverted, the hook's "action" will |
| 51 run. | 51 run. |
| 52 "action" A list describing a command to run along with its arguments, if | 52 "action" A list describing a command to run along with its arguments, if |
| 53 any. An action command will run at most one time per gclient | 53 any. An action command will run at most one time per gclient |
| 54 invocation, regardless of how many files matched the pattern. | 54 invocation, regardless of how many files matched the pattern. |
| 55 The action is executed in the same directory as the .gclient | 55 The action is executed in the same directory as the .gclient |
| 56 file. If the first item in the list is the string "python", | 56 file. If the first item in the list is the string "python", |
| 57 the current Python interpreter (sys.executable) will be used | 57 the current Python interpreter (sys.executable) will be used |
| 58 to run the command. | 58 to run the command. If the list contains string "$matching_files" |
| 59 it will be removed from the list and the list will be extended | |
| 60 by the list of matching files. | |
| 59 | 61 |
| 60 Example: | 62 Example: |
| 61 hooks = [ | 63 hooks = [ |
| 62 { "pattern": "\\.(gif|jpe?g|pr0n|png)$", | 64 { "pattern": "\\.(gif|jpe?g|pr0n|png)$", |
| 63 "action": ["python", "image_indexer.py", "--all"]}, | 65 "action": ["python", "image_indexer.py", "--all"]}, |
| 64 ] | 66 ] |
| 65 """ | 67 """ |
| 66 | 68 |
| 67 __author__ = "darinf@gmail.com (Darin Fisher)" | 69 __author__ = "darinf@gmail.com (Darin Fisher)" |
| 68 __version__ = "0.3.2" | 70 __version__ = "0.3.2" |
| (...skipping 783 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 852 "try again." % (url, checkout_path)) | 854 "try again." % (url, checkout_path)) |
| 853 # Ok delete it. | 855 # Ok delete it. |
| 854 print("\n_____ switching %s to a new checkout" % self.relpath) | 856 print("\n_____ switching %s to a new checkout" % self.relpath) |
| 855 RemoveDirectory(checkout_path) | 857 RemoveDirectory(checkout_path) |
| 856 # We need to checkout. | 858 # We need to checkout. |
| 857 command = ['checkout', url, checkout_path] | 859 command = ['checkout', url, checkout_path] |
| 858 if revision: | 860 if revision: |
| 859 command.extend(['--revision', str(revision)]) | 861 command.extend(['--revision', str(revision)]) |
| 860 RunSVNAndGetFileList(command, self._root_dir, file_list) | 862 RunSVNAndGetFileList(command, self._root_dir, file_list) |
| 861 return | 863 return |
| 862 | 864 |
| 863 | 865 |
| 864 # If the provided url has a revision number that matches the revision | 866 # If the provided url has a revision number that matches the revision |
| 865 # number of the existing directory, then we don't need to bother updating. | 867 # number of the existing directory, then we don't need to bother updating. |
| 866 if not options.force and from_info['Revision'] == revision: | 868 if not options.force and from_info['Revision'] == revision: |
| 867 if options.verbose or not forced_revision: | 869 if options.verbose or not forced_revision: |
| 868 print("\n_____ %s%s" % (self.relpath, rev_str)) | 870 print("\n_____ %s%s" % (self.relpath, rev_str)) |
| 869 return | 871 return |
| 870 | 872 |
| 871 command = ["update", checkout_path] | 873 command = ["update", checkout_path] |
| 872 if revision: | 874 if revision: |
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1213 if d in deps and deps[d] != url: | 1215 if d in deps and deps[d] != url: |
| 1214 raise Error( | 1216 raise Error( |
| 1215 "Solutions have conflicting versions of dependency \"%s\"" % d) | 1217 "Solutions have conflicting versions of dependency \"%s\"" % d) |
| 1216 if d in solution_urls and solution_urls[d] != url: | 1218 if d in solution_urls and solution_urls[d] != url: |
| 1217 raise Error( | 1219 raise Error( |
| 1218 "Dependency \"%s\" conflicts with specified solution" % d) | 1220 "Dependency \"%s\" conflicts with specified solution" % d) |
| 1219 # Grab the dependency. | 1221 # Grab the dependency. |
| 1220 deps[d] = url | 1222 deps[d] = url |
| 1221 return deps | 1223 return deps |
| 1222 | 1224 |
| 1223 def _RunHookAction(self, hook_dict): | 1225 def _RunHookAction(self, hook_dict, matching_file_list): |
| 1224 """Runs the action from a single hook. | 1226 """Runs the action from a single hook. |
| 1225 """ | 1227 """ |
| 1226 command = hook_dict['action'][:] | 1228 command = hook_dict['action'][:] |
| 1227 if command[0] == 'python': | 1229 if command[0] == 'python': |
| 1228 # If the hook specified "python" as the first item, the action is a | 1230 # If the hook specified "python" as the first item, the action is a |
| 1229 # Python script. Run it by starting a new copy of the same | 1231 # Python script. Run it by starting a new copy of the same |
| 1230 # interpreter. | 1232 # interpreter. |
| 1231 command[0] = sys.executable | 1233 command[0] = sys.executable |
| 1232 | 1234 |
| 1235 if '$matching_files' in command: | |
| 1236 command.remove('$matching_files') | |
|
Mark Mentovai
2009/07/31 19:12:42
Don't you want to splice matching_file_list into t
| |
| 1237 command.extend(matching_file_list) | |
| 1238 | |
| 1233 # Use a discrete exit status code of 2 to indicate that a hook action | 1239 # Use a discrete exit status code of 2 to indicate that a hook action |
| 1234 # failed. Users of this script may wish to treat hook action failures | 1240 # failed. Users of this script may wish to treat hook action failures |
| 1235 # differently from VC failures. | 1241 # differently from VC failures. |
| 1236 SubprocessCall(command, self._root_dir, fail_status=2) | 1242 SubprocessCall(command, self._root_dir, fail_status=2) |
| 1237 | 1243 |
| 1238 def _RunHooks(self, command, file_list, is_using_git): | 1244 def _RunHooks(self, command, file_list, is_using_git): |
| 1239 """Evaluates all hooks, running actions as needed. | 1245 """Evaluates all hooks, running actions as needed. |
| 1240 """ | 1246 """ |
| 1241 # Hooks only run for these command types. | 1247 # Hooks only run for these command types. |
| 1242 if not command in ('update', 'revert', 'runhooks'): | 1248 if not command in ('update', 'revert', 'runhooks'): |
| 1243 return | 1249 return |
| 1244 | 1250 |
| 1245 # Hooks only run when --nohooks is not specified | 1251 # Hooks only run when --nohooks is not specified |
| 1246 if self._options.nohooks: | 1252 if self._options.nohooks: |
| 1247 return | 1253 return |
| 1248 | 1254 |
| 1249 # Get any hooks from the .gclient file. | 1255 # Get any hooks from the .gclient file. |
| 1250 hooks = self.GetVar("hooks", []) | 1256 hooks = self.GetVar("hooks", []) |
| 1251 # Add any hooks found in DEPS files. | 1257 # Add any hooks found in DEPS files. |
| 1252 hooks.extend(self._deps_hooks) | 1258 hooks.extend(self._deps_hooks) |
| 1253 | 1259 |
| 1254 # If "--force" was specified, run all hooks regardless of what files have | 1260 # If "--force" was specified, run all hooks regardless of what files have |
| 1255 # changed. If the user is using git, then we don't know what files have | 1261 # changed. If the user is using git, then we don't know what files have |
| 1256 # changed so we always run all hooks. | 1262 # changed so we always run all hooks. |
| 1257 if self._options.force or is_using_git: | 1263 if self._options.force or is_using_git: |
| 1258 for hook_dict in hooks: | 1264 for hook_dict in hooks: |
| 1259 self._RunHookAction(hook_dict) | 1265 self._RunHookAction(hook_dict, []) |
| 1260 return | 1266 return |
| 1261 | 1267 |
| 1262 # Run hooks on the basis of whether the files from the gclient operation | 1268 # Run hooks on the basis of whether the files from the gclient operation |
| 1263 # match each hook's pattern. | 1269 # match each hook's pattern. |
| 1264 for hook_dict in hooks: | 1270 for hook_dict in hooks: |
| 1265 pattern = re.compile(hook_dict['pattern']) | 1271 pattern = re.compile(hook_dict['pattern']) |
| 1266 for file in file_list: | 1272 matching_file_list = [file for file in file_list if pattern.search(file)] |
| 1267 if not pattern.search(file): | 1273 if matching_file_list: |
| 1268 continue | 1274 self._RunHookAction(hook_dict, matching_file_list) |
| 1269 | |
| 1270 self._RunHookAction(hook_dict) | |
| 1271 | |
| 1272 # The hook's action only runs once. Don't bother looking for any | |
| 1273 # more matches. | |
| 1274 break | |
| 1275 | 1275 |
| 1276 def RunOnDeps(self, command, args): | 1276 def RunOnDeps(self, command, args): |
| 1277 """Runs a command on each dependency in a client and its dependencies. | 1277 """Runs a command on each dependency in a client and its dependencies. |
| 1278 | 1278 |
| 1279 The module's dependencies are specified in its top-level DEPS files. | 1279 The module's dependencies are specified in its top-level DEPS files. |
| 1280 | 1280 |
| 1281 Args: | 1281 Args: |
| 1282 command: The command to use (e.g., 'status' or 'diff') | 1282 command: The command to use (e.g., 'status' or 'diff') |
| 1283 args: list of str - extra arguments to add to the command line. | 1283 args: list of str - extra arguments to add to the command line. |
| 1284 | 1284 |
| (...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1545 name = base_url.split("/")[-1] | 1545 name = base_url.split("/")[-1] |
| 1546 safesync_url = "" | 1546 safesync_url = "" |
| 1547 if len(args) > 1: | 1547 if len(args) > 1: |
| 1548 safesync_url = args[1] | 1548 safesync_url = args[1] |
| 1549 client.SetDefaultConfig(name, base_url, safesync_url) | 1549 client.SetDefaultConfig(name, base_url, safesync_url) |
| 1550 client.SaveConfig() | 1550 client.SaveConfig() |
| 1551 | 1551 |
| 1552 | 1552 |
| 1553 def DoExport(options, args): | 1553 def DoExport(options, args): |
| 1554 """Handle the export subcommand. | 1554 """Handle the export subcommand. |
| 1555 | 1555 |
| 1556 Raises: | 1556 Raises: |
| 1557 Error: on usage error | 1557 Error: on usage error |
| 1558 """ | 1558 """ |
| 1559 if len(args) != 1: | 1559 if len(args) != 1: |
| 1560 raise Error("Need directory name") | 1560 raise Error("Need directory name") |
| 1561 client = GClient.LoadCurrentConfig(options) | 1561 client = GClient.LoadCurrentConfig(options) |
| 1562 | 1562 |
| 1563 if not client: | 1563 if not client: |
| 1564 raise Error("client not configured; see 'gclient config'") | 1564 raise Error("client not configured; see 'gclient config'") |
| 1565 | 1565 |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1790 | 1790 |
| 1791 if "__main__" == __name__: | 1791 if "__main__" == __name__: |
| 1792 try: | 1792 try: |
| 1793 result = Main(sys.argv) | 1793 result = Main(sys.argv) |
| 1794 except Error, e: | 1794 except Error, e: |
| 1795 print >> sys.stderr, "Error: %s" % str(e) | 1795 print >> sys.stderr, "Error: %s" % str(e) |
| 1796 result = 1 | 1796 result = 1 |
| 1797 sys.exit(result) | 1797 sys.exit(result) |
| 1798 | 1798 |
| 1799 # vim: ts=2:sw=2:tw=80:et: | 1799 # vim: ts=2:sw=2:tw=80:et: |
| OLD | NEW |