Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(488)

Side by Side Diff: fetch.py

Issue 14093004: Ensure that we pick up 'git.bat' and 'svn.bat' on Windows. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools
Patch Set: fix typo on win, reformat, and clarify an unrelated TODO Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 = {}
53 self._binary_subdirs = {}
49 54
50 def exists(self): 55 def exists(self):
51 pass 56 pass
52 57
53 def init(self): 58 def init(self):
54 pass 59 pass
55 60
56 def sync(self): 61 def sync(self):
57 pass 62 pass
58 63
64 def _find_executable(self, binary_name):
65 if sys.platform == 'win32':
szager1 2013/04/11 21:30:01 This is unnecessary; spawn.find_executable will lo
Dirk Pranke 2013/04/11 21:52:08 Huh, so it does. That's great, as it simplifies th
66 exe_name = binary_name + '.exe'
67 else:
68 exe_name = binary_name
69 path = spawn.find_executable(exe_name)
70 if path:
71 return path
72 return spawn.find_executable(
szager1 2013/04/11 21:30:01 What's the purpose of this call? As far as I can
Dirk Pranke 2013/04/11 21:52:08 I thought that spawn.find_executable() does actual
szager1 2013/04/11 22:18:43 Whoops, should be: spawn.find_executable(binary_n
73 os.path.join(SCRIPT_PATH,
74 self._binary_subdirs[binary_name],
75 exe_name))
76
77 def run_script(self, script, *args, **kwargs):
78 path = self._script_paths.get(script)
79 if not path:
80 path = os.path.join(SCRIPT_PATH, script + '.py')
szager1 2013/04/11 21:30:01 path = os.path.join(SCRIPT_PATH, script) if not sc
Dirk Pranke 2013/04/11 21:52:08 Again, this is too general for my intentions.
81 if not os.path.exists(path):
82 print "Error: could not find '%s.py' in depot_tools" % script
83 return 1
84 self._script_paths[script] = path
85 print 'Running: %s %s' % (script,
86 ' '.join(pipes.quote(arg) for arg in args))
87 if self.dryrun:
88 return 0
89 return subprocess.check_call((sys.executable, path) + args, **kwargs)
90
91 def run_binary(self, binary_name, *args, **kwargs):
92 path = self._binary_paths.get(binary_name)
93 if not path:
94 path = self._find_executable(binary_name)
95 if not path:
96 print "Error: could not find '%s' in PATH" % binary_name
97 return 1
98 self._binary_paths[binary_name] = path
99 print 'Running: %s %s' % (binary_name,
100 ' '.join(pipes.quote(arg) for arg in args))
101 if self.dryrun:
102 return 0
103 return subprocess.check_call((path,) + args, **kwargs)
104
59 105
60 class GclientCheckout(Checkout): 106 class GclientCheckout(Checkout):
61 107 def run_gclient(self, *args, **kwargs):
62 def run_gclient(self, *cmd, **kwargs): 108 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 109
69 110
70 class GitCheckout(Checkout): 111 class GitCheckout(Checkout):
112 def __init__(self, *args, **kwargs):
113 super(GitCheckout, self).__init__(*args, **kwargs)
114 self._binary_subdirs['git'] = os.path.join('git-1.8.0_bin', 'bin')
szager1 2013/04/11 21:30:01 if sys.platform == 'win32': self._binary_subdirs
Dirk Pranke 2013/04/11 21:52:08 I'm not sure if you would still want me to make th
szager1 2013/04/11 22:18:43 Done.
71 115
72 def run_git(self, *cmd, **kwargs): 116 def run_git(self, *args, **kwargs):
73 print 'Running: git %s' % ' '.join(pipes.quote(x) for x in cmd) 117 return self.run_binary('git', *args, **kwargs)
74 if not self.dryrun:
75 return subprocess.check_call(('git',) + cmd, **kwargs)
76 118
77 119
78 class SvnCheckout(Checkout): 120 class SvnCheckout(Checkout):
121 def __init__(self, *args, **kwargs):
122 super(SvnCheckout, self).__init__(*args, **kwargs)
123 self._binary_subdirs['svn'] = 'svn_bin'
szager1 2013/04/11 21:30:01 if sys.platform == 'win32': ...
79 124
80 def run_svn(self, *cmd, **kwargs): 125 def run_svn(self, *args, **kwargs):
81 print 'Running: svn %s' % ' '.join(pipes.quote(x) for x in cmd) 126 return self.run_binary('svn', *args, **kwargs)
82 if not self.dryrun:
83 return subprocess.check_call(('svn',) + cmd, **kwargs)
84 127
85 128
86 class GclientGitSvnCheckout(GclientCheckout, GitCheckout, SvnCheckout): 129 class GclientGitSvnCheckout(GclientCheckout, GitCheckout, SvnCheckout):
87 130
88 def __init__(self, dryrun, spec, root): 131 def __init__(self, dryrun, spec, root):
89 super(GclientGitSvnCheckout, self).__init__(dryrun, spec, root) 132 super(GclientGitSvnCheckout, self).__init__(dryrun, spec, root)
90 assert 'solutions' in self.spec 133 assert 'solutions' in self.spec
91 keys = ['solutions', 'target_os', 'target_os_only'] 134 keys = ['solutions', 'target_os', 'target_os_only']
92 gclient_spec = '\n'.join('%s = %s' % (key, self.spec[key]) 135 gclient_spec = '\n'.join('%s = %s' % (key, self.spec[key])
93 for key in self.spec if key in keys) 136 for key in self.spec if key in keys)
94 self.spec['gclient_spec'] = gclient_spec 137 self.spec['gclient_spec'] = gclient_spec
95 assert 'svn_url' in self.spec 138 assert 'svn_url' in self.spec
96 assert 'svn_branch' in self.spec 139 assert 'svn_branch' in self.spec
97 assert 'svn_ref' in self.spec 140 assert 'svn_ref' in self.spec
98 141
99 def exists(self): 142 def exists(self):
100 return os.path.exists(os.path.join(os.getcwd(), self.root)) 143 return os.path.exists(os.path.join(os.getcwd(), self.root))
101 144
102 def init(self): 145 def init(self):
103 # Ensure we are authenticated with subversion for all submodules. 146 # Ensure we are authenticated with subversion for all submodules.
104 git_svn_dirs = json.loads(self.spec.get('submodule_git_svn_spec', '{}')) 147 git_svn_dirs = json.loads(self.spec.get('submodule_git_svn_spec', '{}'))
105 git_svn_dirs.update({self.root: self.spec}) 148 git_svn_dirs.update({self.root: self.spec})
106 for _, svn_spec in git_svn_dirs.iteritems(): 149 for _, svn_spec in git_svn_dirs.iteritems():
107 try: 150 try:
108 self.run_svn('ls', '--non-interactive', svn_spec['svn_url']) 151 self.run_svn('ls', '--non-interactive', svn_spec['svn_url'])
109 except subprocess.CalledProcessError: 152 except subprocess.CalledProcessError:
110 print 'Please run `svn ls %s`' % svn_spec['svn_url'] 153 print 'Please run `svn ls %s`' % svn_spec['svn_url']
111 return 1 154 return 1
112 155
113 # TODO(dpranke): Work around issues w/ delta compression on big repos. 156 # TODO(dpranke): This works around issues w/ delta compression on
157 # big repos. We should either not be setting this globally, or
158 # not need it at all, or both.
114 self.run_git('config', '--global', 'core.deltaBaseCacheLimit', '1G') 159 self.run_git('config', '--global', 'core.deltaBaseCacheLimit', '1G')
115 160
116 # Configure and do the gclient checkout. 161 # Configure and do the gclient checkout.
117 self.run_gclient('config', '--spec', self.spec['gclient_spec']) 162 self.run_gclient('config', '--spec', self.spec['gclient_spec'])
118 self.run_gclient('sync') 163 self.run_gclient('sync')
119 164
120 # Configure git. 165 # Configure git.
121 wd = os.path.join(self.base, self.root) 166 wd = os.path.join(self.base, self.root)
122 if self.dryrun: 167 if self.dryrun:
123 print 'cd %s' % wd 168 print 'cd %s' % wd
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 289
245 290
246 def main(): 291 def main():
247 dryrun, recipe, props = handle_args(sys.argv) 292 dryrun, recipe, props = handle_args(sys.argv)
248 spec, root = run_recipe_fetch(recipe, props) 293 spec, root = run_recipe_fetch(recipe, props)
249 return run(dryrun, spec, root) 294 return run(dryrun, spec, root)
250 295
251 296
252 if __name__ == '__main__': 297 if __name__ == '__main__':
253 sys.exit(main()) 298 sys.exit(main())
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698