From d5b518e5bd1bdbc865de7624b17c4fc919fe5200 Mon Sep 17 00:00:00 2001 From: Paul Meyer Date: Wed, 23 Jul 2025 08:14:49 +0200 Subject: [PATCH] azure-cli-extensions: update docs on adding extension Closes https://github.com/NixOS/nixpkgs/issues/342214 Signed-off-by: Paul Meyer --- pkgs/by-name/az/azure-cli/README.md | 26 +++++---- pkgs/by-name/az/azure-cli/extensions-tool.py | 59 ++++++++++++++++++-- 2 files changed, 69 insertions(+), 16 deletions(-) diff --git a/pkgs/by-name/az/azure-cli/README.md b/pkgs/by-name/az/azure-cli/README.md index 5907f1916f8f..e8500510f054 100644 --- a/pkgs/by-name/az/azure-cli/README.md +++ b/pkgs/by-name/az/azure-cli/README.md @@ -33,7 +33,10 @@ Use the following command, use the current version of azure-cli in nixpkgs as `c and the name of the extension you want to package as `extension`: ```sh -./query-extension-index.sh --cli-version=2.61.0 --extension=azure-devops --download +nix run .#azure-cli.extension-tool -- \ + --cli-version=2.61.0 \ + --extension=azure-devops \ + --init ``` The output should look something like this: @@ -41,14 +44,13 @@ The output should look something like this: ```json { "pname": "azure-devops", - "description": "Tools for managing Azure DevOps.", - "version": "1.0.1", - "url": "https://github.com/Azure/azure-devops-cli-extension/releases/download/20240514.1/azure_devops-1.0.1-py2.py3-none-any.whl", - "sha256": "f300d0288f017148514ebe6f5912aef10c7a6f29bdc0c916b922edf1d75bc7db", + "version": "1.0.2", + "url": "https://github.com/Azure/azure-devops-cli-extension/releases/download/20250624.2/azure_devops-1.0.2-py2.py3-none-any.whl", + "hash": "sha256-4rDeAqOnRRKMP26MJxG4u9vBuos6/SQIoVgfNbBpulk=", + "description": "Tools for managing Azure DevOps", "license": "MIT", - "requires": [ - "distro (==1.3.0)", - "distro==1.3.0" + "requirements": [ + "distro (>=1.6.0)" ] } ``` @@ -58,9 +60,9 @@ Based on this, you can add an attribute to `extensions-manual.nix`: ```nix azure-devops = mkAzExtension { pname = "azure-devops"; - version = "1.0.0"; - url = "https://github.com/Azure/azure-devops-cli-extension/releases/download/20240206.1/azure_devops-${version}-py2.py3-none-any.whl"; - sha256 = "658a2854d8c80f874f9382d421fa45abf6a38d00334737dda006f8dec64cf70a"; + version = "1.0.2"; + url = "https://github.com/Azure/azure-devops-cli-extension/releases/download/20250624.2/azure_devops-${version}-py2.py3-none-any.whl"; + hash = "sha256-4rDeAqOnRRKMP26MJxG4u9vBuos6/SQIoVgfNbBpulk="; description = "Tools for managing Azure DevOps"; propagatedBuildInputs = with python3Packages; [ distro @@ -71,7 +73,7 @@ Based on this, you can add an attribute to `extensions-manual.nix`: * The attribute name should be the same as `pname`. * Replace the version in `url` with `${version}`. -* The json output `requires` must be transformed into `propagetedBuildInputs`. +* The json output `requirements` must be transformed into package `requirements`. * If `license` is `"MIT"`, it can be left out in the nix expression, as the builder defaults to that license. * Add yourself as maintainer in `meta.maintainers`. diff --git a/pkgs/by-name/az/azure-cli/extensions-tool.py b/pkgs/by-name/az/azure-cli/extensions-tool.py index d3a23fb2cc78..ecf8ecda0c9f 100644 --- a/pkgs/by-name/az/azure-cli/extensions-tool.py +++ b/pkgs/by-name/az/azure-cli/extensions-tool.py @@ -174,12 +174,12 @@ def _get_latest_version(versions: dict) -> dict: return max(versions, key=lambda e: parse(e["metadata"]["version"]), default=None) -def processExtension( +def find_extension_version( extVersions: dict, cli_version: Version, ext_name: Optional[str] = None, requirements: bool = False, -) -> Optional[Ext]: +) -> Optional[Dict[str, Any]]: versions = filter(_filter_invalid, extVersions) versions = filter(lambda v: _filter_compatible(v, cli_version), versions) latest = _get_latest_version(versions) @@ -189,6 +189,18 @@ def processExtension( return None if not requirements and "run_requires" in latest["metadata"]: return None + return latest + + +def find_and_transform_extension_version( + extVersions: dict, + cli_version: Version, + ext_name: Optional[str] = None, + requirements: bool = False, +) -> Optional[Ext]: + latest = find_extension_version(extVersions, cli_version, ext_name, requirements) + if not latest: + return None return _transform_dict_to_obj(latest) @@ -335,6 +347,11 @@ def main() -> None: action=argparse.BooleanOptionalAction, help="whether to commit changes to git", ) + parser.add_argument( + "--init", + action=argparse.BooleanOptionalAction, + help="whether you want to init a new extension", + ) args = parser.parse_args() cli_version = parse(args.cli_version) @@ -348,12 +365,44 @@ def main() -> None: assert index["formatVersion"] == "1" # only support formatVersion 1 extensions_remote = index["extensions"] + # init just prints the json of the extension version that matches the cli version. + if args.init: + if not args.extension: + logger.error("extension name is required for --init") + exit(1) + + for ext_name, ext_versions in extensions_remote.items(): + if ext_name != args.extension: + continue + ext = find_extension_version( + ext_versions, + cli_version, + args.extension, + requirements=True, + ) + break + if not ext: + logger.error(f"Extension {args.extension} not found in index") + exit(1) + + ext_translated = { + "pname": ext["metadata"]["name"], + "version": ext["metadata"]["version"], + "url": ext["downloadUrl"], + "hash": _convert_hash_digest_from_hex_to_b64_sri(ext["sha256Digest"]), + "description": ext["metadata"]["summary"].rstrip("."), + "license": ext["metadata"]["license"], + "requirements": ext["metadata"]["run_requires"][0]["requires"], + } + print(json.dumps(ext_translated, indent=2)) + return + if args.extension: logger.info(f"updating extension: {args.extension}") ext = Optional[Ext] for _ext_name, extension in extensions_remote.items(): - extension = processExtension( + extension = find_and_transform_extension_version( extension, cli_version, args.extension, requirements=True ) if extension: @@ -402,7 +451,9 @@ def main() -> None: extensions_remote_filtered = set() for _ext_name, extension in extensions_remote.items(): - extension = processExtension(extension, cli_version, args.extension) + extension = find_and_transform_extension_version( + extension, cli_version, args.extension + ) if extension: extensions_remote_filtered.add(extension)