Upstream version 8.36.161.0
[platform/framework/web/crosswalk.git] / src / third_party / chromite / scripts / update_manifest_remotes.py
1 #!/usr/bin/python
2
3 # Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file.
6
7 """A tool that updates remotes in all historical manifests to point to GoB.
8
9 It clones manifest-versions repository, scans through all manifests there and
10 replaces known old gerrit/gerrit-int URLs with Gerrit on Borg ones.
11
12 It doesn't commit or push any changes, just updates files in a working
13 directory.
14 """
15
16 import collections
17 import os
18
19 from xml.etree import ElementTree
20
21 from chromite.buildbot import cbuildbot_config
22 from chromite.buildbot import manifest_version
23 from chromite.lib import commandline
24 from chromite.lib import cros_build_lib
25 from chromite.lib import osutils
26
27
28 GOB_EXTERNAL = "https://chromium.googlesource.com"
29 GOB_INTERNAL = "https://chrome-internal.googlesource.com"
30
31
32 GERRIT_EXTERNAL = "https://chromium-review.googlesource.com"
33 GERRIT_INTERNAL = "https://chrome-internal-review.googlesource.com"
34
35
36 # Old fetch URL -> new fetch URL.
37 # Old fetch urls are found by grepping through manifest-versions repo.
38 FETCH_URLS = {
39     'http://git.chromium.org': GOB_EXTERNAL,
40     'http://git.chromium.org/git': GOB_EXTERNAL,
41     'https://git.chromium.org/git': GOB_EXTERNAL,
42     'ssh://gerrit.chromium.org:29418': GOB_EXTERNAL,
43     'ssh://git@gitrw.chromium.org:9222': GOB_EXTERNAL,
44     'ssh://gerrit-int.chromium.org:29419': GOB_INTERNAL,
45 }
46
47
48 # Old review URL -> new review URL.
49 REVIEW_URLS = {
50     'gerrit.chromium.org/gerrit': GERRIT_EXTERNAL,
51     'gerrit-int.chromium.org': GERRIT_INTERNAL,
52 }
53
54
55 # Single remote entry in a manifest.
56 Remote = collections.namedtuple('Remote', ['name', 'fetch', 'review'])
57
58
59 def EnumerateManifests(directory):
60   """Yields paths to manifest files inside a directory."""
61   for path, directories, files in os.walk(directory):
62     # Find regular (not a symlink) xml files.
63     for name in files:
64       if not name.endswith('.xml'):
65         continue
66       full_path = os.path.join(path, name)
67       if os.path.isfile(full_path) and not os.path.islink(full_path):
68         yield full_path
69     # Skip 'hidden' directories.
70     for hidden in [name for name in directories if name.startswith('.')]:
71       directories.remove(hidden)
72
73
74 def UpdateRemotes(manifest):
75   """Updates remotes in manifest to use Gerrit on Borg URLs.
76
77   Args:
78     manifest: Path to manifest file to modify in place.
79
80   Returns:
81     True if file was modified.
82   """
83   # Read manifest file as str.
84   body = osutils.ReadFile(manifest)
85   original = body
86
87   # Update fetch="..." entries.
88   for old, new in FETCH_URLS.iteritems():
89     body = body.replace('fetch="%s"' % old, 'fetch="%s"' % new)
90
91   # Update review="..." entries.
92   for old, new in REVIEW_URLS.iteritems():
93     body = body.replace('review="%s"' % old, 'review="%s"' % new)
94
95   # Write back only if modified.
96   if original != body:
97     osutils.WriteFile(manifest, body)
98     return True
99
100   return False
101
102
103 def GetRemotes(manifest):
104   """Returns list of remotes referenced in manifest.
105
106   Args:
107     manifest: Path to manifest file to scan for remotes.
108
109   Returns:
110     List of Remote tuples.
111   """
112   doc = ElementTree.parse(manifest)
113   root = doc.getroot()
114   return [Remote(remote.attrib['name'], remote.attrib['fetch'],
115       remote.attrib.get('review')) for remote in root.findall('remote')]
116
117
118 def GetParser():
119   """Creates the argparse parser."""
120   parser = commandline.ArgumentParser(description=__doc__)
121   parser.add_argument('--skip-update', action='store_true', default=False,
122       help='Do not revert versions manifest checkout to original state')
123   parser.add_argument('--remotes-summary', action='store_true', default=False,
124       help='Scan all manifests and print all various remotes found in them')
125   parser.add_argument('manifest_versions_dir', type='path',
126       help='Directory to checkout manifest versions repository into')
127   return parser
128
129
130 def main(argv):
131   parser = GetParser()
132   options = parser.parse_args(argv)
133
134   # Clone manifest-versions repository.
135   manifest_repo_url = cbuildbot_config.GetManifestVersionsRepoUrl(
136       internal_build=True, read_only=False)
137   if not options.skip_update:
138     manifest_version.RefreshManifestCheckout(
139         options.manifest_versions_dir, manifest_repo_url)
140
141   if options.remotes_summary:
142     # Find all unique remotes.
143     cros_build_lib.Info('Scanning manifests for remotes...')
144     remotes = set()
145     for manifest in EnumerateManifests(options.manifest_versions_dir):
146       remotes.update(GetRemotes(manifest))
147     # Pretty print a table.
148     print 'Remotes found:'
149     row_formatter = lambda a, b, c: ''.join(
150         [a, ' ' * (16 - len(a)), b, ' ' * (45 - len(b)), c])
151     print row_formatter('Name', 'Remote', 'Review')
152     print '-' * 80
153     for remote in sorted(remotes):
154       print row_formatter(remote.name, remote.fetch, remote.review or '')
155     return 0
156
157   cros_build_lib.Info('Updating manifests...')
158   up_to_date = True
159   for manifest in EnumerateManifests(options.manifest_versions_dir):
160     if UpdateRemotes(manifest):
161       up_to_date = False
162       cros_build_lib.Info('Updated manifest: %s', manifest)
163
164   if up_to_date:
165     cros_build_lib.Info('All manifests are up to date')
166   else:
167     cros_build_lib.Info('Done')
168
169   return 0