OLD | NEW |
---|---|
(Empty) | |
1 # Copyright 2015 The Chromium Authors. All rights reserved. | |
2 # Use of this source code is governed by a BSD-style license that can be | |
3 # found in the LICENSE file. | |
4 | |
5 | |
6 import os | |
7 import shutil | |
8 import tempfile | |
9 | |
10 | |
11 from infra.tools.cros_pin import execute | |
12 from infra.tools.cros_pin.logger import LOGGER | |
13 | |
14 | |
15 class Checkout(object): | |
ghost stip (do not use)
2015/10/15 20:02:54
can you make this a context manager?
just add __e
dnj
2015/10/15 21:06:41
Yeah! I kind of have something going like that in
| |
16 """Checkout is a managed root checkout directory.""" | |
17 | |
18 GCLIENT_TEMPLATE = """ | |
19 solutions = [ | |
20 { | |
21 "url": "https://chromium.googlesource.com/chromium/tools/build.git", | |
22 "managed": False, | |
23 "name": "build", | |
24 "deps_file": ".DEPS.git", | |
25 }, | |
26 { | |
27 "url": "https://chrome-internal.googlesource.com/chrome/tools/build.git", | |
28 "managed": False, | |
29 "name": "build_internal", | |
30 "deps_file": ".DEPS.git", | |
31 }, | |
32 ] | |
33 """ | |
34 | |
35 def __init__(self, path, delete=False): | |
36 self._path = path | |
37 self._delete = delete | |
38 | |
39 @property | |
40 def path(self): | |
41 return self._path | |
42 | |
43 def subpath(self, *components): | |
44 return os.path.join(self._path, *components) | |
45 | |
46 def teardown(self): | |
47 if self._delete: | |
48 self._destroy_directory(self._path) | |
49 | |
50 @classmethod | |
51 def create(cls, path=None): | |
52 """Creates a new Checkout using the specified path. | |
53 | |
54 Args: | |
55 path (str): The path of the checkout to use. If None, a temporary | |
56 checkout will be created. | |
57 """ | |
58 delete = False | |
59 if path: | |
60 if os.path.isdir(path): | |
61 return cls(path, delete=False) | |
62 os.makedirs(path) | |
63 else: | |
64 path = tempfile.mkdtemp(prefix='tmp_cros_pin') | |
65 delete = True | |
66 | |
67 try: | |
68 cls.fetch(path) | |
69 c = cls(path, delete=delete) | |
70 path = None # Signal our "finally" clause not to clean up here. | |
71 finally: | |
72 if path: | |
73 cls._destroy_directory(path) | |
74 return c | |
75 | |
76 @classmethod | |
77 def fetch(cls, path): | |
78 LOGGER.info("Fetching => %s (This can take a while.)", path) | |
79 gclient_path = os.path.join(path, '.gclient') | |
80 with open(gclient_path, 'w') as fd: | |
81 fd.write(cls.GCLIENT_TEMPLATE) | |
82 | |
83 execute.check_call( | |
84 ['gclient', 'sync', '--nohooks', '--noprehooks'], | |
85 cwd=path) | |
86 | |
87 @staticmethod | |
88 def _destroy_directory(d): | |
89 LOGGER.debug('Destorying directory: %s', d) | |
90 def log_failure(_function, path, excinfo): | |
91 LOGGER.warning('Failed when destroying [%s]: %s', | |
92 path, excinfo[1].message) | |
93 shutil.rmtree(d, onerror=log_failure) | |
OLD | NEW |