From 13df818f721466414b48db07e7fad8bf2579e1f1 Mon Sep 17 00:00:00 2001 From: hedger Date: Sun, 7 May 2023 18:13:37 +0300 Subject: [PATCH 1/2] bootstrap: require hw-target for URL & file update modes; linter fixes (#16) * bootstrap: require hw-target for URL & file update modes; linter fixes * bootstrap: fixed condition for url loader --- VERSION.txt | 2 +- ufbt/__init__.py | 10 +++++++--- ufbt/bootstrap.py | 47 ++++++++++++++++++++++------------------------- 3 files changed, 30 insertions(+), 29 deletions(-) diff --git a/VERSION.txt b/VERSION.txt index 0c62199..ee1372d 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -0.2.1 +0.2.2 diff --git a/ufbt/__init__.py b/ufbt/__init__.py index 0140570..31418ca 100644 --- a/ufbt/__init__.py +++ b/ufbt/__init__.py @@ -61,15 +61,19 @@ def ufbt_cli(): if platform.system() == "Windows": commandline = ( - 'call "%UFBT_STATE_DIR%/current/scripts/toolchain/fbtenv.cmd" env & ' - f'python -m SCons -Q --warn=target-not-built -C "%UFBT_STATE_DIR%/current/scripts/ufbt" "UFBT_APP_DIR={UFBT_APP_DIR}" ' + r'call "%UFBT_STATE_DIR%/current/scripts/toolchain/fbtenv.cmd" env & ' + 'python -m SCons -Q --warn=target-not-built ' + r'-C "%UFBT_STATE_DIR%/current/scripts/ufbt" ' + f'"UFBT_APP_DIR={UFBT_APP_DIR}" ' + " ".join(sys.argv[1:]) ) else: commandline = ( '. "$UFBT_STATE_DIR/current/scripts/toolchain/fbtenv.sh" && ' - f'python3 -m SCons -Q --warn=target-not-built -C "$UFBT_STATE_DIR/current/scripts/ufbt" "UFBT_APP_DIR={UFBT_APP_DIR}" ' + 'python3 -m SCons -Q --warn=target-not-built ' + '-C "$UFBT_STATE_DIR/current/scripts/ufbt" ' + f'"UFBT_APP_DIR={UFBT_APP_DIR}" ' + " ".join(sys.argv[1:]) ) diff --git a/ufbt/bootstrap.py b/ufbt/bootstrap.py index b932952..9dfeee4 100644 --- a/ufbt/bootstrap.py +++ b/ufbt/bootstrap.py @@ -27,13 +27,12 @@ import sys from dataclasses import dataclass, field from html.parser import HTMLParser +from importlib.metadata import version from pathlib import Path, PurePosixPath from typing import ClassVar, Dict, Optional from urllib.parse import unquote, urlparse from urllib.request import Request, urlopen from zipfile import ZipFile -from importlib.metadata import version - ############################################################################## @@ -111,9 +110,7 @@ def metadata_to_init_kwargs(cls, metadata: dict) -> Dict[str, str]: # Conversion of argparse.Namespace to metadata dict @classmethod - def args_namespace_to_metadata( - cls, namespace: argparse.Namespace - ) -> Dict[str, str]: + def args_namespace_to_metadata(cls, args: argparse.Namespace) -> Dict[str, str]: raise NotImplementedError() @classmethod @@ -199,12 +196,10 @@ def metadata_to_init_kwargs(cls, metadata: dict) -> Dict[str, str]: } @classmethod - def args_namespace_to_metadata( - cls, namespace: argparse.Namespace - ) -> Dict[str, str]: + def args_namespace_to_metadata(cls, args: argparse.Namespace) -> Dict[str, str]: return { - "branch": namespace.branch, - "branch_root": namespace.index_url, + "branch": args.branch, + "branch_root": args.index_url, } @classmethod @@ -266,7 +261,7 @@ def _fetch_version(self, channel: UpdateChannel) -> dict: @staticmethod def _get_file_info(version_data: dict, file_type: FileType, file_target: str): if not (files := version_data.get("files", [])): - raise ValueError(f"Empty files list") + raise ValueError("Empty files list") if not ( file_info := next( @@ -285,7 +280,7 @@ def _get_file_info(version_data: dict, file_type: FileType, file_target: str): def get_sdk_component(self, target: str) -> str: file_info = self._get_file_info(self.version_info, FileType.SDK_ZIP, target) if not (file_url := file_info.get("url", None)): - raise ValueError(f"Invalid file url") + raise ValueError("Invalid file url") return self._fetch_file(file_url) @@ -307,12 +302,10 @@ def metadata_to_init_kwargs(cls, metadata: dict) -> Dict[str, str]: } @classmethod - def args_namespace_to_metadata( - cls, namespace: argparse.Namespace - ) -> Dict[str, str]: + def args_namespace_to_metadata(cls, args: argparse.Namespace) -> Dict[str, str]: return { - "channel": namespace.channel, - "json_index": namespace.index_url, + "channel": args.channel, + "json_index": args.index_url, } @classmethod @@ -353,10 +346,10 @@ def metadata_to_init_kwargs(cls, metadata: dict) -> Dict[str, str]: return {"url": metadata["url"]} @classmethod - def args_namespace_to_metadata( - cls, namespace: argparse.Namespace - ) -> Dict[str, str]: - return {"url": namespace.url} + def args_namespace_to_metadata(cls, args: argparse.Namespace) -> Dict[str, str]: + if args.url and not args.hw_target: + raise ValueError("HW target must be specified when using direct SDK URL") + return {"url": args.url} @classmethod def add_args_to_mode_group(cls, mode_group): @@ -396,13 +389,17 @@ def metadata_to_init_kwargs(cls, metadata: dict) -> Dict[str, str]: @classmethod def args_namespace_to_metadata(cls, args: argparse.Namespace) -> Dict[str, str]: - return {"file_path": args.local} + if args.local: + if not args.hw_target: + raise ValueError("HW target must be specified when using local SDK") + return {"file_path": str(Path(args.local).absolute())} + return {} @classmethod def add_args_to_mode_group(cls, mode_group): mode_group.add_argument( - f"--local", - f"-l", + "--local", + "-l", type=str, help="Path to local SDK zip file", ) @@ -547,7 +544,7 @@ def deploy(self, task: SdkDeployTask) -> bool: **sdk_loader.get_metadata(), } - log.info(f"Deploying SDK") + log.info("Deploying SDK") with ZipFile(sdk_component_path, "r") as zip_file: zip_file.extractall(sdk_target_dir) From a396ec8bb10dab09789d040f662617cecd81a286 Mon Sep 17 00:00:00 2001 From: hedger Date: Tue, 23 May 2023 02:34:28 +0400 Subject: [PATCH 2/2] ufbt: do update if no currently SDK is deployed (#17) --- ufbt/__init__.py | 14 ++++++-------- ufbt/bootstrap.py | 4 ++-- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/ufbt/__init__.py b/ufbt/__init__.py index 31418ca..221475c 100644 --- a/ufbt/__init__.py +++ b/ufbt/__init__.py @@ -48,8 +48,8 @@ def ufbt_cli(): if any(map(sys.argv.__contains__, bootstrap_subcommands)): return bootstrap_cli() - if not os.path.exists(ufbt_state_dir): - bootstrap_cli() + if not os.path.exists(ufbt_state_dir / "current"): + bootstrap_cli(["update"]) if not (ufbt_state_dir / "current" / "scripts" / "ufbt").exists(): print("SDK is missing scripts distribution!") @@ -62,19 +62,17 @@ def ufbt_cli(): if platform.system() == "Windows": commandline = ( r'call "%UFBT_STATE_DIR%/current/scripts/toolchain/fbtenv.cmd" env & ' - 'python -m SCons -Q --warn=target-not-built ' + "python -m SCons -Q --warn=target-not-built " r'-C "%UFBT_STATE_DIR%/current/scripts/ufbt" ' - f'"UFBT_APP_DIR={UFBT_APP_DIR}" ' - + " ".join(sys.argv[1:]) + f'"UFBT_APP_DIR={UFBT_APP_DIR}" ' + " ".join(sys.argv[1:]) ) else: commandline = ( '. "$UFBT_STATE_DIR/current/scripts/toolchain/fbtenv.sh" && ' - 'python3 -m SCons -Q --warn=target-not-built ' + "python3 -m SCons -Q --warn=target-not-built " '-C "$UFBT_STATE_DIR/current/scripts/ufbt" ' - f'"UFBT_APP_DIR={UFBT_APP_DIR}" ' - + " ".join(sys.argv[1:]) + f'"UFBT_APP_DIR={UFBT_APP_DIR}" ' + " ".join(sys.argv[1:]) ) # print(commandline) diff --git a/ufbt/bootstrap.py b/ufbt/bootstrap.py index 9dfeee4..cf8588d 100644 --- a/ufbt/bootstrap.py +++ b/ufbt/bootstrap.py @@ -737,7 +737,7 @@ def _func(self, args) -> int: ) -def bootstrap_cli() -> Optional[int]: +def bootstrap_cli(cmdline_args=None) -> Optional[int]: logging.basicConfig( format="%(asctime)s.%(msecs)03d [%(levelname).1s] %(message)s", level=logging.INFO, @@ -775,7 +775,7 @@ def bootstrap_cli() -> Optional[int]: for subcommand_cls in bootstrap_subcommand_classes: subcommand_cls().add_to_parser(parsers) - args = root_parser.parse_args() + args = root_parser.parse_args(cmdline_args) if args.verbose: logging.getLogger().setLevel(logging.DEBUG)