| 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 __author__ = "darinf@gmail.com (Darin Fisher)" | 58 __version__ = "0.3.5" |
| 59 __version__ = "0.3.4" | |
| 60 | 59 |
| 61 import errno | 60 import errno |
| 62 import logging | 61 import logging |
| 63 import optparse | 62 import optparse |
| 64 import os | 63 import os |
| 65 import pprint | 64 import pprint |
| 66 import re | 65 import re |
| 67 import sys | 66 import sys |
| 68 import urlparse | 67 import urlparse |
| 69 import urllib | 68 import urllib |
| (...skipping 26 matching lines...) Expand all Loading... |
| 96 Options and extra arguments can be passed to invoked SCM commands by | 95 Options and extra arguments can be passed to invoked SCM commands by |
| 97 appending them to the command line. Note that if the first such | 96 appending them to the command line. Note that if the first such |
| 98 appended option starts with a dash (-) then the options must be | 97 appended option starts with a dash (-) then the options must be |
| 99 preceded by -- to distinguish them from gclient options. | 98 preceded by -- to distinguish them from gclient options. |
| 100 | 99 |
| 101 For additional help on a subcommand or examples of usage, try | 100 For additional help on a subcommand or examples of usage, try |
| 102 %prog help <subcommand> | 101 %prog help <subcommand> |
| 103 %prog help files | 102 %prog help files |
| 104 """) | 103 """) |
| 105 | 104 |
| 106 GENERIC_UPDATE_USAGE_TEXT = ( | |
| 107 """Perform a checkout/update of the modules specified by the gclient | |
| 108 configuration; see 'help config'. Unless --revision is specified, | |
| 109 then the latest revision of the root solutions is checked out, with | |
| 110 dependent submodule versions updated according to DEPS files. | |
| 111 If --revision is specified, then the given revision is used in place | |
| 112 of the latest, either for a single solution or for all solutions. | |
| 113 Unless the --force option is provided, solutions and modules whose | |
| 114 local revision matches the one to update (i.e., they have not changed | |
| 115 in the repository) are *not* modified. Unless --nohooks is provided, | |
| 116 the hooks are run. | |
| 117 This a synonym for 'gclient %(alias)s' | |
| 118 | |
| 119 usage: gclient %(cmd)s [options] [--] [SCM update options/args] | |
| 120 | |
| 121 Valid options: | |
| 122 --force : force update even for unchanged modules | |
| 123 --nohooks : don't run the hooks after the update is complete | |
| 124 --revision SOLUTION@REV : update given solution to specified revision | |
| 125 --deps PLATFORM(S) : sync deps for the given platform(s), or 'all' | |
| 126 --verbose : output additional diagnostics | |
| 127 --head : update to latest revision, instead of last good revi
sion | |
| 128 --reset : resets any local changes before updating (git only) | |
| 129 | |
| 130 Examples: | |
| 131 gclient %(cmd)s | |
| 132 update files from SCM according to current configuration, | |
| 133 *for modules which have changed since last update or sync* | |
| 134 gclient %(cmd)s --force | |
| 135 update files from SCM according to current configuration, for | |
| 136 all modules (useful for recovering files deleted from local copy) | |
| 137 gclient %(cmd)s --revision src@31000 | |
| 138 update src directory to r31000 | |
| 139 """) | |
| 140 | |
| 141 COMMAND_USAGE_TEXT = { | |
| 142 "cleanup": | |
| 143 """Clean up all working copies, using 'svn cleanup' for each module. | |
| 144 Additional options and args may be passed to 'svn cleanup'. | |
| 145 | |
| 146 usage: cleanup [options] [--] [svn cleanup args/options] | |
| 147 | |
| 148 Valid options: | |
| 149 --verbose : output additional diagnostics | |
| 150 """, | |
| 151 "config": """Create a .gclient file in the current directory; this | |
| 152 specifies the configuration for further commands. After update/sync, | |
| 153 top-level DEPS files in each module are read to determine dependent | |
| 154 modules to operate on as well. If optional [url] parameter is | |
| 155 provided, then configuration is read from a specified Subversion server | |
| 156 URL. Otherwise, a --spec option must be provided. A --name option overrides | |
| 157 the default name for the solutions. | |
| 158 | |
| 159 usage: config [option | url] [safesync url] | |
| 160 | |
| 161 Valid options: | |
| 162 --name path : alternate relative path for the solution | |
| 163 --spec=GCLIENT_SPEC : contents of .gclient are read from string parameter. | |
| 164 *Note that due to Cygwin/Python brokenness, it | |
| 165 probably can't contain any newlines.* | |
| 166 | |
| 167 Examples: | |
| 168 gclient config https://gclient.googlecode.com/svn/trunk/gclient | |
| 169 configure a new client to check out gclient.py tool sources | |
| 170 gclient config --name tools https://gclient.googlecode.com/svn/trunk/gclient | |
| 171 gclient config --spec='solutions=[{"name":"gclient",""" | |
| 172 '"url":"https://gclient.googlecode.com/svn/trunk/gclient",' | |
| 173 '"custom_deps":{}}]', | |
| 174 "diff": """Display the differences between two revisions of modules. | |
| 175 (Does 'svn diff' for each checked out module and dependences.) | |
| 176 Additional args and options to 'svn diff' can be passed after | |
| 177 gclient options. | |
| 178 | |
| 179 usage: diff [options] [--] [svn args/options] | |
| 180 | |
| 181 Valid options: | |
| 182 --verbose : output additional diagnostics | |
| 183 | |
| 184 Examples: | |
| 185 gclient diff | |
| 186 simple 'svn diff' for configured client and dependences | |
| 187 gclient diff -- -x -b | |
| 188 use 'svn diff -x -b' to suppress whitespace-only differences | |
| 189 gclient diff -- -r HEAD -x -b | |
| 190 diff versus the latest version of each module | |
| 191 """, | |
| 192 "export": | |
| 193 """Wrapper for svn export for all managed directories | |
| 194 """, | |
| 195 "pack": | |
| 196 | |
| 197 """Generate a patch which can be applied at the root of the tree. | |
| 198 Internally, runs 'svn diff' on each checked out module and | |
| 199 dependencies, and performs minimal postprocessing of the output. The | |
| 200 resulting patch is printed to stdout and can be applied to a freshly | |
| 201 checked out tree via 'patch -p0 < patchfile'. Additional args and | |
| 202 options to 'svn diff' can be passed after gclient options. | |
| 203 | |
| 204 usage: pack [options] [--] [svn args/options] | |
| 205 | |
| 206 Valid options: | |
| 207 --verbose : output additional diagnostics | |
| 208 | |
| 209 Examples: | |
| 210 gclient pack > patch.txt | |
| 211 generate simple patch for configured client and dependences | |
| 212 gclient pack -- -x -b > patch.txt | |
| 213 generate patch using 'svn diff -x -b' to suppress | |
| 214 whitespace-only differences | |
| 215 gclient pack -- -r HEAD -x -b > patch.txt | |
| 216 generate patch, diffing each file versus the latest version of | |
| 217 each module | |
| 218 """, | |
| 219 "revert": | |
| 220 """Revert every file in every managed directory in the client view. | |
| 221 | |
| 222 usage: revert | |
| 223 """, | |
| 224 "status": | |
| 225 """Show the status of client and dependent modules, using 'svn diff' | |
| 226 for each module. Additional options and args may be passed to 'svn diff'. | |
| 227 | |
| 228 usage: status [options] [--] [svn diff args/options] | |
| 229 | |
| 230 Valid options: | |
| 231 --verbose : output additional diagnostics | |
| 232 --nohooks : don't run the hooks after the update is complete | |
| 233 """, | |
| 234 "sync": GENERIC_UPDATE_USAGE_TEXT % {"cmd": "sync", "alias": "update"}, | |
| 235 "update": GENERIC_UPDATE_USAGE_TEXT % {"cmd": "update", "alias": "sync"}, | |
| 236 "help": """Describe the usage of this program or its subcommands. | |
| 237 | |
| 238 usage: help [options] [subcommand] | |
| 239 | |
| 240 Valid options: | |
| 241 --verbose : output additional diagnostics | |
| 242 """, | |
| 243 "runhooks": | |
| 244 """Runs hooks for files that have been modified in the local working copy, | |
| 245 according to 'svn status'. Implies --force. | |
| 246 | |
| 247 usage: runhooks [options] | |
| 248 | |
| 249 Valid options: | |
| 250 --verbose : output additional diagnostics | |
| 251 """, | |
| 252 "revinfo": | |
| 253 """Outputs source path, server URL and revision information for every | |
| 254 dependency in all solutions. | |
| 255 | |
| 256 usage: revinfo [options] | |
| 257 """, | |
| 258 } | |
| 259 | 105 |
| 260 DEFAULT_CLIENT_FILE_TEXT = ("""\ | 106 DEFAULT_CLIENT_FILE_TEXT = ("""\ |
| 261 # An element of this array (a "solution") describes a repository directory | 107 # An element of this array (a "solution") describes a repository directory |
| 262 # that will be checked out into your working copy. Each solution may | 108 # that will be checked out into your working copy. Each solution may |
| 263 # optionally define additional dependencies (via its DEPS file) to be | 109 # optionally define additional dependencies (via its DEPS file) to be |
| 264 # checked out alongside the solution's directory. A solution may also | 110 # checked out alongside the solution's directory. A solution may also |
| 265 # specify custom dependencies (via the "custom_deps" property) that | 111 # specify custom dependencies (via the "custom_deps" property) that |
| 266 # override or augment the dependencies specified by the DEPS file. | 112 # override or augment the dependencies specified by the DEPS file. |
| 267 # If a "safesync_url" is specified, it is assumed to reference the location of | 113 # If a "safesync_url" is specified, it is assumed to reference the location of |
| 268 # a text file which contains nothing but the last known good SCM revision to | 114 # a text file which contains nothing but the last known good SCM revision to |
| (...skipping 516 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 785 scm = gclient_scm.CreateSCM(url, self._root_dir, d) | 631 scm = gclient_scm.CreateSCM(url, self._root_dir, d) |
| 786 scm.RunCommand(command, self._options, args, file_list) | 632 scm.RunCommand(command, self._options, args, file_list) |
| 787 self._options.revision = None | 633 self._options.revision = None |
| 788 elif isinstance(deps[d], self.FileImpl): | 634 elif isinstance(deps[d], self.FileImpl): |
| 789 file = deps[d] | 635 file = deps[d] |
| 790 self._options.revision = file.GetRevision() | 636 self._options.revision = file.GetRevision() |
| 791 if run_scm: | 637 if run_scm: |
| 792 scm = gclient_scm.CreateSCM(file.GetPath(), self._root_dir, d) | 638 scm = gclient_scm.CreateSCM(file.GetPath(), self._root_dir, d) |
| 793 scm.RunCommand("updatesingle", self._options, | 639 scm.RunCommand("updatesingle", self._options, |
| 794 args + [file.GetFilename()], file_list) | 640 args + [file.GetFilename()], file_list) |
| 795 | 641 |
| 796 if command == 'update' and not self._options.verbose: | 642 if command == 'update' and not self._options.verbose: |
| 797 pm.end() | 643 pm.end() |
| 798 | 644 |
| 799 # Second pass for inherited deps (via the From keyword) | 645 # Second pass for inherited deps (via the From keyword) |
| 800 for d in deps_to_process: | 646 for d in deps_to_process: |
| 801 if isinstance(deps[d], self.FromImpl): | 647 if isinstance(deps[d], self.FromImpl): |
| 802 filename = os.path.join(self._root_dir, | 648 filename = os.path.join(self._root_dir, |
| 803 deps[d].module_name, | 649 deps[d].module_name, |
| 804 self._options.deps_file) | 650 self._options.deps_file) |
| 805 content = gclient_utils.FileRead(filename) | 651 content = gclient_utils.FileRead(filename) |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 988 if self._options.snapshot: | 834 if self._options.snapshot: |
| 989 config = DEFAULT_SNAPSHOT_FILE_TEXT % {'solution_list': new_gclient} | 835 config = DEFAULT_SNAPSHOT_FILE_TEXT % {'solution_list': new_gclient} |
| 990 snapclient = GClient(self._root_dir, self._options) | 836 snapclient = GClient(self._root_dir, self._options) |
| 991 snapclient.SetConfig(config) | 837 snapclient.SetConfig(config) |
| 992 print(snapclient._config_content) | 838 print(snapclient._config_content) |
| 993 | 839 |
| 994 | 840 |
| 995 ## gclient commands. | 841 ## gclient commands. |
| 996 | 842 |
| 997 | 843 |
| 998 def DoCleanup(options, args): | 844 def CMDcleanup(options, args): |
| 999 """Handle the cleanup subcommand. | 845 """Clean up all working copies, using 'svn cleanup' for each module. |
| 846 Additional options and args may be passed to 'svn cleanup'. |
| 1000 | 847 |
| 1001 Raises: | 848 usage: cleanup [options] [--] [svn cleanup args/options] |
| 1002 Error: if client isn't configured properly. | 849 |
| 1003 """ | 850 Valid options: |
| 851 --verbose : output additional diagnostics |
| 852 """ |
| 1004 client = GClient.LoadCurrentConfig(options) | 853 client = GClient.LoadCurrentConfig(options) |
| 1005 if not client: | 854 if not client: |
| 1006 raise gclient_utils.Error("client not configured; see 'gclient config'") | 855 raise gclient_utils.Error("client not configured; see 'gclient config'") |
| 1007 if options.verbose: | 856 if options.verbose: |
| 1008 # Print out the .gclient file. This is longer than if we just printed the | 857 # Print out the .gclient file. This is longer than if we just printed the |
| 1009 # client dict, but more legible, and it might contain helpful comments. | 858 # client dict, but more legible, and it might contain helpful comments. |
| 1010 print(client.ConfigContent()) | 859 print(client.ConfigContent()) |
| 1011 return client.RunOnDeps('cleanup', args) | 860 return client.RunOnDeps('cleanup', args) |
| 1012 | 861 |
| 1013 | 862 |
| 1014 def DoConfig(options, args): | 863 def CMDconfig(options, args): |
| 1015 """Handle the config subcommand. | 864 """Create a .gclient file in the current directory; this |
| 865 specifies the configuration for further commands. After update/sync, |
| 866 top-level DEPS files in each module are read to determine dependent |
| 867 modules to operate on as well. If optional [url] parameter is |
| 868 provided, then configuration is read from a specified Subversion server |
| 869 URL. Otherwise, a --spec option must be provided. A --name option overrides |
| 870 the default name for the solutions. |
| 1016 | 871 |
| 1017 Args: | 872 usage: config [option | url] [safesync url] |
| 1018 options: If options.spec set, a string providing contents of config file. | |
| 1019 args: The command line args. If spec is not set, | |
| 1020 then args[0] is a string URL to get for config file. | |
| 1021 | 873 |
| 1022 Raises: | 874 Valid options: |
| 1023 Error: on usage error | 875 --name path : alternate relative path for the solution |
| 1024 """ | 876 --spec=GCLIENT_SPEC : contents of .gclient are read from string parameter. |
| 877 *Note that due to Cygwin/Python brokenness, it |
| 878 probably can't contain any newlines.* |
| 879 |
| 880 Examples: |
| 881 gclient config https://gclient.googlecode.com/svn/trunk/gclient |
| 882 configure a new client to check out gclient.py tool sources |
| 883 gclient config --name tools https://gclient.googlecode.com/svn/trunk/gclient |
| 884 gclient config --spec='solutions=[{"name":"gclient", |
| 885 '"url":"https://gclient.googlecode.com/svn/trunk/gclient",' |
| 886 '"custom_deps":{}}]' |
| 887 """ |
| 1025 if len(args) < 1 and not options.spec: | 888 if len(args) < 1 and not options.spec: |
| 1026 raise gclient_utils.Error("required argument missing; see 'gclient help " | 889 raise gclient_utils.Error("required argument missing; see 'gclient help " |
| 1027 "config'") | 890 "config'") |
| 1028 if os.path.exists(options.config_filename): | 891 if os.path.exists(options.config_filename): |
| 1029 raise gclient_utils.Error("%s file already exists in the current directory" | 892 raise gclient_utils.Error("%s file already exists in the current directory" |
| 1030 % options.config_filename) | 893 % options.config_filename) |
| 1031 client = GClient('.', options) | 894 client = GClient('.', options) |
| 1032 if options.spec: | 895 if options.spec: |
| 1033 client.SetConfig(options.spec) | 896 client.SetConfig(options.spec) |
| 1034 else: | 897 else: |
| 1035 base_url = args[0].rstrip('/') | 898 base_url = args[0].rstrip('/') |
| 1036 if not options.name: | 899 if not options.name: |
| 1037 name = base_url.split("/")[-1] | 900 name = base_url.split("/")[-1] |
| 1038 else: | 901 else: |
| 1039 # specify an alternate relpath for the given URL. | 902 # specify an alternate relpath for the given URL. |
| 1040 name = options.name | 903 name = options.name |
| 1041 safesync_url = "" | 904 safesync_url = "" |
| 1042 if len(args) > 1: | 905 if len(args) > 1: |
| 1043 safesync_url = args[1] | 906 safesync_url = args[1] |
| 1044 client.SetDefaultConfig(name, base_url, safesync_url) | 907 client.SetDefaultConfig(name, base_url, safesync_url) |
| 1045 client.SaveConfig() | 908 client.SaveConfig() |
| 909 return 0 |
| 1046 | 910 |
| 1047 | 911 |
| 1048 def DoExport(options, args): | 912 def CMDexport(options, args): |
| 1049 """Handle the export subcommand. | 913 """Wrapper for svn export for all managed directories |
| 1050 | 914 """ |
| 1051 Raises: | |
| 1052 Error: on usage error | |
| 1053 """ | |
| 1054 if len(args) != 1: | 915 if len(args) != 1: |
| 1055 raise gclient_utils.Error("Need directory name") | 916 raise gclient_utils.Error("Need directory name") |
| 1056 client = GClient.LoadCurrentConfig(options) | 917 client = GClient.LoadCurrentConfig(options) |
| 1057 | 918 |
| 1058 if not client: | 919 if not client: |
| 1059 raise gclient_utils.Error("client not configured; see 'gclient config'") | 920 raise gclient_utils.Error("client not configured; see 'gclient config'") |
| 1060 | 921 |
| 1061 if options.verbose: | 922 if options.verbose: |
| 1062 # Print out the .gclient file. This is longer than if we just printed the | 923 # Print out the .gclient file. This is longer than if we just printed the |
| 1063 # client dict, but more legible, and it might contain helpful comments. | 924 # client dict, but more legible, and it might contain helpful comments. |
| 1064 print(client.ConfigContent()) | 925 print(client.ConfigContent()) |
| 1065 return client.RunOnDeps('export', args) | 926 return client.RunOnDeps('export', args) |
| 1066 | 927 |
| 1067 def DoHelp(options, args): | |
| 1068 """Handle the help subcommand giving help for another subcommand. | |
| 1069 | 928 |
| 1070 Raises: | 929 def CMDhelp(options, args): |
| 1071 Error: if the command is unknown. | 930 """Describe the usage of this program or its subcommands. |
| 1072 """ | 931 |
| 932 usage: help [options] [subcommand] |
| 933 |
| 934 Valid options: |
| 935 --verbose : output additional diagnostics |
| 936 """ |
| 1073 __pychecker__ = 'unusednames=options' | 937 __pychecker__ = 'unusednames=options' |
| 1074 if len(args) == 1 and args[0] in COMMAND_USAGE_TEXT: | 938 module = sys.modules[__name__] |
| 1075 print(COMMAND_USAGE_TEXT[args[0]]) | 939 commands = [x[3:] for x in dir(module) if x.startswith('CMD')] |
| 940 if len(args) == 1 and args[0] in commands: |
| 941 print getattr(module, 'CMD' + args[0]).__doc__ |
| 1076 else: | 942 else: |
| 1077 raise gclient_utils.Error("unknown subcommand '%s'; see 'gclient help'" % | 943 raise gclient_utils.Error("unknown subcommand '%s'; see 'gclient help'" % |
| 1078 args[0]) | 944 args[0]) |
| 945 return 0 |
| 1079 | 946 |
| 1080 | 947 |
| 1081 def DoPack(options, args): | 948 def CMDpack(options, args): |
| 1082 """Handle the pack subcommand. | 949 """Generate a patch which can be applied at the root of the tree. |
| 950 Internally, runs 'svn diff' on each checked out module and |
| 951 dependencies, and performs minimal postprocessing of the output. The |
| 952 resulting patch is printed to stdout and can be applied to a freshly |
| 953 checked out tree via 'patch -p0 < patchfile'. Additional args and |
| 954 options to 'svn diff' can be passed after gclient options. |
| 1083 | 955 |
| 1084 Raises: | 956 usage: pack [options] [--] [svn args/options] |
| 1085 Error: if client isn't configured properly. | 957 |
| 1086 """ | 958 Valid options: |
| 959 --verbose : output additional diagnostics |
| 960 |
| 961 Examples: |
| 962 gclient pack > patch.txt |
| 963 generate simple patch for configured client and dependences |
| 964 gclient pack -- -x -b > patch.txt |
| 965 generate patch using 'svn diff -x -b' to suppress |
| 966 whitespace-only differences |
| 967 gclient pack -- -r HEAD -x -b > patch.txt |
| 968 generate patch, diffing each file versus the latest version of |
| 969 each module |
| 970 """ |
| 1087 client = GClient.LoadCurrentConfig(options) | 971 client = GClient.LoadCurrentConfig(options) |
| 1088 if not client: | 972 if not client: |
| 1089 raise gclient_utils.Error("client not configured; see 'gclient config'") | 973 raise gclient_utils.Error("client not configured; see 'gclient config'") |
| 1090 if options.verbose: | 974 if options.verbose: |
| 1091 # 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 |
| 1092 # client dict, but more legible, and it might contain helpful comments. | 976 # client dict, but more legible, and it might contain helpful comments. |
| 1093 print(client.ConfigContent()) | 977 print(client.ConfigContent()) |
| 1094 return client.RunOnDeps('pack', args) | 978 return client.RunOnDeps('pack', args) |
| 1095 | 979 |
| 1096 | 980 |
| 1097 def DoStatus(options, args): | 981 def CMDstatus(options, args): |
| 1098 """Handle the status subcommand. | 982 """Show the status of client and dependent modules, using 'svn diff' |
| 983 for each module. Additional options and args may be passed to 'svn diff'. |
| 1099 | 984 |
| 1100 Raises: | 985 usage: status [options] [--] [svn diff args/options] |
| 1101 Error: if client isn't configured properly. | 986 |
| 1102 """ | 987 Valid options: |
| 988 --verbose : output additional diagnostics |
| 989 --nohooks : don't run the hooks after the update is complete |
| 990 """ |
| 1103 client = GClient.LoadCurrentConfig(options) | 991 client = GClient.LoadCurrentConfig(options) |
| 1104 if not client: | 992 if not client: |
| 1105 raise gclient_utils.Error("client not configured; see 'gclient config'") | 993 raise gclient_utils.Error("client not configured; see 'gclient config'") |
| 1106 if options.verbose: | 994 if options.verbose: |
| 1107 # Print out the .gclient file. This is longer than if we just printed the | 995 # Print out the .gclient file. This is longer than if we just printed the |
| 1108 # client dict, but more legible, and it might contain helpful comments. | 996 # client dict, but more legible, and it might contain helpful comments. |
| 1109 print(client.ConfigContent()) | 997 print(client.ConfigContent()) |
| 1110 return client.RunOnDeps('status', args) | 998 return client.RunOnDeps('status', args) |
| 1111 | 999 |
| 1112 | 1000 |
| 1113 def DoUpdate(options, args): | 1001 def CMDsync(options, args): |
| 1114 """Handle the update and sync subcommands. | 1002 """Perform a checkout/update of the modules specified by the gclient |
| 1003 configuration; see 'help config'. Unless --revision is specified, |
| 1004 then the latest revision of the root solutions is checked out, with |
| 1005 dependent submodule versions updated according to DEPS files. |
| 1006 If --revision is specified, then the given revision is used in place |
| 1007 of the latest, either for a single solution or for all solutions. |
| 1008 Unless the --force option is provided, solutions and modules whose |
| 1009 local revision matches the one to update (i.e., they have not changed |
| 1010 in the repository) are *not* modified. Unless --nohooks is provided, |
| 1011 the hooks are run. |
| 1115 | 1012 |
| 1116 Raises: | 1013 usage: gclient sync [options] [--] [SCM update options/args] |
| 1117 Error: if client isn't configured properly. | 1014 |
| 1118 """ | 1015 Valid options: |
| 1016 --force : force update even for unchanged modules |
| 1017 --nohooks : don't run the hooks after the update is complete |
| 1018 --revision SOLUTION@REV : update given solution to specified revision |
| 1019 --deps PLATFORM(S) : sync deps for the given platform(s), or 'all' |
| 1020 --verbose : output additional diagnostics |
| 1021 --head : update to latest revision, instead of last good |
| 1022 revision |
| 1023 --reset : resets any local changes before updating (git only) |
| 1024 |
| 1025 Examples: |
| 1026 gclient sync |
| 1027 update files from SCM according to current configuration, |
| 1028 *for modules which have changed since last update or sync* |
| 1029 gclient sync --force |
| 1030 update files from SCM according to current configuration, for |
| 1031 all modules (useful for recovering files deleted from local copy) |
| 1032 gclient sync --revision src@31000 |
| 1033 update src directory to r31000 |
| 1034 """ |
| 1119 client = GClient.LoadCurrentConfig(options) | 1035 client = GClient.LoadCurrentConfig(options) |
| 1120 | 1036 |
| 1121 if not client: | 1037 if not client: |
| 1122 raise gclient_utils.Error("client not configured; see 'gclient config'") | 1038 raise gclient_utils.Error("client not configured; see 'gclient config'") |
| 1123 | 1039 |
| 1124 if not options.head: | 1040 if not options.head: |
| 1125 solutions = client.GetVar('solutions') | 1041 solutions = client.GetVar('solutions') |
| 1126 if solutions: | 1042 if solutions: |
| 1127 for s in solutions: | 1043 for s in solutions: |
| 1128 if s.get('safesync_url', ''): | 1044 if s.get('safesync_url', ''): |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1141 if len(rev): | 1057 if len(rev): |
| 1142 options.revisions.append(s['name']+'@'+rev) | 1058 options.revisions.append(s['name']+'@'+rev) |
| 1143 | 1059 |
| 1144 if options.verbose: | 1060 if options.verbose: |
| 1145 # Print out the .gclient file. This is longer than if we just printed the | 1061 # Print out the .gclient file. This is longer than if we just printed the |
| 1146 # client dict, but more legible, and it might contain helpful comments. | 1062 # client dict, but more legible, and it might contain helpful comments. |
| 1147 print(client.ConfigContent()) | 1063 print(client.ConfigContent()) |
| 1148 return client.RunOnDeps('update', args) | 1064 return client.RunOnDeps('update', args) |
| 1149 | 1065 |
| 1150 | 1066 |
| 1151 def DoDiff(options, args): | 1067 def CMDupdate(options, args): |
| 1152 """Handle the diff subcommand. | 1068 """Alias for the sync command. Deprecated. |
| 1069 """ |
| 1070 return CMDsync(options, args) |
| 1153 | 1071 |
| 1154 Raises: | 1072 |
| 1155 Error: if client isn't configured properly. | 1073 def CMDdiff(options, args): |
| 1156 """ | 1074 """Display the differences between two revisions of modules. |
| 1075 (Does 'svn diff' for each checked out module and dependences.) |
| 1076 Additional args and options to 'svn diff' can be passed after |
| 1077 gclient options. |
| 1078 |
| 1079 usage: diff [options] [--] [svn args/options] |
| 1080 |
| 1081 Valid options: |
| 1082 --verbose : output additional diagnostics |
| 1083 |
| 1084 Examples: |
| 1085 gclient diff |
| 1086 simple 'svn diff' for configured client and dependences |
| 1087 gclient diff -- -x -b |
| 1088 use 'svn diff -x -b' to suppress whitespace-only differences |
| 1089 gclient diff -- -r HEAD -x -b |
| 1090 diff versus the latest version of each module |
| 1091 """ |
| 1157 client = GClient.LoadCurrentConfig(options) | 1092 client = GClient.LoadCurrentConfig(options) |
| 1158 if not client: | 1093 if not client: |
| 1159 raise gclient_utils.Error("client not configured; see 'gclient config'") | 1094 raise gclient_utils.Error("client not configured; see 'gclient config'") |
| 1160 if options.verbose: | 1095 if options.verbose: |
| 1161 # Print out the .gclient file. This is longer than if we just printed the | 1096 # Print out the .gclient file. This is longer than if we just printed the |
| 1162 # client dict, but more legible, and it might contain helpful comments. | 1097 # client dict, but more legible, and it might contain helpful comments. |
| 1163 print(client.ConfigContent()) | 1098 print(client.ConfigContent()) |
| 1164 return client.RunOnDeps('diff', args) | 1099 return client.RunOnDeps('diff', args) |
| 1165 | 1100 |
| 1166 | 1101 |
| 1167 def DoRevert(options, args): | 1102 def CMDrevert(options, args): |
| 1168 """Handle the revert subcommand. | 1103 """Revert every file in every managed directory in the client view. |
| 1169 | 1104 """ |
| 1170 Raises: | |
| 1171 Error: if client isn't configured properly. | |
| 1172 """ | |
| 1173 client = GClient.LoadCurrentConfig(options) | 1105 client = GClient.LoadCurrentConfig(options) |
| 1174 if not client: | 1106 if not client: |
| 1175 raise gclient_utils.Error("client not configured; see 'gclient config'") | 1107 raise gclient_utils.Error("client not configured; see 'gclient config'") |
| 1176 return client.RunOnDeps('revert', args) | 1108 return client.RunOnDeps('revert', args) |
| 1177 | 1109 |
| 1178 | 1110 |
| 1179 def DoRunHooks(options, args): | 1111 def CMDrunhooks(options, args): |
| 1180 """Handle the runhooks subcommand. | 1112 """Runs hooks for files that have been modified in the local working copy, |
| 1113 according to 'svn status'. Implies --force. |
| 1181 | 1114 |
| 1182 Raises: | 1115 usage: runhooks [options] |
| 1183 Error: if client isn't configured properly. | 1116 |
| 1184 """ | 1117 Valid options: |
| 1118 --verbose : output additional diagnostics |
| 1119 """ |
| 1185 client = GClient.LoadCurrentConfig(options) | 1120 client = GClient.LoadCurrentConfig(options) |
| 1186 if not client: | 1121 if not client: |
| 1187 raise gclient_utils.Error("client not configured; see 'gclient config'") | 1122 raise gclient_utils.Error("client not configured; see 'gclient config'") |
| 1188 if options.verbose: | 1123 if options.verbose: |
| 1189 # Print out the .gclient file. This is longer than if we just printed the | 1124 # Print out the .gclient file. This is longer than if we just printed the |
| 1190 # client dict, but more legible, and it might contain helpful comments. | 1125 # client dict, but more legible, and it might contain helpful comments. |
| 1191 print(client.ConfigContent()) | 1126 print(client.ConfigContent()) |
| 1192 options.force = True | 1127 options.force = True |
| 1193 return client.RunOnDeps('runhooks', args) | 1128 return client.RunOnDeps('runhooks', args) |
| 1194 | 1129 |
| 1195 | 1130 |
| 1196 def DoRevInfo(options, args): | 1131 def CMDrevinfo(options, args): |
| 1197 """Handle the revinfo subcommand. | 1132 """Outputs source path, server URL and revision information for every |
| 1133 dependency in all solutions. |
| 1198 | 1134 |
| 1199 Raises: | 1135 usage: revinfo [options] |
| 1200 Error: if client isn't configured properly. | 1136 """ |
| 1201 """ | |
| 1202 __pychecker__ = 'unusednames=args' | 1137 __pychecker__ = 'unusednames=args' |
| 1203 client = GClient.LoadCurrentConfig(options) | 1138 client = GClient.LoadCurrentConfig(options) |
| 1204 if not client: | 1139 if not client: |
| 1205 raise gclient_utils.Error("client not configured; see 'gclient config'") | 1140 raise gclient_utils.Error("client not configured; see 'gclient config'") |
| 1206 client.PrintRevInfo() | 1141 client.PrintRevInfo() |
| 1142 return 0 |
| 1207 | 1143 |
| 1208 | 1144 |
| 1209 gclient_command_map = { | 1145 def DispatchCommand(command, options, args): |
| 1210 "cleanup": DoCleanup, | 1146 """Dispatches the appropriate subcommand based on command line arguments. |
| 1211 "config": DoConfig, | 1147 """ |
| 1212 "diff": DoDiff, | 1148 module = sys.modules[__name__] |
| 1213 "export": DoExport, | 1149 command = getattr(module, 'CMD' + command, None) |
| 1214 "help": DoHelp, | 1150 if command: |
| 1215 "pack": DoPack, | 1151 return command(options, args) |
| 1216 "status": DoStatus, | |
| 1217 "sync": DoUpdate, | |
| 1218 "update": DoUpdate, | |
| 1219 "revert": DoRevert, | |
| 1220 "runhooks": DoRunHooks, | |
| 1221 "revinfo" : DoRevInfo, | |
| 1222 } | |
| 1223 | |
| 1224 | |
| 1225 def DispatchCommand(command, options, args, command_map=None): | |
| 1226 """Dispatches the appropriate subcommand based on command line arguments.""" | |
| 1227 if command_map is None: | |
| 1228 command_map = gclient_command_map | |
| 1229 | |
| 1230 if command in command_map: | |
| 1231 return command_map[command](options, args) | |
| 1232 else: | 1152 else: |
| 1233 raise gclient_utils.Error("unknown subcommand '%s'; see 'gclient help'" % | 1153 raise gclient_utils.Error("unknown subcommand '%s'; see 'gclient help'" % |
| 1234 command) | 1154 command) |
| 1235 | 1155 |
| 1236 | 1156 |
| 1237 def Main(argv): | 1157 def Main(argv): |
| 1238 """Parse command line arguments and dispatch command.""" | |
| 1239 | |
| 1240 option_parser = optparse.OptionParser(usage=DEFAULT_USAGE_TEXT, | 1158 option_parser = optparse.OptionParser(usage=DEFAULT_USAGE_TEXT, |
| 1241 version=__version__) | 1159 version=__version__) |
| 1242 option_parser.disable_interspersed_args() | 1160 option_parser.disable_interspersed_args() |
| 1243 option_parser.add_option("", "--force", action="store_true", default=False, | 1161 option_parser.add_option("", "--force", action="store_true", default=False, |
| 1244 help=("(update/sync only) force update even " | 1162 help=("(update/sync only) force update even " |
| 1245 "for modules which haven't changed")) | 1163 "for modules which haven't changed")) |
| 1246 option_parser.add_option("", "--nohooks", action="store_true", default=False, | 1164 option_parser.add_option("", "--nohooks", action="store_true", default=False, |
| 1247 help=("(update/sync/revert only) prevent the hooks fr
om " | 1165 help=("(update/sync/revert only) prevent the hooks fr
om " |
| 1248 "running")) | 1166 "running")) |
| 1249 option_parser.add_option("", "--revision", action="append", dest="revisions", | 1167 option_parser.add_option("", "--revision", action="append", dest="revisions", |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1321 | 1239 |
| 1322 if "__main__" == __name__: | 1240 if "__main__" == __name__: |
| 1323 try: | 1241 try: |
| 1324 result = Main(sys.argv) | 1242 result = Main(sys.argv) |
| 1325 except gclient_utils.Error, e: | 1243 except gclient_utils.Error, e: |
| 1326 print >> sys.stderr, "Error: %s" % str(e) | 1244 print >> sys.stderr, "Error: %s" % str(e) |
| 1327 result = 1 | 1245 result = 1 |
| 1328 sys.exit(result) | 1246 sys.exit(result) |
| 1329 | 1247 |
| 1330 # vim: ts=2:sw=2:tw=80:et: | 1248 # vim: ts=2:sw=2:tw=80:et: |
| OLD | NEW |