-
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
0a13739
commit 7b1e855
Showing
6 changed files
with
131 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
# /// script | ||
# requires-python = ">=3.12" | ||
# dependencies = [ | ||
# "more-itertools", | ||
# "nccsp", | ||
# "pydantic", | ||
# ] | ||
# | ||
# [tool.uv.sources] | ||
# nccsp = { git = "https://github.com/InSyncWithFoo/nccsp", rev = "master" } | ||
# /// | ||
|
||
from __future__ import annotations | ||
|
||
import json | ||
import subprocess | ||
from itertools import groupby | ||
from pathlib import Path | ||
from typing import Literal, Self | ||
|
||
import nccsp | ||
from more_itertools import partition | ||
from pydantic import BaseModel, Field | ||
|
||
type _Executable = Literal['ruff', 'uv'] | ||
|
||
|
||
def _is_option(option_or_argument: nccsp.OptionOrArgument) -> bool: | ||
return option_or_argument.name.startswith('-') | ||
|
||
|
||
class _Command(BaseModel): | ||
name: str | ||
path: list[str] | ||
description: str | None | ||
arguments: list[nccsp.OptionOrArgument] | ||
options: list[nccsp.OptionOrArgument] | ||
subcommands: dict[str, _Command] = Field(default_factory = dict) | ||
|
||
@classmethod | ||
def convert(cls, command: nccsp.Command) -> Self: | ||
fragments = command.fragments if len(command.fragments) == 1 else command.fragments[1:] | ||
|
||
*path, name = fragments | ||
description = command.description | ||
arguments, options = partition(_is_option, command.options_and_arguments) | ||
|
||
return cls( | ||
name = name, path = path, | ||
description = description, | ||
arguments = arguments, # pyright: ignore [reportArgumentType] | ||
options = options # pyright: ignore [reportArgumentType] | ||
) | ||
|
||
|
||
def _get_version(executable: _Executable) -> str: | ||
return subprocess.check_output([executable, 'version']).decode('utf-8').strip() | ||
|
||
|
||
def _get_data(executable: _Executable) -> list[nccsp.Command]: | ||
arguments = ['nccsp', 'executable', executable] | ||
output_stream = subprocess.check_output(arguments) | ||
output = output_stream.decode('utf-8') | ||
|
||
return [nccsp.Command(**element) for element in json.loads(output)] | ||
|
||
|
||
def _add_to_tree(ancestor: _Command, descendant: _Command, path: list[str]) -> None: | ||
subtree = ancestor.subcommands | ||
|
||
if len(path) == 1: | ||
subtree[descendant.name] = descendant | ||
return | ||
|
||
_add_to_tree(subtree[path[0]], descendant, path[1:]) | ||
|
||
|
||
def _convert_flat_to_nested(commands: list[nccsp.Command]) -> _Command: | ||
root = _Command.convert(commands[0]) | ||
|
||
for command in commands[1:]: | ||
_add_to_tree(root, _Command.convert(command), path = command.fragments[1:]) | ||
|
||
return root | ||
|
||
|
||
def _dump_data(version: str, tree: _Command, filename: str) -> None: | ||
json_resources_directory = Path(__file__).parent.parent / 'src' / 'main' / 'resources' / 'commandspecs' | ||
json_resources_directory.mkdir(parents = True, exist_ok = True) | ||
|
||
path = json_resources_directory / f'{filename}.json' | ||
|
||
with open(path.absolute(), 'w') as file: | ||
data = { | ||
'version': version, | ||
'tree': tree.model_dump() | ||
} | ||
json.dump(data, file) | ||
|
||
|
||
def _get_and_dump_data(executable: _Executable) -> None: | ||
version = _get_version(executable) | ||
data_grouped_by_tool = groupby(_get_data(executable), lambda command: command.fragments[0]) | ||
|
||
for tool_name, tool_data in data_grouped_by_tool: | ||
tree = _convert_flat_to_nested(list(tool_data)) | ||
_dump_data(version, tree, filename = tool_name) | ||
|
||
|
||
def main() -> None: # noqa: D103 | ||
_get_and_dump_data('ruff') | ||
_get_and_dump_data('uv') | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{"version": "uv 0.4.12 (2545bca69 2024-09-18)", "tree": {"name": "uvx", "path": [], "description": "Run a command provided by a Python package.", "arguments": [], "options": [{"name": "--from", "alias": null, "variadic": false, "optional": false, "type": "string", "suggestions": null, "description": "Use the given package to provide the command"}, {"name": "--with", "alias": null, "variadic": false, "optional": false, "type": "string", "suggestions": null, "description": "Run with the given packages installed"}, {"name": "--with-editable", "alias": null, "variadic": false, "optional": false, "type": "string", "suggestions": null, "description": "Run with the given packages installed as editables"}, {"name": "--with-requirements", "alias": null, "variadic": false, "optional": false, "type": "string", "suggestions": null, "description": "Run with all packages listed in the given `requirements.txt` files"}, {"name": "--isolated", "alias": null, "variadic": false, "optional": false, "type": null, "suggestions": null, "description": "Run the tool in an isolated virtual environment, ignoring any already-installed tools"}, {"name": "--index-url", "alias": "-i", "variadic": false, "optional": false, "type": "string", "suggestions": null, "description": "The URL of the Python package index (by default: <https://pypi.org/simple>)"}, {"name": "--extra-index-url", "alias": null, "variadic": false, "optional": false, "type": "string", "suggestions": null, "description": "Extra URLs of package indexes to use, in addition to `--index-url`"}, {"name": "--find-links", "alias": "-f", "variadic": false, "optional": false, "type": "string", "suggestions": null, "description": "Locations to search for candidate distributions, in addition to those found in the registry indexes"}, {"name": "--no-index", "alias": null, "variadic": false, "optional": false, "type": null, "suggestions": null, "description": "Ignore the registry index (e.g., PyPI), instead relying on direct URL dependencies and those provided via `--find-links`"}, {"name": "--upgrade", "alias": "-U", "variadic": false, "optional": false, "type": null, "suggestions": null, "description": "Allow package upgrades, ignoring pinned versions in any existing output file. Implies `--refresh`"}, {"name": "--no-upgrade", "alias": null, "variadic": false, "optional": false, "type": null, "suggestions": null, "description": null}, {"name": "--upgrade-package", "alias": "-P", "variadic": false, "optional": false, "type": "string", "suggestions": null, "description": "Allow upgrades for a specific package, ignoring pinned versions in any existing output file. Implies `--refresh-package`"}, {"name": "--reinstall", "alias": null, "variadic": false, "optional": false, "type": null, "suggestions": null, "description": "Reinstall all packages, regardless of whether they're already installed. Implies `--refresh`"}, {"name": "--no-reinstall", "alias": null, "variadic": false, "optional": false, "type": null, "suggestions": null, "description": null}, {"name": "--reinstall-package", "alias": null, "variadic": false, "optional": false, "type": "string", "suggestions": null, "description": "Reinstall a specific package, regardless of whether it's already installed. Implies `--refresh-package`"}, {"name": "--index-strategy", "alias": null, "variadic": false, "optional": false, "type": "string", "suggestions": ["first-index", "unsafe-first-match", "unsafe-best-match"], "description": "The strategy to use when resolving against multiple index URLs"}, {"name": "--keyring-provider", "alias": null, "variadic": false, "optional": false, "type": "string", "suggestions": ["disabled", "subprocess"], "description": "Attempt to use `keyring` for authentication for index URLs"}, {"name": "--allow-insecure-host", "alias": null, "variadic": false, "optional": false, "type": "string", "suggestions": null, "description": "Allow insecure connections to a host"}, {"name": "--resolution", "alias": null, "variadic": false, "optional": false, "type": "string", "suggestions": ["highest", "lowest", "lowest-direct"], "description": "The strategy to use when selecting between the different compatible versions for a given package requirement"}, {"name": "--prerelease", "alias": null, "variadic": false, "optional": false, "type": "string", "suggestions": ["disallow", "allow", "if-necessary", "explicit", "if-necessary-or-explicit"], "description": "The strategy to use when considering pre-release versions"}, {"name": "--pre", "alias": null, "variadic": false, "optional": false, "type": null, "suggestions": null, "description": null}, {"name": "--config-setting", "alias": "-C", "variadic": false, "optional": false, "type": "string", "suggestions": null, "description": "Settings to pass to the PEP 517 build backend, specified as `KEY=VALUE` pairs"}, {"name": "--no-build-isolation", "alias": null, "variadic": false, "optional": false, "type": null, "suggestions": null, "description": "Disable isolation when building source distributions"}, {"name": "--no-build-isolation-package", "alias": null, "variadic": false, "optional": false, "type": "string", "suggestions": null, "description": "Disable isolation when building source distributions for a specific package"}, {"name": "--build-isolation", "alias": null, "variadic": false, "optional": false, "type": null, "suggestions": null, "description": null}, {"name": "--exclude-newer", "alias": null, "variadic": false, "optional": false, "type": "string", "suggestions": null, "description": "Limit candidate packages to those that were uploaded prior to the given date"}, {"name": "--link-mode", "alias": null, "variadic": false, "optional": false, "type": "string", "suggestions": ["clone", "copy", "hardlink", "symlink"], "description": "The method to use when installing packages from the global cache"}, {"name": "--compile-bytecode", "alias": null, "variadic": false, "optional": false, "type": null, "suggestions": null, "description": "Compile Python files to bytecode after installation"}, {"name": "--no-compile-bytecode", "alias": null, "variadic": false, "optional": false, "type": null, "suggestions": null, "description": null}, {"name": "--no-sources", "alias": null, "variadic": false, "optional": false, "type": null, "suggestions": null, "description": "Ignore the `tool.uv.sources` table when resolving dependencies. Used to lock against the standards-compliant, publishable package metadata, as opposed to using any local or Git sources"}, {"name": "--no-build", "alias": null, "variadic": false, "optional": false, "type": null, "suggestions": null, "description": "Don't build source distributions"}, {"name": "--build", "alias": null, "variadic": false, "optional": false, "type": null, "suggestions": null, "description": null}, {"name": "--no-build-package", "alias": null, "variadic": false, "optional": false, "type": "string", "suggestions": null, "description": "Don't build source distributions for a specific package"}, {"name": "--no-binary", "alias": null, "variadic": false, "optional": false, "type": null, "suggestions": null, "description": "Don't install pre-built wheels"}, {"name": "--binary", "alias": null, "variadic": false, "optional": false, "type": null, "suggestions": null, "description": null}, {"name": "--no-binary-package", "alias": null, "variadic": false, "optional": false, "type": "string", "suggestions": null, "description": "Don't install pre-built wheels for a specific package"}, {"name": "--refresh", "alias": null, "variadic": false, "optional": false, "type": null, "suggestions": null, "description": "Refresh all cached data"}, {"name": "--no-refresh", "alias": null, "variadic": false, "optional": false, "type": null, "suggestions": null, "description": null}, {"name": "--refresh-package", "alias": null, "variadic": false, "optional": false, "type": "string", "suggestions": null, "description": "Refresh cached data for a specific package"}, {"name": "--python", "alias": "-p", "variadic": false, "optional": false, "type": "string", "suggestions": null, "description": "The Python interpreter to use to build the run environment."}, {"name": "--show-resolution", "alias": null, "variadic": false, "optional": false, "type": null, "suggestions": null, "description": "Whether to show resolver and installer output from any environment modifications"}, {"name": "--no-cache", "alias": "-n", "variadic": false, "optional": false, "type": null, "suggestions": null, "description": "Avoid reading from or writing to the cache, instead using a temporary directory for the duration of the operation"}, {"name": "--cache-dir", "alias": null, "variadic": false, "optional": false, "type": "string", "suggestions": null, "description": "Path to the cache directory"}, {"name": "--python-preference", "alias": null, "variadic": false, "optional": false, "type": "string", "suggestions": ["only-managed", "managed", "system", "only-system"], "description": "Whether to prefer uv-managed or system Python installations"}, {"name": "--allow-python-downloads", "alias": null, "variadic": false, "optional": false, "type": null, "suggestions": null, "description": "Allow automatically downloading Python when required. [env: \"UV_PYTHON_DOWNLOADS=auto\"]"}, {"name": "--no-python-downloads", "alias": null, "variadic": false, "optional": false, "type": null, "suggestions": null, "description": "Disable automatic downloads of Python. [env: \"UV_PYTHON_DOWNLOADS=never\"]"}, {"name": "--python-fetch", "alias": null, "variadic": false, "optional": false, "type": "string", "suggestions": ["automatic", "manual", "never"], "description": "Deprecated version of [`Self::python_downloads`]"}, {"name": "--quiet", "alias": "-q", "variadic": false, "optional": false, "type": null, "suggestions": null, "description": "Do not print any output"}, {"name": "--verbose", "alias": "-v", "variadic": false, "optional": false, "type": null, "suggestions": null, "description": "Use verbose output"}, {"name": "--no-color", "alias": null, "variadic": false, "optional": false, "type": null, "suggestions": null, "description": "Disable colors"}, {"name": "--color", "alias": null, "variadic": false, "optional": false, "type": "string", "suggestions": ["auto", "always", "never"], "description": "Control colors in output"}, {"name": "--native-tls", "alias": null, "variadic": false, "optional": false, "type": null, "suggestions": null, "description": "Whether to load TLS certificates from the platform's native certificate store"}, {"name": "--no-native-tls", "alias": null, "variadic": false, "optional": false, "type": null, "suggestions": null, "description": null}, {"name": "--offline", "alias": null, "variadic": false, "optional": false, "type": null, "suggestions": null, "description": "Disable network access"}, {"name": "--no-offline", "alias": null, "variadic": false, "optional": false, "type": null, "suggestions": null, "description": null}, {"name": "--preview", "alias": null, "variadic": false, "optional": false, "type": null, "suggestions": null, "description": "Whether to enable experimental, preview features"}, {"name": "--no-preview", "alias": null, "variadic": false, "optional": false, "type": null, "suggestions": null, "description": null}, {"name": "--show-settings", "alias": null, "variadic": false, "optional": false, "type": null, "suggestions": null, "description": "Show the resolved settings for the current command"}, {"name": "--no-progress", "alias": null, "variadic": false, "optional": false, "type": null, "suggestions": null, "description": "Hide all progress outputs"}, {"name": "--directory", "alias": null, "variadic": false, "optional": false, "type": "string", "suggestions": null, "description": "Change to the given directory prior to running the command"}, {"name": "--config-file", "alias": null, "variadic": false, "optional": false, "type": "string", "suggestions": null, "description": "The path to a `uv.toml` file to use for configuration"}, {"name": "--no-config", "alias": null, "variadic": false, "optional": false, "type": null, "suggestions": null, "description": "Avoid discovering configuration files (`pyproject.toml`, `uv.toml`)"}, {"name": "--help", "alias": "-h", "variadic": false, "optional": false, "type": null, "suggestions": null, "description": "Display the concise help for this command"}, {"name": "--version", "alias": "-V", "variadic": false, "optional": false, "type": null, "suggestions": null, "description": "Display the uv version"}], "subcommands": {}}} |