
On master, we are removing all traces of Buck (Idb93a48345). To avoid recreating buck-cache when maintainers switch between stable branches, backport the directory renaming to stable-2.14 and later. Change-Id: Ia9c58bc5ac8fd28bac7ee220e917580b60f25a69 (cherry picked from commit 7788ae9cb2165d8d4f99e9cbdd1887ba3d201f41)
174 lines
5.0 KiB
Python
Executable File
174 lines
5.0 KiB
Python
Executable File
#!/usr/bin/env python
|
|
# Copyright (C) 2013 The Android Open Source Project
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
from __future__ import print_function
|
|
|
|
from hashlib import sha1
|
|
from optparse import OptionParser
|
|
from os import link, makedirs, path, remove
|
|
import shutil
|
|
from subprocess import check_call, CalledProcessError
|
|
from sys import stderr
|
|
from util import hash_file, resolve_url
|
|
from zipfile import ZipFile, BadZipfile, LargeZipFile
|
|
|
|
GERRIT_HOME = path.expanduser('~/.gerritcodereview')
|
|
CACHE_DIR = path.join(GERRIT_HOME, 'bazel-cache', 'downloaded-artifacts')
|
|
LOCAL_PROPERTIES = 'local.properties'
|
|
|
|
|
|
def safe_mkdirs(d):
|
|
if path.isdir(d):
|
|
return
|
|
try:
|
|
makedirs(d)
|
|
except OSError as err:
|
|
if not path.isdir(d):
|
|
raise err
|
|
|
|
|
|
def download_properties(root_dir):
|
|
""" Get the download properties.
|
|
|
|
First tries to find the properties file in the given root directory,
|
|
and if not found there, tries in the Gerrit settings folder in the
|
|
user's home directory.
|
|
|
|
Returns a set of download properties, which may be empty.
|
|
|
|
"""
|
|
p = {}
|
|
local_prop = path.join(root_dir, LOCAL_PROPERTIES)
|
|
if not path.isfile(local_prop):
|
|
local_prop = path.join(GERRIT_HOME, LOCAL_PROPERTIES)
|
|
if path.isfile(local_prop):
|
|
try:
|
|
with open(local_prop) as fd:
|
|
for line in fd:
|
|
if line.startswith('download.'):
|
|
d = [e.strip() for e in line.split('=', 1)]
|
|
name, url = d[0], d[1]
|
|
p[name[len('download.'):]] = url
|
|
except OSError:
|
|
pass
|
|
return p
|
|
|
|
|
|
def cache_entry(args):
|
|
if args.v:
|
|
h = args.v
|
|
else:
|
|
h = sha1(args.u.encode('utf-8')).hexdigest()
|
|
name = '%s-%s' % (path.basename(args.o), h)
|
|
return path.join(CACHE_DIR, name)
|
|
|
|
opts = OptionParser()
|
|
opts.add_option('-o', help='local output file')
|
|
opts.add_option('-u', help='URL to download')
|
|
opts.add_option('-v', help='expected content SHA-1')
|
|
opts.add_option('-x', action='append', help='file to delete from ZIP')
|
|
opts.add_option('--exclude_java_sources', action='store_true')
|
|
opts.add_option('--unsign', action='store_true')
|
|
args, _ = opts.parse_args()
|
|
|
|
root_dir = args.o
|
|
while root_dir and path.dirname(root_dir) != root_dir:
|
|
root_dir, n = path.split(root_dir)
|
|
if n == 'WORKSPACE':
|
|
break
|
|
|
|
redirects = download_properties(root_dir)
|
|
cache_ent = cache_entry(args)
|
|
src_url = resolve_url(args.u, redirects)
|
|
|
|
if not path.exists(cache_ent):
|
|
try:
|
|
safe_mkdirs(path.dirname(cache_ent))
|
|
except OSError as err:
|
|
print('error creating directory %s: %s' %
|
|
(path.dirname(cache_ent), err), file=stderr)
|
|
exit(1)
|
|
|
|
print('Download %s' % src_url, file=stderr)
|
|
try:
|
|
check_call(['curl', '--proxy-anyauth', '-ksSfLo', cache_ent, src_url])
|
|
except OSError as err:
|
|
print('could not invoke curl: %s\nis curl installed?' % err, file=stderr)
|
|
exit(1)
|
|
except CalledProcessError as err:
|
|
print('error using curl: %s' % err, file=stderr)
|
|
exit(1)
|
|
|
|
if args.v:
|
|
have = hash_file(sha1(), cache_ent).hexdigest()
|
|
if args.v != have:
|
|
print((
|
|
'%s:\n' +
|
|
'expected %s\n' +
|
|
'received %s\n') % (src_url, args.v, have), file=stderr)
|
|
try:
|
|
remove(cache_ent)
|
|
except OSError as err:
|
|
if path.exists(cache_ent):
|
|
print('error removing %s: %s' % (cache_ent, err), file=stderr)
|
|
exit(1)
|
|
|
|
exclude = []
|
|
if args.x:
|
|
exclude += args.x
|
|
if args.exclude_java_sources:
|
|
try:
|
|
with ZipFile(cache_ent, 'r') as zf:
|
|
for n in zf.namelist():
|
|
if n.endswith('.java'):
|
|
exclude.append(n)
|
|
except (BadZipfile, LargeZipFile) as err:
|
|
print('error opening %s: %s' % (cache_ent, err), file=stderr)
|
|
exit(1)
|
|
|
|
if args.unsign:
|
|
try:
|
|
with ZipFile(cache_ent, 'r') as zf:
|
|
for n in zf.namelist():
|
|
if (n.endswith('.RSA')
|
|
or n.endswith('.SF')
|
|
or n.endswith('.LIST')):
|
|
exclude.append(n)
|
|
except (BadZipfile, LargeZipFile) as err:
|
|
print('error opening %s: %s' % (cache_ent, err), file=stderr)
|
|
exit(1)
|
|
|
|
safe_mkdirs(path.dirname(args.o))
|
|
if exclude:
|
|
try:
|
|
shutil.copyfile(cache_ent, args.o)
|
|
except (shutil.Error, IOError) as err:
|
|
print('error copying to %s: %s' % (args.o, err), file=stderr)
|
|
exit(1)
|
|
try:
|
|
check_call(['zip', '-d', args.o] + exclude)
|
|
except CalledProcessError as err:
|
|
print('error removing files from zip: %s' % err, file=stderr)
|
|
exit(1)
|
|
else:
|
|
try:
|
|
link(cache_ent, args.o)
|
|
except OSError as err:
|
|
try:
|
|
shutil.copyfile(cache_ent, args.o)
|
|
except (shutil.Error, IOError) as err:
|
|
print('error copying to %s: %s' % (args.o, err), file=stderr)
|
|
exit(1)
|