blob: 0cc5b4c2dab8daf975d9781e1786a86ad4de1726 [file] [log] [blame]
#!/usr/bin/env python
#
# Copyright 2017 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# A script to fetch missing LICENSE files when building a vendored repo
# Should be run from top-level of third_party/rust_crates repository.
import argparse
import os
import re
import sys
import urllib2
repo_re = re.compile('\s*repository\s*=\s*"(.*)"\s*$')
def die(reason):
raise Exception(reason)
def get_repo_path(subdir):
for line in open(os.path.join(subdir, 'Cargo.toml')):
m = repo_re.match(line)
if m:
return m.group(1)
def find_github_blob_path(path):
s = path.split('/')
if s[2] == 'github.com':
s[2] = 'raw.githubusercontent.com'
# github redirects "github.com/$USER/$PROJECT.git" to
# "github.com/$USER/$PROJECT".
if s[4].endswith('.git'):
s[4] = s[4][:len('.git')]
else:
die('don\'t know raw content path for ' + path)
if s[-1] == '':
del s[-1]
if len(s) >= 6 and s[5] == 'tree':
del s[5]
else:
s.append('master')
return '/'.join(s)
def fetch_license(subdir):
repo_path = get_repo_path(subdir)
if repo_path is None:
die('can\'t find repo path for ' + subdir)
baseurl = find_github_blob_path(repo_path)
text = []
# 'LICENCE' is a British English spelling variant used in https://github.com/ebarnard/rust-plist
for license_filename in ('LICENSE', 'LICENSE-APACHE', 'LICENSE-MIT', 'COPYING', 'LICENCE', 'LICENSE.md'):
url = '/'.join((baseurl, license_filename))
try:
resp = urllib2.urlopen(url)
contents = resp.read()
if text: text.append('=' * 40 + '\n')
text.append(url + ':\n\n')
text.append(contents)
except urllib2.HTTPError:
pass
if not text:
die('no licenses found under ' + baseurl)
else:
license_out = open(os.path.join(subdir, 'LICENSE'), 'w')
license_out.write(''.join(text))
def check_licenses(directory, verify=False):
success = True
os.chdir(directory)
for subdir in sorted(os.listdir(os.getcwd())):
# TODO(pylaligand): remove this temporary hack when a new version of
# the crate is published.
if (subdir.startswith('magenta-sys') or
subdir.startswith('fuchsia-zircon-sys')):
print 'IGNORED %s' % subdir
continue
if subdir.startswith('.') or not os.path.isdir(subdir):
continue
license_files = [file for file in os.listdir(subdir)
if file.startswith('LICENSE') or
file.startswith('LICENCE') or
file.startswith('license')]
if license_files:
print 'OK %s' % subdir
continue
if verify:
print 'MISSING %s' % subdir
success = False
continue
try:
fetch_license(subdir)
print 'FETCH %s' % subdir
except Exception as err:
print 'ERROR %s (%s)' % (subdir, err.message)
success = False
return success
def main():
parser = argparse.ArgumentParser(
'Verifies licenses for third-party Rust crates')
parser.add_argument('--directory',
help='Directory containing the crates',
default=os.getcwd())
parser.add_argument('--verify',
help='Simply check whether licenses are up-to-date',
action='store_true')
args = parser.parse_args()
if not check_licenses(args.directory, verify=args.verify):
sys.exit(1)
if __name__ == '__main__':
main()