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

Side by Side Diff: tools/licenses.py

Issue 10816041: Add a tool to check license compatibility with Android (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Update regex Created 8 years, 5 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
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2012 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 """Utility for checking and processing licensing information in third_party 6 """Utility for checking and processing licensing information in third_party
7 directories. 7 directories.
8 8
9 Usage: licenses.py <command> 9 Usage: licenses.py <command>
10 10
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 if filename.startswith('/'): 166 if filename.startswith('/'):
167 # Absolute-looking paths are relative to the source root 167 # Absolute-looking paths are relative to the source root
168 # (which is the directory we're run from). 168 # (which is the directory we're run from).
169 absolute_path = os.path.join(os.getcwd(), filename[1:]) 169 absolute_path = os.path.join(os.getcwd(), filename[1:])
170 else: 170 else:
171 absolute_path = os.path.join(path, filename) 171 absolute_path = os.path.join(path, filename)
172 if os.path.exists(absolute_path): 172 if os.path.exists(absolute_path):
173 return absolute_path 173 return absolute_path
174 return None 174 return None
175 175
176 def ParseDir(path): 176 def ParseDir(path, raise_on_error):
177 """Examine a third_party/foo component and extract its metadata.""" 177 """Examine a third_party/foo component and extract its metadata.
178 Args:
179 path the path to the component to examine
180 raise_on_error whether to raise an exception if an error occurs
181 Returns:
182 metadata for the component
183 """
178 184
179 # Parse metadata fields out of README.chromium. 185 # Parse metadata fields out of README.chromium.
180 # We examine "LICENSE" for the license file by default. 186 # We examine "LICENSE" for the license file by default.
181 metadata = { 187 metadata = {
182 "License File": "LICENSE", # Relative path to license text. 188 "License File": "LICENSE", # Relative path to license text.
183 "Name": None, # Short name (for header on about:credits). 189 "Name": None, # Short name (for header on about:credits).
184 "URL": None, # Project home page. 190 "URL": None, # Project home page.
185 } 191 }
186 192
187 # Relative path to a file containing some html we're required to place in 193 # Relative path to a file containing some html we're required to place in
188 # about:credits. 194 # about:credits.
189 optional_keys = ["Required Text"] 195 optional_keys = ["Required Text"]
190 196
191 if path in SPECIAL_CASES: 197 if path in SPECIAL_CASES:
192 metadata.update(SPECIAL_CASES[path]) 198 metadata.update(SPECIAL_CASES[path])
193 else: 199 else:
194 # Try to find README.chromium. 200 # Try to find README.chromium.
195 readme_path = os.path.join(path, 'README.chromium') 201 readme_path = os.path.join(path, 'README.chromium')
196 if not os.path.exists(readme_path): 202 if not os.path.exists(readme_path):
197 raise LicenseError("missing README.chromium") 203 if raise_on_error:
198 204 raise LicenseError("missing README.chromium")
199 for line in open(readme_path): 205 else:
200 line = line.strip() 206 for line in open(readme_path):
201 if not line: 207 line = line.strip()
202 break 208 if not line:
203 for key in metadata.keys() + optional_keys: 209 break
204 field = key + ": " 210 for key in metadata.keys() + optional_keys:
205 if line.startswith(field): 211 field = key + ": "
206 metadata[key] = line[len(field):] 212 if line.startswith(field):
213 metadata[key] = line[len(field):]
207 214
208 # Check that all expected metadata is present. 215 # Check that all expected metadata is present.
209 for key, value in metadata.iteritems(): 216 if raise_on_error:
210 if not value: 217 for key, value in metadata.iteritems():
211 raise LicenseError("couldn't find '" + key + "' line " 218 if not value:
212 "in README.chromium or licences.py " 219 raise LicenseError("couldn't find '" + key + "' line "
213 "SPECIAL_CASES") 220 "in README.chromium or licences.py "
221 "SPECIAL_CASES")
214 222
215 # Check that the license file exists. 223 # Check that the license file exists.
216 for filename in (metadata["License File"], "COPYING"): 224 for filename in (metadata["License File"], "COPYING"):
217 license_path = AbsolutePath(path, filename) 225 license_path = AbsolutePath(path, filename)
218 if license_path is not None: 226 if license_path is not None:
219 metadata["License File"] = license_path 227 metadata["License File"] = license_path
220 break 228 break
221 229
222 if not license_path: 230 if raise_on_error and not license_path:
223 raise LicenseError("License file not found. " 231 raise LicenseError("License file not found. "
224 "Either add a file named LICENSE, " 232 "Either add a file named LICENSE, "
225 "import upstream's COPYING if available, " 233 "import upstream's COPYING if available, "
226 "or add a 'License File:' line to README.chromium " 234 "or add a 'License File:' line to README.chromium "
227 "with the appropriate path.") 235 "with the appropriate path.")
228 236
229 if "Required Text" in metadata: 237 if "Required Text" in metadata:
230 required_path = AbsolutePath(path, metadata["Required Text"]) 238 required_path = AbsolutePath(path, metadata["Required Text"])
231 if required_path is not None: 239 if required_path is not None:
232 metadata["Required Text"] = required_path 240 metadata["Required Text"] = required_path
233 else: 241 elif raise_on_error:
234 raise LicenseError("Required text file listed but not found.") 242 raise LicenseError("Required text file listed but not found.")
235 243
236 return metadata 244 return metadata
237 245
238 246
239 def FindThirdPartyDirs(): 247 def FindThirdPartyDirs():
240 """Find all third_party directories underneath the current directory.""" 248 """Find all third_party directories underneath the current directory."""
241 third_party_dirs = [] 249 third_party_dirs = []
242 for path, dirs, files in os.walk('.'): 250 for path, dirs, files in os.walk('.'):
243 path = path[len('./'):] # Pretty up the path. 251 path = path[len('./'):] # Pretty up the path.
(...skipping 26 matching lines...) Expand all
270 return third_party_dirs 278 return third_party_dirs
271 279
272 280
273 def ScanThirdPartyDirs(): 281 def ScanThirdPartyDirs():
274 """Scan a list of directories and report on any problems we find.""" 282 """Scan a list of directories and report on any problems we find."""
275 third_party_dirs = FindThirdPartyDirs() 283 third_party_dirs = FindThirdPartyDirs()
276 284
277 errors = [] 285 errors = []
278 for path in sorted(third_party_dirs): 286 for path in sorted(third_party_dirs):
279 try: 287 try:
280 metadata = ParseDir(path) 288 metadata = ParseDir(path, True)
Evan Martin 2012/07/24 19:41:28 Consider something like: ParseDir(path, raise_on
Steve Block 2012/07/24 21:20:58 Regarding a try block, this approach doesn't work
281 except LicenseError, e: 289 except LicenseError, e:
282 errors.append((path, e.args[0])) 290 errors.append((path, e.args[0]))
283 continue 291 continue
284 292
285 for path, error in sorted(errors): 293 for path, error in sorted(errors):
286 print path + ": " + error 294 print path + ": " + error
287 295
288 return len(errors) == 0 296 return len(errors) == 0
289 297
290 298
291 def GenerateCredits(): 299 def GenerateCredits():
292 """Generate about:credits, dumping the result to stdout.""" 300 """Generate about:credits, dumping the result to stdout."""
293 301
294 def EvaluateTemplate(template, env, escape=True): 302 def EvaluateTemplate(template, env, escape=True):
295 """Expand a template with variables like {{foo}} using a 303 """Expand a template with variables like {{foo}} using a
296 dictionary of expansions.""" 304 dictionary of expansions."""
297 for key, val in env.items(): 305 for key, val in env.items():
298 if escape and not key.endswith("_unescaped"): 306 if escape and not key.endswith("_unescaped"):
299 val = cgi.escape(val) 307 val = cgi.escape(val)
300 template = template.replace('{{%s}}' % key, val) 308 template = template.replace('{{%s}}' % key, val)
301 return template 309 return template
302 310
303 third_party_dirs = FindThirdPartyDirs() 311 third_party_dirs = FindThirdPartyDirs()
304 312
305 entry_template = open('chrome/browser/resources/about_credits_entry.tmpl', 313 entry_template = open('chrome/browser/resources/about_credits_entry.tmpl',
306 'rb').read() 314 'rb').read()
307 entries = [] 315 entries = []
308 for path in sorted(third_party_dirs): 316 for path in sorted(third_party_dirs):
309 try: 317 try:
310 metadata = ParseDir(path) 318 metadata = ParseDir(path, True)
311 except LicenseError: 319 except LicenseError:
312 print >>sys.stderr, ("WARNING: licensing info for " + path + 320 print >>sys.stderr, ("WARNING: licensing info for " + path +
313 " is incomplete, skipping.") 321 " is incomplete, skipping.")
314 continue 322 continue
315 env = { 323 env = {
316 'name': metadata['Name'], 324 'name': metadata['Name'],
317 'url': metadata['URL'], 325 'url': metadata['URL'],
318 'license': open(metadata['License File'], 'rb').read(), 326 'license': open(metadata['License File'], 'rb').read(),
319 'license_unescaped': '', 327 'license_unescaped': '',
320 } 328 }
(...skipping 20 matching lines...) Expand all
341 elif command == 'credits': 349 elif command == 'credits':
342 if not GenerateCredits(): 350 if not GenerateCredits():
343 return 1 351 return 1
344 else: 352 else:
345 print __doc__ 353 print __doc__
346 return 1 354 return 1
347 355
348 356
349 if __name__ == '__main__': 357 if __name__ == '__main__':
350 sys.exit(main()) 358 sys.exit(main())
OLDNEW
« android_webview/tools/webview_licenses.py ('K') | « android_webview/tools/webview_licenses.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698