1 # Copyright (c) 2014 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.
12 from common
import utils
15 _THIS_DIR
= os
.path
.abspath(os
.path
.dirname(__file__
))
16 CONFIG
= json
.loads(open(os
.path
.join(_THIS_DIR
,
17 'deps_config.json'), 'r').read())
18 OLD_GIT_URL_PATTERN
= re
.compile(r
'https?://git.chromium.org/(.*)')
21 class _VarImpl(object):
23 def __init__(self
, local_scope
):
24 self
._local
_scope
= local_scope
26 def Lookup(self
, var_name
):
27 if var_name
in self
._local
_scope
.get('vars', {}):
28 return self
._local
_scope
['vars'][var_name
]
29 raise Exception('Var is not defined: %s' % var_name
)
32 def _ParseDEPS(content
):
33 """Parse the DEPS file of chromium."""
35 var
= _VarImpl(local_scope
)
41 'skip_child_includes': [],
44 exec(content
, global_scope
, local_scope
)
46 local_scope
.setdefault('deps', {})
47 local_scope
.setdefault('deps_os', {})
49 return (local_scope
['deps'], local_scope
['deps_os'])
52 def _GetComponentName(path
, host_dirs
):
53 """Return the component name of a path."""
54 components_renamed
= {
58 for host_dir
in host_dirs
:
59 if path
.startswith(host_dir
):
60 path
= path
[len(host_dir
):]
61 name
= path
.split('/')[0].lower()
62 if name
in components_renamed
:
63 return components_renamed
[name
].lower()
67 # Unknown path, return the whole path as component name.
68 return '_'.join(path
.split('/'))
71 def _GetContentOfDEPS(revision
):
72 chromium_git_file_url_template
= CONFIG
['chromium_git_file_url']
74 # Try .DEPS.git first, because before migration from SVN to GIT, the .DEPS.git
75 # has the dependency in GIT repo while DEPS has dependency in SVN repo.
76 url
= chromium_git_file_url_template
% (revision
, '.DEPS.git')
77 http_status_code
, content
= utils
.GetHttpClient().Get(
78 url
, retries
=5, retry_if_not
=404)
80 # If .DEPS.git is not found, use DEPS, assuming it is a commit after migration
82 if http_status_code
== 404:
83 url
= chromium_git_file_url_template
% (revision
, 'DEPS')
84 http_status_code
, content
= utils
.GetHttpClient().Get(url
, retries
=5)
86 if http_status_code
== 200:
87 return base64
.b64decode(content
)
92 def GetChromiumComponents(chromium_revision
,
94 deps_file_downloader
=_GetContentOfDEPS
):
95 """Return a list of components used by Chrome of the given revision.
98 chromium_revision: Revision of the Chrome build: svn revision, or git hash.
99 os_platform: The target platform of the Chrome build, eg. win, mac, etc.
100 deps_file_downloader: A function that takes the chromium_revision as input,
101 and returns the content of the DEPS file. The returned
102 content is assumed to be trusted input and will be
103 evaluated as python code.
106 A map from component path to parsed component name, repository URL,
107 repository type and revision.
108 Return None if an error occurs.
110 if os_platform
.lower() == 'linux':
113 chromium_git_base_url
= CONFIG
['chromium_git_base_url']
115 if not utils
.IsGitHash(chromium_revision
):
116 # Convert svn revision or commit position to Git hash.
117 cr_rev_url_template
= CONFIG
['cr_rev_url']
118 url
= cr_rev_url_template
% chromium_revision
119 status_code
, content
= utils
.GetHttpClient().Get(
120 url
, timeout
=120, retries
=5, retry_if_not
=404)
121 if status_code
!= 200 or not content
:
122 if status_code
== 404:
123 print 'Chromium commit position %s is not found.' % chromium_revision
126 cr_rev_data
= json
.loads(content
)
127 if 'git_sha' not in cr_rev_data
:
130 if 'repo' not in cr_rev_data
or cr_rev_data
['repo'] != 'chromium/src':
131 print ('%s seems like a commit position of "%s", but not "chromium/src".'
132 % (chromium_revision
, cr_rev_data
['repo']))
135 chromium_revision
= cr_rev_data
.get('git_sha')
136 if not chromium_revision
:
139 # Download the content of DEPS file in chromium.
140 deps_content
= deps_file_downloader(chromium_revision
)
146 # Parse the content of DEPS file.
147 deps
, deps_os
= _ParseDEPS(deps_content
)
148 all_deps
.update(deps
)
149 if os_platform
is not None:
150 all_deps
.update(deps_os
.get(os_platform
, {}))
152 # Figure out components based on the dependencies.
154 host_dirs
= CONFIG
['host_directories']
155 for component_path
, component_repo_url
in all_deps
.iteritems():
156 if component_repo_url
is None:
157 # For some platform like iso, some component is ignored.
160 name
= _GetComponentName(component_path
, host_dirs
)
161 repository
, revision
= component_repo_url
.split('@')
162 match
= OLD_GIT_URL_PATTERN
.match(repository
)
164 repository
= 'https://chromium.googlesource.com/%s' % match
.group(1)
165 is_git_hash
= utils
.IsGitHash(revision
)
167 repository_type
= 'git'
169 repository_type
= 'svn'
170 if not component_path
.endswith('/'):
171 component_path
+= '/'
172 components
[component_path
] = {
173 'path': component_path
,
175 'repository': repository
,
176 'repository_type': repository_type
,
180 # Add chromium as a component.
181 components
['src/'] = {
184 'repository': chromium_git_base_url
,
185 'repository_type': 'git',
186 'revision': chromium_revision
192 def GetChromiumComponentRange(old_revision
,
195 deps_file_downloader
=_GetContentOfDEPS
):
196 """Return a list of components with their revision ranges.
199 old_revision: The old revision of a Chrome build.
200 new_revision: The new revision of a Chrome build.
201 os_platform: The target platform of the Chrome build, eg. win, mac, etc.
202 deps_file_downloader: A function that takes the chromium_revision as input,
203 and returns the content of the DEPS file. The returned
204 content is assumed to be trusted input and will be
205 evaluated as python code.
208 A map from component path to its parsed regression and other information.
209 Return None if an error occurs.
211 old_components
= GetChromiumComponents(old_revision
, os_platform
,
212 deps_file_downloader
)
213 if not old_components
:
216 new_components
= GetChromiumComponents(new_revision
, os_platform
,
217 deps_file_downloader
)
218 if not new_components
:
222 for path
in new_components
:
223 new_component
= new_components
[path
]
226 if path
in old_components
:
227 old_component
= old_components
[path
]
228 old_revision
= old_component
['revision']
232 'rolled': new_component
['revision'] != old_revision
,
233 'name': new_component
['name'],
234 'old_revision': old_revision
,
235 'new_revision': new_component
['revision'],
236 'repository': new_component
['repository'],
237 'repository_type': new_component
['repository_type']