| Index: gclient.py
|
| diff --git a/gclient.py b/gclient.py
|
| index e1df6e08dce2a4db3611a041dafe444caf11cb5b..e7672a14b5de59ba8b63e08b00f9cab7a64b1e5a 100644
|
| --- a/gclient.py
|
| +++ b/gclient.py
|
| @@ -55,7 +55,7 @@ Hooks
|
| ]
|
| """
|
|
|
| -__version__ = "0.3.6"
|
| +__version__ = "0.3.7"
|
|
|
| import errno
|
| import logging
|
| @@ -75,23 +75,10 @@ from third_party.repo.progress import Progress
|
|
|
| # default help text
|
| DEFAULT_USAGE_TEXT = (
|
| -"""usage: %prog <subcommand> [options] [--] [SCM options/args...]
|
| +"""%prog <subcommand> [options] [--] [SCM options/args...]
|
| a wrapper for managing a set of svn client modules and/or git repositories.
|
| Version """ + __version__ + """
|
|
|
| -subcommands:
|
| - cleanup
|
| - config
|
| - diff
|
| - export
|
| - pack
|
| - revert
|
| - status
|
| - sync
|
| - update
|
| - runhooks
|
| - revinfo
|
| -
|
| Options and extra arguments can be passed to invoked SCM commands by
|
| appending them to the command line. Note that if the first such
|
| appended option starts with a dash (-) then the options must be
|
| @@ -829,8 +816,9 @@ solutions = [
|
| ## gclient commands.
|
|
|
|
|
| -def CMDcleanup(options, args):
|
| +def CMDcleanup(parser, options, args):
|
| """Clean up all working copies, using 'svn cleanup' for each module.
|
| +
|
| Additional options and args may be passed to 'svn cleanup'.
|
|
|
| usage: cleanup [options] [--] [svn cleanup args/options]
|
| @@ -848,9 +836,10 @@ Valid options:
|
| return client.RunOnDeps('cleanup', args)
|
|
|
|
|
| -def CMDconfig(options, args):
|
| - """Create a .gclient file in the current directory; this
|
| -specifies the configuration for further commands. After update/sync,
|
| +def CMDconfig(parser, options, args):
|
| + """Create a .gclient file in the current directory.
|
| +
|
| +This specifies the configuration for further commands. After update/sync,
|
| top-level DEPS files in each module are read to determine dependent
|
| modules to operate on as well. If optional [url] parameter is
|
| provided, then configuration is read from a specified Subversion server
|
| @@ -897,9 +886,8 @@ Examples:
|
| return 0
|
|
|
|
|
| -def CMDexport(options, args):
|
| - """Wrapper for svn export for all managed directories
|
| -"""
|
| +def CMDexport(parser, options, args):
|
| + """Wrapper for svn export for all managed directories."""
|
| if len(args) != 1:
|
| raise gclient_utils.Error("Need directory name")
|
| client = GClient.LoadCurrentConfig(options)
|
| @@ -914,27 +902,9 @@ def CMDexport(options, args):
|
| return client.RunOnDeps('export', args)
|
|
|
|
|
| -def CMDhelp(options, args):
|
| - """Describe the usage of this program or its subcommands.
|
| -
|
| -usage: help [options] [subcommand]
|
| -
|
| -Valid options:
|
| - --verbose : output additional diagnostics
|
| -"""
|
| - __pychecker__ = 'unusednames=options'
|
| - module = sys.modules[__name__]
|
| - commands = [x[3:] for x in dir(module) if x.startswith('CMD')]
|
| - if len(args) == 1 and args[0] in commands:
|
| - print getattr(module, 'CMD' + args[0]).__doc__
|
| - else:
|
| - raise gclient_utils.Error("unknown subcommand '%s'; see 'gclient help'" %
|
| - args[0])
|
| - return 0
|
| -
|
| -
|
| -def CMDpack(options, args):
|
| +def CMDpack(parser, options, args):
|
| """Generate a patch which can be applied at the root of the tree.
|
| +
|
| Internally, runs 'svn diff' on each checked out module and
|
| dependencies, and performs minimal postprocessing of the output. The
|
| resulting patch is printed to stdout and can be applied to a freshly
|
| @@ -966,9 +936,10 @@ Examples:
|
| return client.RunOnDeps('pack', args)
|
|
|
|
|
| -def CMDstatus(options, args):
|
| - """Show the status of client and dependent modules, using 'svn diff'
|
| -for each module. Additional options and args may be passed to 'svn diff'.
|
| +def CMDstatus(parser, options, args):
|
| + """Show the modification status of for every dependencies.
|
| +
|
| +Additional options and args may be passed to 'svn status'.
|
|
|
| usage: status [options] [--] [svn diff args/options]
|
|
|
| @@ -986,17 +957,17 @@ Valid options:
|
| return client.RunOnDeps('status', args)
|
|
|
|
|
| -def CMDsync(options, args):
|
| - """Perform a checkout/update of the modules specified by the gclient
|
| -configuration; see 'help config'. Unless --revision is specified,
|
| -then the latest revision of the root solutions is checked out, with
|
| -dependent submodule versions updated according to DEPS files.
|
| -If --revision is specified, then the given revision is used in place
|
| +def CMDsync(parser, options, args):
|
| + """Checkout/update the modules specified by the gclient configuration.
|
| +
|
| +Unless --revision is specified, then the latest revision of the root solutions
|
| +is checked out, with dependent submodule versions updated according to DEPS
|
| +files. If --revision is specified, then the given revision is used in place
|
| of the latest, either for a single solution or for all solutions.
|
| Unless the --force option is provided, solutions and modules whose
|
| local revision matches the one to update (i.e., they have not changed
|
| in the repository) are *not* modified. Unless --nohooks is provided,
|
| -the hooks are run.
|
| +the hooks are run. See 'help config' for more information.
|
|
|
| usage: gclient sync [options] [--] [SCM update options/args]
|
|
|
| @@ -1052,14 +1023,14 @@ Examples:
|
| return client.RunOnDeps('update', args)
|
|
|
|
|
| -def CMDupdate(options, args):
|
| - """Alias for the sync command. Deprecated.
|
| -"""
|
| - return CMDsync(options, args)
|
| +def CMDupdate(parser, options, args):
|
| + """Alias for the sync command. Deprecated."""
|
| + return CMDsync(parser, options, args)
|
|
|
|
|
| -def CMDdiff(options, args):
|
| +def CMDdiff(parser, options, args):
|
| """Display the differences between two revisions of modules.
|
| +
|
| (Does 'svn diff' for each checked out module and dependences.)
|
| Additional args and options to 'svn diff' can be passed after
|
| gclient options.
|
| @@ -1087,18 +1058,18 @@ Examples:
|
| return client.RunOnDeps('diff', args)
|
|
|
|
|
| -def CMDrevert(options, args):
|
| - """Revert every file in every managed directory in the client view.
|
| -"""
|
| +def CMDrevert(parser, options, args):
|
| + """Revert every file in every managed directory in the client view."""
|
| client = GClient.LoadCurrentConfig(options)
|
| if not client:
|
| raise gclient_utils.Error("client not configured; see 'gclient config'")
|
| return client.RunOnDeps('revert', args)
|
|
|
|
|
| -def CMDrunhooks(options, args):
|
| - """Runs hooks for files that have been modified in the local working copy,
|
| -according to 'svn status'. Implies --force.
|
| +def CMDrunhooks(parser, options, args):
|
| + """Runs hooks for files that have been modified in the local working copy.
|
| +
|
| +Implies --force.
|
|
|
| usage: runhooks [options]
|
|
|
| @@ -1116,8 +1087,10 @@ Valid options:
|
| return client.RunOnDeps('runhooks', args)
|
|
|
|
|
| -def CMDrevinfo(options, args):
|
| - """Outputs source path, server URL and revision information for every
|
| +def CMDrevinfo(parser, options, args):
|
| + """Outputs defails for every dependencies.
|
| +
|
| +This includes source path, server URL and revision information for every
|
| dependency in all solutions.
|
|
|
| usage: revinfo [options]
|
| @@ -1130,102 +1103,102 @@ usage: revinfo [options]
|
| return 0
|
|
|
|
|
| -def DispatchCommand(command, options, args):
|
| - """Dispatches the appropriate subcommand based on command line arguments.
|
| -"""
|
| - module = sys.modules[__name__]
|
| - command = getattr(module, 'CMD' + command, None)
|
| - if command:
|
| - return command(options, args)
|
| - else:
|
| - raise gclient_utils.Error("unknown subcommand '%s'; see 'gclient help'" %
|
| - command)
|
| +def CMDhelp(parser, options, args):
|
| + """Prints general help or command-specific documentation."""
|
| + if len(args) == 1:
|
| + command = Command(args[0])
|
| + if command:
|
| + print getattr(sys.modules[__name__], 'CMD' + args[0]).__doc__
|
| + return 0
|
| + parser.usage = (DEFAULT_USAGE_TEXT + '\nCommands are:\n' + '\n'.join([
|
| + ' %-10s %s' % (fn[3:], Command(fn[3:]).__doc__.split('\n')[0].strip())
|
| + for fn in dir(sys.modules[__name__]) if fn.startswith('CMD')]))
|
| + parser.print_help()
|
| + return 0
|
| +
|
| +
|
| +def Command(command):
|
| + return getattr(sys.modules[__name__], 'CMD' + command, CMDhelp)
|
|
|
|
|
| def Main(argv):
|
| - option_parser = optparse.OptionParser(usage=DEFAULT_USAGE_TEXT,
|
| - version=__version__)
|
| - option_parser.add_option("--force", action="store_true",
|
| - help="(update/sync only) force update even "
|
| - "for modules which haven't changed")
|
| - option_parser.add_option("--nohooks", action="store_true",
|
| - help="(update/sync/revert only) prevent the hooks "
|
| - "from running")
|
| - option_parser.add_option("--revision", action="append", dest="revisions",
|
| - metavar="REV", default=[],
|
| - help="(update/sync only) sync to a specific "
|
| - "revision, can be used multiple times for "
|
| - "each solution, e.g. --revision=src@123, "
|
| - "--revision=internal@32")
|
| - option_parser.add_option("--deps", dest="deps_os", metavar="OS_LIST",
|
| - help="(update/sync only) sync deps for the "
|
| - "specified (comma-separated) platform(s); "
|
| - "'all' will sync all platforms")
|
| - option_parser.add_option("--reset", action="store_true",
|
| - help="(update/sync only) resets any local changes "
|
| - "before updating (git only)")
|
| - option_parser.add_option("--spec",
|
| - help="(config only) create a gclient file "
|
| - "containing the provided string")
|
| - option_parser.add_option("-v", "--verbose", action="count", default=0,
|
| - help="produce additional output for diagnostics")
|
| - option_parser.add_option("--manually_grab_svn_rev", action="store_true",
|
| - help="Skip svn up whenever possible by requesting "
|
| - "actual HEAD revision from the repository")
|
| - option_parser.add_option("--head", action="store_true",
|
| - help="skips any safesync_urls specified in "
|
| - "configured solutions")
|
| - option_parser.add_option("--delete_unversioned_trees", action="store_true",
|
| - help="on update, delete any unexpected "
|
| - "unversioned trees that are in the checkout")
|
| - option_parser.add_option("--snapshot", action="store_true",
|
| - help="(revinfo only), create a snapshot file "
|
| - "of the current version of all repositories")
|
| - option_parser.add_option("--name",
|
| - help="specify alternate relative solution path")
|
| - option_parser.add_option("--gclientfile", metavar="FILENAME",
|
| - help="specify an alternate .gclient file")
|
| -
|
| - if len(argv) < 2:
|
| - # Users don't need to be told to use the 'help' command.
|
| - option_parser.print_help()
|
| - return 1
|
| + parser = optparse.OptionParser(usage=DEFAULT_USAGE_TEXT,
|
| + version='%prog ' + __version__)
|
| + parser.add_option("-v", "--verbose", action="count", default=0,
|
| + help="Produces additional output for diagnostics. Can be "
|
| + "used up to three times for more logging info.")
|
| + parser.add_option("--gclientfile", metavar="FILENAME", dest="config_filename",
|
| + default=os.environ.get("GCLIENT_FILE", ".gclient"),
|
| + help="Specify an alternate .gclient file")
|
| + # The other options will be moved eventually.
|
| + parser.add_option("--force", action="store_true",
|
| + help="(update/sync only) force update even "
|
| + "for modules which haven't changed")
|
| + parser.add_option("--nohooks", action="store_true",
|
| + help="(update/sync/revert only) prevent the hooks "
|
| + "from running")
|
| + parser.add_option("--revision", action="append", dest="revisions",
|
| + metavar="REV", default=[],
|
| + help="(update/sync only) sync to a specific "
|
| + "revision, can be used multiple times for "
|
| + "each solution, e.g. --revision=src@123, "
|
| + "--revision=internal@32")
|
| + parser.add_option("--deps", dest="deps_os", metavar="OS_LIST",
|
| + help="(update/sync only) sync deps for the "
|
| + "specified (comma-separated) platform(s); "
|
| + "'all' will sync all platforms")
|
| + parser.add_option("--reset", action="store_true",
|
| + help="(update/sync only) resets any local changes "
|
| + "before updating (git only)")
|
| + parser.add_option("--spec",
|
| + help="(config only) create a gclient file "
|
| + "containing the provided string")
|
| + parser.add_option("--manually_grab_svn_rev", action="store_true",
|
| + help="Skip svn up whenever possible by requesting "
|
| + "actual HEAD revision from the repository")
|
| + parser.add_option("--head", action="store_true",
|
| + help="skips any safesync_urls specified in "
|
| + "configured solutions")
|
| + parser.add_option("--delete_unversioned_trees", action="store_true",
|
| + help="on update, delete any unexpected "
|
| + "unversioned trees that are in the checkout")
|
| + parser.add_option("--snapshot", action="store_true",
|
| + help="(revinfo only), create a snapshot file "
|
| + "of the current version of all repositories")
|
| + parser.add_option("--name",
|
| + help="specify alternate relative solution path")
|
| + # Integrate standard options processing.
|
| + old_parser = parser.parse_args
|
| + def Parse(args):
|
| + (options, args) = old_parser(args)
|
| + if options.verbose == 2:
|
| + logging.basicConfig(level=logging.INFO)
|
| + elif options.verbose > 2:
|
| + logging.basicConfig(level=logging.DEBUG)
|
| + options.entries_filename = options.config_filename + "_entries"
|
| + return (options, args)
|
| + parser.parse_args = Parse
|
| + # We don't want wordwrapping in epilog (usually examples)
|
| + parser.format_epilog = lambda _: parser.epilog or ''
|
| +
|
| + if not len(argv):
|
| + argv = ['help']
|
| # Add manual support for --version as first argument.
|
| - if argv[1] == '--version':
|
| - option_parser.print_version()
|
| + if argv[0] == '--version':
|
| + parser.print_version()
|
| return 0
|
| -
|
| # Add manual support for --help as first argument.
|
| - if argv[1] == '--help':
|
| - argv[1] = 'help'
|
| -
|
| - command = argv[1]
|
| - options, args = option_parser.parse_args(argv[2:])
|
| -
|
| - if len(argv) < 3 and command == "help":
|
| - option_parser.print_help()
|
| - return 0
|
| -
|
| - if options.verbose > 1:
|
| - logging.basicConfig(level=logging.DEBUG)
|
| -
|
| - # Files used for configuration and state saving.
|
| - options.config_filename = os.environ.get("GCLIENT_FILE", ".gclient")
|
| - if options.gclientfile:
|
| - options.config_filename = options.gclientfile
|
| - options.entries_filename = options.config_filename + "_entries"
|
| - options.deps_file = "DEPS"
|
| -
|
| - options.platform = sys.platform
|
| - return DispatchCommand(command, options, args)
|
| + if argv[0] == '--help':
|
| + argv[0] = 'help'
|
| + options, args = parser.parse_args(argv[1:])
|
| + return Command(argv[0])(parser, options, args)
|
|
|
|
|
| if "__main__" == __name__:
|
| try:
|
| - result = Main(sys.argv)
|
| + sys.exit(Main(sys.argv[1:]))
|
| except gclient_utils.Error, e:
|
| print >> sys.stderr, "Error: %s" % str(e)
|
| - result = 1
|
| - sys.exit(result)
|
| + sys.exit(1)
|
|
|
| # vim: ts=2:sw=2:tw=80:et:
|
|
|