blob: 0b5b1ad2ee5327c4e47a79afb94509af265f5a11 [file] [log] [blame]
# Copyright 2021 The Pigweed Authors
#
# 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
#
# https://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.
"""Copies files from CIPD to a specified directory.
By default, Pigweed installs packages from a manifest file to a CIPD
subdirectory as part of environment setup. This script will copy files from this
directory into a specified output directory.
Here's an example of how to use this script:
Let's say you have a package with a static library:
CIPD path: `pigweed/third_party/libsomething`
Files:
./libsomething/include/something.h
./libsomething/libsomething.a
And this package was referenced in my_project_packages.json, which was provided
as a --cipd-package-file in your bootstrap script.
To copy the static libraryto $PW_PROJECT_ROOT/static_libraries, you'd have an
invocation something like this:
copy_from_cipd --package-name=pigweed/third_party/libsomething \
--mainfest=$PW_PROJECT_ROOT/tools/my_project_packages.json \
--file=libsomething/libsomething.a \
--out=$PW_PROJECT_ROOT/static_libraries
"""
import argparse
import json
import logging
import os
import shutil
import subprocess
import sys
from pathlib import Path
import pw_env_setup.cipd_setup.update
logger = logging.getLogger(__name__)
def parse_args():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('--verbose',
'-v',
help='Verbose output',
action='store_true')
parser.add_argument('--manifest',
required=True,
type=Path,
help='Path to CIPD JSON manifest file')
parser.add_argument('--out-dir',
type=Path,
default='.',
help='Output folder to copy the specified file to')
parser.add_argument('--package-name',
required=True,
help='The CIPD package name')
# TODO(pwbug/334) Support multiple values for --file.
parser.add_argument('--file',
required=True,
type=Path,
help='Path of the file to copy from the CIPD package. '
'This is relative to the CIPD package root of the '
'provided manifest.')
parser.add_argument('--cipd-package-root',
type=Path,
help="Path to the root of the package's install "
'directory. This is usually at '
'PW_{manifest name}_CIPD_INSTALL_DIR')
return parser.parse_args()
def check_version(manifest, cipd_path, package_name):
base_package_name = os.path.basename(package_name)
instance_id_path = os.path.join(cipd_path, '.versions',
f'{base_package_name}.cipd_version')
with open(instance_id_path, 'r') as ins:
instance_id = json.load(ins)['instance_id']
with open(manifest, 'r') as ins:
data = json.load(ins)['packages']
path = None
expected_version = None
for entry in data:
if package_name in entry['path']:
path = entry['path']
expected_version = entry['tags'][0]
if not path:
raise LookupError(f'failed to find {package_name} entry')
cmd = ['cipd', 'describe', path, '-version', instance_id]
output = subprocess.check_output(cmd).decode()
if expected_version not in output:
pw_env_setup.cipd_setup.update.update(
'cipd', (manifest, ), os.environ['PW_CIPD_INSTALL_DIR'],
os.environ['CIPD_CACHE_DIR'])
def main():
args = parse_args()
if args.verbose:
logger.setLevel(logging.DEBUG)
# Try to infer CIPD install root from the manifest name.
if args.cipd_package_root is None:
file_base_name = args.manifest.stem
args.cipd_var = 'PW_{}_CIPD_INSTALL_DIR'.format(file_base_name.upper())
try:
args.cipd_package_root = os.environ[args.cipd_var]
except KeyError:
logger.error(
"The %s environment variable isn't set. Did you forget to run "
'`. ./bootstrap.sh`? Is the %s manifest installed to a '
'different path?', args.cipd_var, file_base_name)
sys.exit(1)
check_version(args.manifest, args.cipd_package_root, args.package_name)
shutil.copyfile(os.path.join(args.cipd_package_root, args.file),
os.path.join(args.out_dir, args.file))
if __name__ == '__main__':
logging.basicConfig()
main()