1# Copyright 2023 The Pigweed Authors 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); you may not 4# use this file except in compliance with the License. You may obtain a copy of 5# the License at 6# 7# https://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12# License for the specific language governing permissions and limitations under 13# the License. 14"""Install and check status of picotool.""" 15 16import logging 17import os 18from pathlib import Path 19import shutil 20import subprocess 21from typing import Sequence 22 23import pw_package.git_repo 24import pw_package.package_manager 25 26_LOG = logging.getLogger(__package__) 27 28 29def force_copy(source: Path, destination: Path): 30 _LOG.info('Copy %s -> %s', source, destination) 31 # ensure the destination directory exists 32 # otherwise the copy will fail on mac. 33 dirname = os.path.dirname(destination) 34 if not os.path.isdir(dirname): 35 os.makedirs(dirname) 36 destination.unlink(missing_ok=True) 37 shutil.copy(source, destination) 38 39 40class Picotool(pw_package.package_manager.Package): 41 """Install and check status of picotool.""" 42 43 def __init__(self, *args, **kwargs): 44 super().__init__(*args, name='picotool', **kwargs) 45 46 def install(self, path: Path) -> None: 47 env = os.environ.copy() 48 49 def log_and_run(command: Sequence[str], **kwargs): 50 _LOG.info('==> %s', ' '.join(command)) 51 return subprocess.run( 52 command, 53 env=env, 54 check=True, 55 **kwargs, 56 ) 57 58 log_and_run(('bazel', 'build', '@picotool')) 59 build_path = log_and_run( 60 ('bazel', 'cquery', '@picotool', '--output=files'), 61 capture_output=True, 62 text=True, 63 ).stdout.strip() 64 65 picotool_bin = path / 'out' / 'picotool' 66 force_copy(build_path, picotool_bin) 67 68 _LOG.info('Done! picotool binary located at:') 69 _LOG.info(picotool_bin) 70 71 bootstrap_env_path = Path(env.get('_PW_ACTUAL_ENVIRONMENT_ROOT', '')) 72 if bootstrap_env_path.is_dir() and picotool_bin.is_file(): 73 bin_path = ( 74 bootstrap_env_path / 'cipd' / 'packages' / 'pigweed' / 'bin' 75 ) 76 destination_path = bin_path / picotool_bin.name 77 force_copy(build_path, destination_path) 78 79 def info(self, path: Path) -> Sequence[str]: 80 return (f'{self.name} installed in: {path}',) 81 82 83pw_package.package_manager.register(Picotool) 84