| OLD | NEW | 
|     1 #!/usr/bin/python |     1 #!/usr/bin/python | 
|     2 # Copyright (c) 2010 The Chromium Authors. All rights reserved. |     2 # Copyright (c) 2010 The Chromium Authors. All rights reserved. | 
|     3 # Use of this source code is governed by a BSD-style license that can be |     3 # Use of this source code is governed by a BSD-style license that can be | 
|     4 # found in the LICENSE file. |     4 # found in the LICENSE file. | 
|     5  |     5  | 
|     6 """A wrapper script to manage a set of client modules in different SCM. |     6 """A wrapper script to manage a set of client modules in different SCM. | 
|     7  |     7  | 
|     8 This script is intended to be used to help basic management of client |     8 This script is intended to be used to help basic management of client | 
|     9 program sources residing in one or more Subversion modules and Git |     9 program sources residing in one or more Subversion modules and Git | 
|    10 repositories, along with other modules it depends on, also in Subversion or Git, |    10 repositories, along with other modules it depends on, also in Subversion or Git, | 
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|    48                it will be removed from the list and the list will be extended |    48                it will be removed from the list and the list will be extended | 
|    49                by the list of matching files. |    49                by the list of matching files. | 
|    50  |    50  | 
|    51   Example: |    51   Example: | 
|    52     hooks = [ |    52     hooks = [ | 
|    53       { "pattern": "\\.(gif|jpe?g|pr0n|png)$", |    53       { "pattern": "\\.(gif|jpe?g|pr0n|png)$", | 
|    54         "action":  ["python", "image_indexer.py", "--all"]}, |    54         "action":  ["python", "image_indexer.py", "--all"]}, | 
|    55     ] |    55     ] | 
|    56 """ |    56 """ | 
|    57  |    57  | 
|    58 __version__ = "0.3.7" |    58 __version__ = "0.4" | 
|    59  |    59  | 
|    60 import errno |    60 import errno | 
|    61 import logging |    61 import logging | 
|    62 import optparse |    62 import optparse | 
|    63 import os |    63 import os | 
|    64 import pprint |    64 import pprint | 
|    65 import re |    65 import re | 
|    66 import sys |    66 import sys | 
|    67 import urlparse |    67 import urlparse | 
|    68 import urllib |    68 import urllib | 
|    69  |    69  | 
|    70 import breakpad |    70 import breakpad | 
|    71  |    71  | 
|    72 import gclient_scm |    72 import gclient_scm | 
|    73 import gclient_utils |    73 import gclient_utils | 
|    74 from third_party.repo.progress import Progress |    74 from third_party.repo.progress import Progress | 
|    75  |    75  | 
|    76 # default help text |  | 
|    77 DEFAULT_USAGE_TEXT = ( |  | 
|    78 """%prog <subcommand> [options] [--] [SCM options/args...] |  | 
|    79 a wrapper for managing a set of svn client modules and/or git repositories. |  | 
|    80 Version """ + __version__ + """ |  | 
|    81  |  | 
|    82 Options and extra arguments can be passed to invoked SCM commands by |  | 
|    83 appending them to the command line.  Note that if the first such |  | 
|    84 appended option starts with a dash (-) then the options must be |  | 
|    85 preceded by -- to distinguish them from gclient options. |  | 
|    86  |  | 
|    87 For additional help on a subcommand or examples of usage, try |  | 
|    88    %prog help <subcommand> |  | 
|    89    %prog help files |  | 
|    90 """) |  | 
|    91  |  | 
|    92  |    76  | 
|    93 def attr(attr, data): |    77 def attr(attr, data): | 
|    94   """Sets an attribute on a function.""" |    78   """Sets an attribute on a function.""" | 
|    95   def hook(fn): |    79   def hook(fn): | 
|    96     setattr(fn, attr, data) |    80     setattr(fn, attr, data) | 
|    97     return fn |    81     return fn | 
|    98   return hook |    82   return hook | 
|    99  |    83  | 
|   100  |    84  | 
|   101 ## GClient implementation. |    85 ## GClient implementation. | 
| (...skipping 704 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   806                        for x in sorted(entries.keys())])) |   790                        for x in sorted(entries.keys())])) | 
|   807  |   791  | 
|   808     # Print the snapshot configuration file |   792     # Print the snapshot configuration file | 
|   809     if self._options.snapshot: |   793     if self._options.snapshot: | 
|   810       config = self.DEFAULT_SNAPSHOT_FILE_TEXT % {'solution_list': new_gclient} |   794       config = self.DEFAULT_SNAPSHOT_FILE_TEXT % {'solution_list': new_gclient} | 
|   811       snapclient = GClient(self._root_dir, self._options) |   795       snapclient = GClient(self._root_dir, self._options) | 
|   812       snapclient.SetConfig(config) |   796       snapclient.SetConfig(config) | 
|   813       print(snapclient._config_content) |   797       print(snapclient._config_content) | 
|   814  |   798  | 
|   815  |   799  | 
|   816 ## gclient commands. |   800 #### gclient commands. | 
|   817  |   801  | 
|   818  |   802  | 
|   819 def CMDcleanup(parser, options, args): |   803 def CMDcleanup(parser, args): | 
|   820   """Clean up all working copies, using 'svn cleanup' for each module. |   804   """Cleans up all working copies. | 
|   821  |   805  | 
|   822 Additional options and args may be passed to 'svn cleanup'. |   806 Mostly svn-specific. Simply runs 'svn cleanup' for each module. | 
|   823  |  | 
|   824 usage: cleanup [options] [--] [svn cleanup args/options] |  | 
|   825  |  | 
|   826 Valid options: |  | 
|   827   --verbose           : output additional diagnostics |  | 
|   828 """ |   807 """ | 
 |   808   (options, args) = parser.parse_args(args) | 
|   829   client = GClient.LoadCurrentConfig(options) |   809   client = GClient.LoadCurrentConfig(options) | 
|   830   if not client: |   810   if not client: | 
|   831     raise gclient_utils.Error("client not configured; see 'gclient config'") |   811     raise gclient_utils.Error("client not configured; see 'gclient config'") | 
|   832   if options.verbose: |   812   if options.verbose: | 
|   833     # Print out the .gclient file.  This is longer than if we just printed the |   813     # Print out the .gclient file.  This is longer than if we just printed the | 
|   834     # client dict, but more legible, and it might contain helpful comments. |   814     # client dict, but more legible, and it might contain helpful comments. | 
|   835     print(client.ConfigContent()) |   815     print(client.ConfigContent()) | 
|   836   return client.RunOnDeps('cleanup', args) |   816   return client.RunOnDeps('cleanup', args) | 
|   837  |   817  | 
|   838  |   818  | 
|   839 def CMDconfig(parser, options, args): |   819 @attr('usage', '[url] [safesync url]') | 
 |   820 def CMDconfig(parser, args): | 
|   840   """Create a .gclient file in the current directory. |   821   """Create a .gclient file in the current directory. | 
|   841  |   822  | 
|   842 This specifies the configuration for further commands.  After update/sync, |   823 This specifies the configuration for further commands. After update/sync, | 
|   843 top-level DEPS files in each module are read to determine dependent |   824 top-level DEPS files in each module are read to determine dependent | 
|   844 modules to operate on as well.  If optional [url] parameter is |   825 modules to operate on as well. If optional [url] parameter is | 
|   845 provided, then configuration is read from a specified Subversion server |   826 provided, then configuration is read from a specified Subversion server | 
|   846 URL.  Otherwise, a --spec option must be provided.  A --name option overrides |   827 URL. | 
|   847 the default name for the solutions. |  | 
|   848  |  | 
|   849 usage: config [option | url] [safesync url] |  | 
|   850  |  | 
|   851 Valid options: |  | 
|   852   --name path           : alternate relative path for the solution |  | 
|   853   --spec=GCLIENT_SPEC   : contents of .gclient are read from string parameter. |  | 
|   854                           *Note that due to Cygwin/Python brokenness, it |  | 
|   855                           probably can't contain any newlines.* |  | 
|   856  |  | 
|   857 Examples: |  | 
|   858   gclient config https://gclient.googlecode.com/svn/trunk/gclient |  | 
|   859       configure a new client to check out gclient.py tool sources |  | 
|   860   gclient config --name tools https://gclient.googlecode.com/svn/trunk/gclient |  | 
|   861   gclient config --spec='solutions=[{"name":"gclient", |  | 
|   862     '"url":"https://gclient.googlecode.com/svn/trunk/gclient",' |  | 
|   863     '"custom_deps":{}}]' |  | 
|   864 """ |   828 """ | 
 |   829   parser.add_option("--spec", | 
 |   830                     help="create a gclient file containing the provided " | 
 |   831                          "string. Due to Cygwin/Python brokenness, it " | 
 |   832                          "probably can't contain any newlines.") | 
 |   833   parser.add_option("--name", | 
 |   834                     help="overrides the default name for the solution") | 
 |   835   (options, args) = parser.parse_args(args) | 
|   865   if len(args) < 1 and not options.spec: |   836   if len(args) < 1 and not options.spec: | 
|   866     raise gclient_utils.Error("required argument missing; see 'gclient help " |   837     raise gclient_utils.Error("required argument missing; see 'gclient help " | 
|   867                               "config'") |   838                               "config'") | 
|   868   if os.path.exists(options.config_filename): |   839   if os.path.exists(options.config_filename): | 
|   869     raise gclient_utils.Error("%s file already exists in the current directory" |   840     raise gclient_utils.Error("%s file already exists in the current directory" | 
|   870                                   % options.config_filename) |   841                                   % options.config_filename) | 
|   871   client = GClient('.', options) |   842   client = GClient('.', options) | 
|   872   if options.spec: |   843   if options.spec: | 
|   873     client.SetConfig(options.spec) |   844     client.SetConfig(options.spec) | 
|   874   else: |   845   else: | 
|   875     base_url = args[0].rstrip('/') |   846     base_url = args[0].rstrip('/') | 
|   876     if not options.name: |   847     if not options.name: | 
|   877       name = base_url.split("/")[-1] |   848       name = base_url.split("/")[-1] | 
|   878     else: |   849     else: | 
|   879       # specify an alternate relpath for the given URL. |   850       # specify an alternate relpath for the given URL. | 
|   880       name = options.name |   851       name = options.name | 
|   881     safesync_url = "" |   852     safesync_url = "" | 
|   882     if len(args) > 1: |   853     if len(args) > 1: | 
|   883       safesync_url = args[1] |   854       safesync_url = args[1] | 
|   884     client.SetDefaultConfig(name, base_url, safesync_url) |   855     client.SetDefaultConfig(name, base_url, safesync_url) | 
|   885   client.SaveConfig() |   856   client.SaveConfig() | 
|   886   return 0 |   857   return 0 | 
|   887  |   858  | 
|   888  |   859  | 
|   889 def CMDexport(parser, options, args): |   860 def CMDexport(parser, args): | 
|   890   """Wrapper for svn export for all managed directories.""" |   861   """Wrapper for svn export for all managed directories.""" | 
 |   862   (options, args) = parser.parse_args(args) | 
|   891   if len(args) != 1: |   863   if len(args) != 1: | 
|   892     raise gclient_utils.Error("Need directory name") |   864     raise gclient_utils.Error("Need directory name") | 
|   893   client = GClient.LoadCurrentConfig(options) |   865   client = GClient.LoadCurrentConfig(options) | 
|   894  |   866  | 
|   895   if not client: |   867   if not client: | 
|   896     raise gclient_utils.Error("client not configured; see 'gclient config'") |   868     raise gclient_utils.Error("client not configured; see 'gclient config'") | 
|   897  |   869  | 
|   898   if options.verbose: |   870   if options.verbose: | 
|   899     # Print out the .gclient file.  This is longer than if we just printed the |   871     # Print out the .gclient file.  This is longer than if we just printed the | 
|   900     # client dict, but more legible, and it might contain helpful comments. |   872     # client dict, but more legible, and it might contain helpful comments. | 
|   901     print(client.ConfigContent()) |   873     print(client.ConfigContent()) | 
|   902   return client.RunOnDeps('export', args) |   874   return client.RunOnDeps('export', args) | 
|   903  |   875  | 
|   904  |   876  | 
|   905 def CMDpack(parser, options, args): |   877 @attr('epilog', """Example: | 
 |   878   gclient pack > patch.txt | 
 |   879     generate simple patch for configured client and dependences | 
 |   880 """) | 
 |   881 def CMDpack(parser, args): | 
|   906   """Generate a patch which can be applied at the root of the tree. |   882   """Generate a patch which can be applied at the root of the tree. | 
|   907  |   883  | 
|   908 Internally, runs 'svn diff' on each checked out module and |   884 Internally, runs 'svn diff'/'git diff' on each checked out module and | 
|   909 dependencies, and performs minimal postprocessing of the output. The |   885 dependencies, and performs minimal postprocessing of the output. The | 
|   910 resulting patch is printed to stdout and can be applied to a freshly |   886 resulting patch is printed to stdout and can be applied to a freshly | 
|   911 checked out tree via 'patch -p0 < patchfile'. Additional args and |   887 checked out tree via 'patch -p0 < patchfile'. | 
|   912 options to 'svn diff' can be passed after gclient options. |  | 
|   913  |  | 
|   914 usage: pack [options] [--] [svn args/options] |  | 
|   915  |  | 
|   916 Valid options: |  | 
|   917   --verbose            : output additional diagnostics |  | 
|   918  |  | 
|   919 Examples: |  | 
|   920   gclient pack > patch.txt |  | 
|   921       generate simple patch for configured client and dependences |  | 
|   922   gclient pack -- -x -b > patch.txt |  | 
|   923       generate patch using 'svn diff -x -b' to suppress |  | 
|   924       whitespace-only differences |  | 
|   925   gclient pack -- -r HEAD -x -b > patch.txt |  | 
|   926       generate patch, diffing each file versus the latest version of |  | 
|   927       each module |  | 
|   928 """ |   888 """ | 
 |   889   (options, args) = parser.parse_args(args) | 
|   929   client = GClient.LoadCurrentConfig(options) |   890   client = GClient.LoadCurrentConfig(options) | 
|   930   if not client: |   891   if not client: | 
|   931     raise gclient_utils.Error("client not configured; see 'gclient config'") |   892     raise gclient_utils.Error("client not configured; see 'gclient config'") | 
|   932   if options.verbose: |   893   if options.verbose: | 
|   933     # Print out the .gclient file.  This is longer than if we just printed the |   894     # Print out the .gclient file.  This is longer than if we just printed the | 
|   934     # client dict, but more legible, and it might contain helpful comments. |   895     # client dict, but more legible, and it might contain helpful comments. | 
|   935     print(client.ConfigContent()) |   896     print(client.ConfigContent()) | 
|   936   return client.RunOnDeps('pack', args) |   897   return client.RunOnDeps('pack', args) | 
|   937  |   898  | 
|   938  |   899  | 
|   939 def CMDstatus(parser, options, args): |   900 def CMDstatus(parser, args): | 
|   940   """Show the modification status of for every dependencies. |   901   """Show modification status for every dependencies.""" | 
|   941  |   902   (options, args) = parser.parse_args(args) | 
|   942 Additional options and args may be passed to 'svn status'. |  | 
|   943  |  | 
|   944 usage: status [options] [--] [svn diff args/options] |  | 
|   945  |  | 
|   946 Valid options: |  | 
|   947   --verbose           : output additional diagnostics |  | 
|   948   --nohooks           : don't run the hooks after the update is complete |  | 
|   949 """ |  | 
|   950   client = GClient.LoadCurrentConfig(options) |   903   client = GClient.LoadCurrentConfig(options) | 
|   951   if not client: |   904   if not client: | 
|   952     raise gclient_utils.Error("client not configured; see 'gclient config'") |   905     raise gclient_utils.Error("client not configured; see 'gclient config'") | 
|   953   if options.verbose: |   906   if options.verbose: | 
|   954     # Print out the .gclient file.  This is longer than if we just printed the |   907     # Print out the .gclient file.  This is longer than if we just printed the | 
|   955     # client dict, but more legible, and it might contain helpful comments. |   908     # client dict, but more legible, and it might contain helpful comments. | 
|   956     print(client.ConfigContent()) |   909     print(client.ConfigContent()) | 
|   957   return client.RunOnDeps('status', args) |   910   return client.RunOnDeps('status', args) | 
|   958  |   911  | 
|   959  |   912  | 
|   960 def CMDsync(parser, options, args): |   913 @attr('epilog', """Examples: | 
|   961   """Checkout/update the modules specified by the gclient configuration. |  | 
|   962  |  | 
|   963 Unless --revision is specified, then the latest revision of the root solutions |  | 
|   964 is checked out, with dependent submodule versions updated according to DEPS |  | 
|   965 files. If --revision is specified, then the given revision is used in place |  | 
|   966 of the latest, either for a single solution or for all solutions. |  | 
|   967 Unless the --force option is provided, solutions and modules whose |  | 
|   968 local revision matches the one to update (i.e., they have not changed |  | 
|   969 in the repository) are *not* modified. Unless --nohooks is provided, |  | 
|   970 the hooks are run. See 'help config' for more information. |  | 
|   971  |  | 
|   972 usage: gclient sync [options] [--] [SCM update options/args] |  | 
|   973  |  | 
|   974 Valid options: |  | 
|   975   --force                 : force update even for unchanged modules |  | 
|   976   --nohooks               : don't run the hooks after the update is complete |  | 
|   977   --revision SOLUTION@REV : update given solution to specified revision |  | 
|   978   --deps PLATFORM(S)      : sync deps for the given platform(s), or 'all' |  | 
|   979   --verbose               : output additional diagnostics |  | 
|   980   --head                  : update to latest revision, instead of last good |  | 
|   981                             revision |  | 
|   982   --reset                 : resets any local changes before updating (git only) |  | 
|   983  |  | 
|   984 Examples: |  | 
|   985   gclient sync |   914   gclient sync | 
|   986       update files from SCM according to current configuration, |   915       update files from SCM according to current configuration, | 
|   987       *for modules which have changed since last update or sync* |   916       *for modules which have changed since last update or sync* | 
|   988   gclient sync --force |   917   gclient sync --force | 
|   989       update files from SCM according to current configuration, for |   918       update files from SCM according to current configuration, for | 
|   990       all modules (useful for recovering files deleted from local copy) |   919       all modules (useful for recovering files deleted from local copy) | 
|   991   gclient sync --revision src@31000 |   920   gclient sync --revision src@31000 | 
|   992       update src directory to r31000 |   921       update src directory to r31000 | 
|   993 """ |   922 """) | 
 |   923 def CMDsync(parser, args): | 
 |   924   """Checkout/update all modules.""" | 
 |   925   parser.add_option("--force", action="store_true", | 
 |   926                     help="force update even for unchanged modules") | 
 |   927   parser.add_option("--nohooks", action="store_true", | 
 |   928                     help="don't run hooks after the update is complete") | 
 |   929   parser.add_option("-r", "--revision", action="append", | 
 |   930                     dest="revisions", metavar="REV", default=[], | 
 |   931                     help="update given solution to specified revision, " | 
 |   932                          "can be used multiple times for each solution, " | 
 |   933                          "e.g. -r src@123, -r internal@32") | 
 |   934   parser.add_option("--head", action="store_true", | 
 |   935                     help="skips any safesync_urls specified in " | 
 |   936                          "configured solutions and sync to head instead") | 
 |   937   parser.add_option("--delete_unversioned_trees", action="store_true", | 
 |   938                     help="delete any unexpected unversioned trees " | 
 |   939                          "that are in the checkout") | 
 |   940   parser.add_option("--reset", action="store_true", | 
 |   941                     help="resets any local changes before updating (git only)") | 
 |   942   parser.add_option("--deps", dest="deps_os", metavar="OS_LIST", | 
 |   943                     help="sync deps for the specified (comma-separated) " | 
 |   944                          "platform(s); 'all' will sync all platforms") | 
 |   945   parser.add_option("--manually_grab_svn_rev", action="store_true", | 
 |   946                     help="Skip svn up whenever possible by requesting " | 
 |   947                          "actual HEAD revision from the repository") | 
 |   948   (options, args) = parser.parse_args(args) | 
|   994   client = GClient.LoadCurrentConfig(options) |   949   client = GClient.LoadCurrentConfig(options) | 
|   995  |   950  | 
|   996   if not client: |   951   if not client: | 
|   997     raise gclient_utils.Error("client not configured; see 'gclient config'") |   952     raise gclient_utils.Error("client not configured; see 'gclient config'") | 
|   998  |   953  | 
|   999   if not options.head: |   954   if not options.head: | 
|  1000     solutions = client.GetVar('solutions') |   955     solutions = client.GetVar('solutions') | 
|  1001     if solutions: |   956     if solutions: | 
|  1002       for s in solutions: |   957       for s in solutions: | 
|  1003         if s.get('safesync_url', ''): |   958         if s.get('safesync_url', ''): | 
| (...skipping 12 matching lines...) Expand all  Loading... | 
|  1016             if len(rev): |   971             if len(rev): | 
|  1017               options.revisions.append(s['name']+'@'+rev) |   972               options.revisions.append(s['name']+'@'+rev) | 
|  1018  |   973  | 
|  1019   if options.verbose: |   974   if options.verbose: | 
|  1020     # Print out the .gclient file.  This is longer than if we just printed the |   975     # Print out the .gclient file.  This is longer than if we just printed the | 
|  1021     # client dict, but more legible, and it might contain helpful comments. |   976     # client dict, but more legible, and it might contain helpful comments. | 
|  1022     print(client.ConfigContent()) |   977     print(client.ConfigContent()) | 
|  1023   return client.RunOnDeps('update', args) |   978   return client.RunOnDeps('update', args) | 
|  1024  |   979  | 
|  1025  |   980  | 
|  1026 def CMDupdate(parser, options, args): |   981 def CMDupdate(parser, args): | 
|  1027   """Alias for the sync command. Deprecated.""" |   982   """Alias for the sync command. Deprecated.""" | 
|  1028   return CMDsync(parser, options, args) |   983   return CMDsync(parser, args) | 
|  1029  |   984  | 
|  1030  |   985 def CMDdiff(parser, args): | 
|  1031 def CMDdiff(parser, options, args): |   986   """Displays local diff for every dependencies.""" | 
|  1032   """Display the differences between two revisions of modules. |   987   (options, args) = parser.parse_args(args) | 
|  1033  |  | 
|  1034 (Does 'svn diff' for each checked out module and dependences.) |  | 
|  1035 Additional args and options to 'svn diff' can be passed after |  | 
|  1036 gclient options. |  | 
|  1037  |  | 
|  1038 usage: diff [options] [--] [svn args/options] |  | 
|  1039  |  | 
|  1040 Valid options: |  | 
|  1041   --verbose            : output additional diagnostics |  | 
|  1042  |  | 
|  1043 Examples: |  | 
|  1044   gclient diff |  | 
|  1045       simple 'svn diff' for configured client and dependences |  | 
|  1046   gclient diff -- -x -b |  | 
|  1047       use 'svn diff -x -b' to suppress whitespace-only differences |  | 
|  1048   gclient diff -- -r HEAD -x -b |  | 
|  1049       diff versus the latest version of each module |  | 
|  1050 """ |  | 
|  1051   client = GClient.LoadCurrentConfig(options) |   988   client = GClient.LoadCurrentConfig(options) | 
|  1052   if not client: |   989   if not client: | 
|  1053     raise gclient_utils.Error("client not configured; see 'gclient config'") |   990     raise gclient_utils.Error("client not configured; see 'gclient config'") | 
|  1054   if options.verbose: |   991   if options.verbose: | 
|  1055     # Print out the .gclient file.  This is longer than if we just printed the |   992     # Print out the .gclient file.  This is longer than if we just printed the | 
|  1056     # client dict, but more legible, and it might contain helpful comments. |   993     # client dict, but more legible, and it might contain helpful comments. | 
|  1057     print(client.ConfigContent()) |   994     print(client.ConfigContent()) | 
|  1058   return client.RunOnDeps('diff', args) |   995   return client.RunOnDeps('diff', args) | 
|  1059  |   996  | 
|  1060  |   997  | 
|  1061 def CMDrevert(parser, options, args): |   998 def CMDrevert(parser, args): | 
|  1062   """Revert every file in every managed directory in the client view.""" |   999   """Revert all modifications in every dependencies.""" | 
 |  1000   parser.add_option("--nohooks", action="store_true", | 
 |  1001                     help="don't run hooks after the revert is complete") | 
 |  1002   (options, args) = parser.parse_args(args) | 
|  1063   client = GClient.LoadCurrentConfig(options) |  1003   client = GClient.LoadCurrentConfig(options) | 
|  1064   if not client: |  1004   if not client: | 
|  1065     raise gclient_utils.Error("client not configured; see 'gclient config'") |  1005     raise gclient_utils.Error("client not configured; see 'gclient config'") | 
|  1066   return client.RunOnDeps('revert', args) |  1006   return client.RunOnDeps('revert', args) | 
|  1067  |  1007  | 
|  1068  |  1008  | 
|  1069 def CMDrunhooks(parser, options, args): |  1009 def CMDrunhooks(parser, args): | 
|  1070   """Runs hooks for files that have been modified in the local working copy. |  1010   """Runs hooks for files that have been modified in the local working copy.""" | 
|  1071  |  1011   parser.add_option("--force", action="store_true", default=True, | 
|  1072 Implies --force. |  1012                     help="Deprecated. No effect.") | 
|  1073  |  1013   (options, args) = parser.parse_args(args) | 
|  1074 usage: runhooks [options] |  | 
|  1075  |  | 
|  1076 Valid options: |  | 
|  1077   --verbose           : output additional diagnostics |  | 
|  1078 """ |  | 
|  1079   client = GClient.LoadCurrentConfig(options) |  1014   client = GClient.LoadCurrentConfig(options) | 
|  1080   if not client: |  1015   if not client: | 
|  1081     raise gclient_utils.Error("client not configured; see 'gclient config'") |  1016     raise gclient_utils.Error("client not configured; see 'gclient config'") | 
|  1082   if options.verbose: |  1017   if options.verbose: | 
|  1083     # Print out the .gclient file.  This is longer than if we just printed the |  1018     # Print out the .gclient file.  This is longer than if we just printed the | 
|  1084     # client dict, but more legible, and it might contain helpful comments. |  1019     # client dict, but more legible, and it might contain helpful comments. | 
|  1085     print(client.ConfigContent()) |  1020     print(client.ConfigContent()) | 
|  1086   options.force = True |  1021   options.force = True | 
|  1087   return client.RunOnDeps('runhooks', args) |  1022   return client.RunOnDeps('runhooks', args) | 
|  1088  |  1023  | 
|  1089  |  1024  | 
|  1090 def CMDrevinfo(parser, options, args): |  1025 def CMDrevinfo(parser, args): | 
|  1091   """Outputs defails for every dependencies. |  1026   """Outputs details for every dependencies.""" | 
|  1092  |  1027   parser.add_option("--snapshot", action="store_true", | 
|  1093 This includes source path, server URL and revision information for every |  1028                     help="create a snapshot file of the current " | 
|  1094 dependency in all solutions. |  1029                          "version of all repositories") | 
|  1095  |  1030   (options, args) = parser.parse_args(args) | 
|  1096 usage: revinfo [options] |  | 
|  1097 """ |  | 
|  1098   __pychecker__ = 'unusednames=args' |  | 
|  1099   client = GClient.LoadCurrentConfig(options) |  1031   client = GClient.LoadCurrentConfig(options) | 
|  1100   if not client: |  1032   if not client: | 
|  1101     raise gclient_utils.Error("client not configured; see 'gclient config'") |  1033     raise gclient_utils.Error("client not configured; see 'gclient config'") | 
|  1102   client.PrintRevInfo() |  1034   client.PrintRevInfo() | 
|  1103   return 0 |  1035   return 0 | 
|  1104  |  1036  | 
|  1105  |  1037  | 
|  1106 def CMDhelp(parser, options, args): |  1038 def Command(name): | 
|  1107   """Prints general help or command-specific documentation.""" |  1039   return getattr(sys.modules[__name__], 'CMD' + name, None) | 
 |  1040  | 
 |  1041  | 
 |  1042 def CMDhelp(parser, args): | 
 |  1043   """Prints list of commands or help for a specific command.""" | 
 |  1044   (options, args) = parser.parse_args(args) | 
|  1108   if len(args) == 1: |  1045   if len(args) == 1: | 
|  1109     command = Command(args[0]) |  1046     return Main(args + ['--help']) | 
|  1110     if command: |  | 
|  1111       print getattr(sys.modules[__name__], 'CMD' + args[0]).__doc__ |  | 
|  1112       return 0 |  | 
|  1113   parser.usage = (DEFAULT_USAGE_TEXT + '\nCommands are:\n' + '\n'.join([ |  | 
|  1114       '  %-10s %s' % (fn[3:], Command(fn[3:]).__doc__.split('\n')[0].strip()) |  | 
|  1115       for fn in dir(sys.modules[__name__]) if fn.startswith('CMD')])) |  | 
|  1116   parser.print_help() |  1047   parser.print_help() | 
|  1117   return 0 |  1048   return 0 | 
|  1118  |  1049  | 
|  1119  |  1050  | 
|  1120 def Command(command): |  1051 def GenUsage(parser, command): | 
|  1121   return getattr(sys.modules[__name__], 'CMD' + command, CMDhelp) |  1052   """Modify an OptParse object with the function's documentation.""" | 
 |  1053   obj = Command(command) | 
 |  1054   if command == 'help': | 
 |  1055     command = '<command>' | 
 |  1056   # OptParser.description prefer nicely non-formatted strings. | 
 |  1057   parser.description = re.sub('[\r\n ]{2,}', ' ', obj.__doc__) | 
 |  1058   usage = getattr(obj, 'usage', '') | 
 |  1059   parser.set_usage('%%prog %s [options] %s' % (command, usage)) | 
 |  1060   parser.epilog = getattr(obj, 'epilog', None) | 
|  1122  |  1061  | 
|  1123  |  1062  | 
|  1124 def Main(argv): |  1063 def Main(argv): | 
|  1125   parser = optparse.OptionParser(usage=DEFAULT_USAGE_TEXT, |  1064   """Doesn't parse the arguments here, just find the right subcommand to | 
|  1126                                  version='%prog ' + __version__) |  1065   execute.""" | 
 |  1066   # Do it late so all commands are listed. | 
 |  1067   CMDhelp.usage = ('\n\nCommands are:\n' + '\n'.join([ | 
 |  1068       '  %-10s %s' % (fn[3:], Command(fn[3:]).__doc__.split('\n')[0].strip()) | 
 |  1069       for fn in dir(sys.modules[__name__]) if fn.startswith('CMD')])) | 
 |  1070   parser = optparse.OptionParser(version='%prog ' + __version__) | 
|  1127   parser.add_option("-v", "--verbose", action="count", default=0, |  1071   parser.add_option("-v", "--verbose", action="count", default=0, | 
|  1128                     help="Produces additional output for diagnostics. Can be " |  1072                     help="Produces additional output for diagnostics. Can be " | 
|  1129                          "used up to three times for more logging info.") |  1073                          "used up to three times for more logging info.") | 
|  1130   parser.add_option("--gclientfile", metavar="FILENAME", dest="config_filename", |  1074   parser.add_option("--gclientfile", metavar="FILENAME", dest="config_filename", | 
|  1131                     default=os.environ.get("GCLIENT_FILE", ".gclient"), |  1075                     default=os.environ.get("GCLIENT_FILE", ".gclient"), | 
|  1132                     help="Specify an alternate .gclient file") |  1076                     help="Specify an alternate .gclient file") | 
|  1133   # The other options will be moved eventually. |  | 
|  1134   parser.add_option("--force", action="store_true", |  | 
|  1135                     help="(update/sync only) force update even " |  | 
|  1136                          "for modules which haven't changed") |  | 
|  1137   parser.add_option("--nohooks", action="store_true", |  | 
|  1138                     help="(update/sync/revert only) prevent the hooks " |  | 
|  1139                          "from running") |  | 
|  1140   parser.add_option("--revision", action="append", dest="revisions", |  | 
|  1141                     metavar="REV", default=[], |  | 
|  1142                     help="(update/sync only) sync to a specific " |  | 
|  1143                          "revision, can be used multiple times for " |  | 
|  1144                          "each solution, e.g. --revision=src@123, " |  | 
|  1145                          "--revision=internal@32") |  | 
|  1146   parser.add_option("--deps", dest="deps_os", metavar="OS_LIST", |  | 
|  1147                     help="(update/sync only) sync deps for the " |  | 
|  1148                          "specified (comma-separated) platform(s); " |  | 
|  1149                          "'all' will sync all platforms") |  | 
|  1150   parser.add_option("--reset", action="store_true", |  | 
|  1151                     help="(update/sync only) resets any local changes " |  | 
|  1152                          "before updating (git only)") |  | 
|  1153   parser.add_option("--spec", |  | 
|  1154                     help="(config only) create a gclient file " |  | 
|  1155                          "containing the provided string") |  | 
|  1156   parser.add_option("--manually_grab_svn_rev", action="store_true", |  | 
|  1157                     help="Skip svn up whenever possible by requesting " |  | 
|  1158                          "actual HEAD revision from the repository") |  | 
|  1159   parser.add_option("--head", action="store_true", |  | 
|  1160                     help="skips any safesync_urls specified in " |  | 
|  1161                           "configured solutions") |  | 
|  1162   parser.add_option("--delete_unversioned_trees", action="store_true", |  | 
|  1163                     help="on update, delete any unexpected " |  | 
|  1164                          "unversioned trees that are in the checkout") |  | 
|  1165   parser.add_option("--snapshot", action="store_true", |  | 
|  1166                     help="(revinfo only), create a snapshot file " |  | 
|  1167                          "of the current version of all repositories") |  | 
|  1168   parser.add_option("--name", |  | 
|  1169                     help="specify alternate relative solution path") |  | 
|  1170   # Integrate standard options processing. |  1077   # Integrate standard options processing. | 
|  1171   old_parser = parser.parse_args |  1078   old_parser = parser.parse_args | 
|  1172   def Parse(args): |  1079   def Parse(args): | 
|  1173     (options, args) = old_parser(args) |  1080     (options, args) = old_parser(args) | 
|  1174     if options.verbose == 2: |  1081     if options.verbose == 2: | 
|  1175       logging.basicConfig(level=logging.INFO) |  1082       logging.basicConfig(level=logging.INFO) | 
|  1176     elif options.verbose > 2: |  1083     elif options.verbose > 2: | 
|  1177       logging.basicConfig(level=logging.DEBUG) |  1084       logging.basicConfig(level=logging.DEBUG) | 
|  1178     options.entries_filename = options.config_filename + "_entries" |  1085     options.entries_filename = options.config_filename + "_entries" | 
|  1179     return (options, args) |  1086     return (options, args) | 
|  1180   parser.parse_args = Parse |  1087   parser.parse_args = Parse | 
|  1181   # We don't want wordwrapping in epilog (usually examples) |  1088   # We don't want wordwrapping in epilog (usually examples) | 
|  1182   parser.format_epilog = lambda _: parser.epilog or '' |  1089   parser.format_epilog = lambda _: parser.epilog or '' | 
|  1183  |  1090   if argv: | 
|  1184   if not len(argv): |  1091     command = Command(argv[0]) | 
|  1185     argv = ['help'] |  1092     if command: | 
|  1186   # Add manual support for --version as first argument. |  1093       # "fix" the usage and the description now that we know the subcommand. | 
|  1187   if argv[0] == '--version': |  1094       GenUsage(parser, argv[0]) | 
|  1188     parser.print_version() |  1095       return command(parser, argv[1:]) | 
|  1189     return 0 |  1096   # Not a known command. Default to help. | 
|  1190   # Add manual support for --help as first argument. |  1097   GenUsage(parser, 'help') | 
|  1191   if argv[0] == '--help': |  1098   return CMDhelp(parser, argv) | 
|  1192     argv[0] = 'help' |  | 
|  1193   options, args = parser.parse_args(argv[1:]) |  | 
|  1194   return Command(argv[0])(parser, options, args) |  | 
|  1195  |  1099  | 
|  1196  |  1100  | 
|  1197 if "__main__" == __name__: |  1101 if "__main__" == __name__: | 
|  1198   try: |  1102   try: | 
|  1199     sys.exit(Main(sys.argv[1:])) |  1103     sys.exit(Main(sys.argv[1:])) | 
|  1200   except gclient_utils.Error, e: |  1104   except gclient_utils.Error, e: | 
|  1201     print >> sys.stderr, "Error: %s" % str(e) |  1105     print >> sys.stderr, "Error: %s" % str(e) | 
|  1202     sys.exit(1) |  1106     sys.exit(1) | 
|  1203  |  1107  | 
|  1204 # vim: ts=2:sw=2:tw=80:et: |  1108 # vim: ts=2:sw=2:tw=80:et: | 
| OLD | NEW |