OLD | NEW |
---|---|
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (c) 2013 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2013 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 """ | 6 """ |
7 Tool to perform checkouts in one easy command line! | 7 Tool to perform checkouts in one easy command line! |
8 | 8 |
9 Usage: | 9 Usage: |
10 fetch <recipe> [--property=value [--property2=value2 ...]] | 10 fetch <recipe> [--property=value [--property2=value2 ...]] |
11 | 11 |
12 This script is a wrapper around various version control and repository | 12 This script is a wrapper around various version control and repository |
13 checkout commands. It requires a |recipe| name, fetches data from that | 13 checkout commands. It requires a |recipe| name, fetches data from that |
14 recipe in depot_tools/recipes, and then performs all necessary inits, | 14 recipe in depot_tools/recipes, and then performs all necessary inits, |
15 checkouts, pulls, fetches, etc. | 15 checkouts, pulls, fetches, etc. |
16 | 16 |
17 Optional arguments may be passed on the command line in key-value pairs. | 17 Optional arguments may be passed on the command line in key-value pairs. |
18 These parameters will be passed through to the recipe's main method. | 18 These parameters will be passed through to the recipe's main method. |
19 """ | 19 """ |
20 | 20 |
21 import json | 21 import json |
22 import os | 22 import os |
23 import subprocess | 23 import subprocess |
24 import sys | 24 import sys |
25 import pipes | 25 import pipes |
26 | 26 |
27 from distutils import spawn | |
28 | |
27 | 29 |
28 SCRIPT_PATH = os.path.dirname(os.path.abspath(__file__)) | 30 SCRIPT_PATH = os.path.dirname(os.path.abspath(__file__)) |
29 | 31 |
30 | 32 |
31 ################################################# | 33 ################################################# |
32 # Checkout class definitions. | 34 # Checkout class definitions. |
33 ################################################# | 35 ################################################# |
34 class Checkout(object): | 36 class Checkout(object): |
35 """Base class for implementing different types of checkouts. | 37 """Base class for implementing different types of checkouts. |
36 | 38 |
37 Attributes: | 39 Attributes: |
38 |base|: the absolute path of the directory in which this script is run. | 40 |base|: the absolute path of the directory in which this script is run. |
39 |spec|: the spec for this checkout as returned by the recipe. Different | 41 |spec|: the spec for this checkout as returned by the recipe. Different |
40 subclasses will expect different keys in this dictionary. | 42 subclasses will expect different keys in this dictionary. |
41 |root|: the directory into which the checkout will be performed, as returned | 43 |root|: the directory into which the checkout will be performed, as returned |
42 by the recipe. This is a relative path from |base|. | 44 by the recipe. This is a relative path from |base|. |
43 """ | 45 """ |
44 def __init__(self, dryrun, spec, root): | 46 def __init__(self, dryrun, spec, root): |
45 self.base = os.getcwd() | 47 self.base = os.getcwd() |
46 self.dryrun = dryrun | 48 self.dryrun = dryrun |
47 self.spec = spec | 49 self.spec = spec |
48 self.root = root | 50 self.root = root |
51 self._script_paths = {} | |
52 self._binary_paths = {} | |
49 | 53 |
50 def exists(self): | 54 def exists(self): |
51 pass | 55 pass |
52 | 56 |
53 def init(self): | 57 def init(self): |
54 pass | 58 pass |
55 | 59 |
56 def sync(self): | 60 def sync(self): |
57 pass | 61 pass |
58 | 62 |
63 @staticmethod | |
64 def _find_executable(binary_name): | |
65 exe_name = binary_name + '.exe' if sys.platform == 'win32' else binary_name | |
66 path = spawn.find_executable(exe_name) | |
67 if path: | |
68 return path | |
69 return spawn.find_executable(os.path.join(SCRIPT_PATH, binary_name + '_bin', | |
agable
2013/04/11 18:21:09
Isn't git installed to depot_tools\git-1.8.0_bin\
| |
70 exe_name)) | |
71 | |
72 def run_script(self, script, *args, **kwargs): | |
73 path = self._script_paths.get(script) | |
74 if not path: | |
75 path = os.path.join(SCRIPT_PATH, script + '.py') | |
76 if not os.path.exists(path): | |
77 print "Error: could not find '%s.py' in depot_tools" % script | |
78 return 1 | |
79 self._script_paths[script] = path | |
80 print 'Running: %s %s' % (script, | |
81 ' '.join(pipes.quote(arg) for arg in args)) | |
82 if self.dryrun: | |
83 return 0 | |
84 return subprocess.check_call((sys.executable, path) + args, **kwargs) | |
85 | |
86 def run_binary(self, binary_name, *args, **kwargs): | |
87 path = self._binary_paths.get(binary_name) | |
88 if not path: | |
89 path = self._find_executable(binary_name) | |
90 if not path: | |
91 print "Error: could not find '%s' in PATH" % binary_name | |
92 return 1 | |
93 self._binary_paths[binary_name] = path | |
94 print 'Running: %s %s' % (binary_name, | |
95 ' '.join(pipes.quote(arg) for arg in args)) | |
96 if self.dryrun: | |
97 return 0 | |
98 return subprocess.check_call((path,) + args, **kwargs) | |
99 | |
59 | 100 |
60 class GclientCheckout(Checkout): | 101 class GclientCheckout(Checkout): |
61 | 102 def run_gclient(self, *args, **kwargs): |
62 def run_gclient(self, *cmd, **kwargs): | 103 return self.run_script('gclient', *args, **kwargs) |
63 print 'Running: gclient %s' % ' '.join(pipes.quote(x) for x in cmd) | |
64 if not self.dryrun: | |
65 return subprocess.check_call( | |
66 (sys.executable, os.path.join(SCRIPT_PATH, 'gclient.py')) + cmd, | |
67 **kwargs) | |
68 | 104 |
69 | 105 |
70 class GitCheckout(Checkout): | 106 class GitCheckout(Checkout): |
71 | 107 def run_git(self, *args, **kwargs): |
72 def run_git(self, *cmd, **kwargs): | 108 return self.run_binary('git', *args, **kwargs) |
73 print 'Running: git %s' % ' '.join(pipes.quote(x) for x in cmd) | |
74 if not self.dryrun: | |
75 return subprocess.check_call(('git',) + cmd, **kwargs) | |
76 | 109 |
77 | 110 |
78 class SvnCheckout(Checkout): | 111 class SvnCheckout(Checkout): |
79 | 112 def run_svn(self, *args, **kwargs): |
80 def run_svn(self, *cmd, **kwargs): | 113 return self.run_binary('svn', *args, **kwargs) |
81 print 'Running: svn %s' % ' '.join(pipes.quote(x) for x in cmd) | |
82 if not self.dryrun: | |
83 return subprocess.check_call(('svn',) + cmd, **kwargs) | |
84 | 114 |
85 | 115 |
86 class GclientGitSvnCheckout(GclientCheckout, GitCheckout, SvnCheckout): | 116 class GclientGitSvnCheckout(GclientCheckout, GitCheckout, SvnCheckout): |
87 | 117 |
88 def __init__(self, dryrun, spec, root): | 118 def __init__(self, dryrun, spec, root): |
89 super(GclientGitSvnCheckout, self).__init__(dryrun, spec, root) | 119 super(GclientGitSvnCheckout, self).__init__(dryrun, spec, root) |
90 assert 'solutions' in self.spec | 120 assert 'solutions' in self.spec |
91 keys = ['solutions', 'target_os', 'target_os_only'] | 121 keys = ['solutions', 'target_os', 'target_os_only'] |
92 gclient_spec = '\n'.join('%s = %s' % (key, self.spec[key]) | 122 gclient_spec = '\n'.join('%s = %s' % (key, self.spec[key]) |
93 for key in self.spec if key in keys) | 123 for key in self.spec if key in keys) |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
244 | 274 |
245 | 275 |
246 def main(): | 276 def main(): |
247 dryrun, recipe, props = handle_args(sys.argv) | 277 dryrun, recipe, props = handle_args(sys.argv) |
248 spec, root = run_recipe_fetch(recipe, props) | 278 spec, root = run_recipe_fetch(recipe, props) |
249 return run(dryrun, spec, root) | 279 return run(dryrun, spec, root) |
250 | 280 |
251 | 281 |
252 if __name__ == '__main__': | 282 if __name__ == '__main__': |
253 sys.exit(main()) | 283 sys.exit(main()) |
OLD | NEW |