Skip to content

Commit

Permalink
Refactor and cleanup (#23)
Browse files Browse the repository at this point in the history
* cleanup

* bump

* update makefile
  • Loading branch information
jaykv authored Jun 24, 2023
1 parent 076ad6b commit 9131e12
Show file tree
Hide file tree
Showing 9 changed files with 188 additions and 193 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ test:
pytest -vv --capture=tee-sys

clean:
rm -rf build/ dist/ *.egg-info .pytest_cache
rm -rf build/ dist/ *.egg-info .*_cache
find . -name '*.pyc' -type f -exec rm -rf {} +
find . -name '__pycache__' -exec rm -rf {} +

Expand Down
43 changes: 23 additions & 20 deletions cliffy/commander.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,31 +122,34 @@ def add_command(self, command: Command) -> None:
group = command.name.split(".")[:-1][-1]
self.add_sub_command(command, self.groups[group])

def add_lazy_command(self, greedy_command: Command, group: str):
# make it lazy and interpolate
lazy_command_name = greedy_command.name.replace("(*)", group)
lazy_command_script = ""
if isinstance(greedy_command.script, str):
lazy_command_script = greedy_command.script.replace("{(*)}", group)
elif isinstance(greedy_command.script, list):
lazy_command_script = []
for script_block in greedy_command.script:
if isinstance(script_block, dict):
lazy_command_script.append(script_block["help"].replace("{(*)}", group))
else:
lazy_command_script.append(script_block.replace("{(*)}", group))

if greedy_command_args := self.manifest.args.get(greedy_command.name):
self.manifest.args[lazy_command_name] = greedy_command_args

# lazy load
lazy_command = Command(name=lazy_command_name, script=lazy_command_script)
self.commands.append(lazy_command)
self.add_command(lazy_command)

def add_greedy_commands(self) -> None:
"""Greedy commands get lazy-loaded. Only supported for group-commands currently"""
for greedy_command in self.greedy:
if greedy_command.name.startswith("(*)"):
for group in self.groups:
# make it lazy and interpolate
lazy_command_name = greedy_command.name.replace("(*)", group)
lazy_command_script = ""
if isinstance(greedy_command.script, str):
lazy_command_script = greedy_command.script.replace("{(*)}", group)
elif isinstance(greedy_command.script, list):
lazy_command_script = []
for script_block in greedy_command.script:
if isinstance(script_block, dict):
lazy_command_script.append(script_block["help"].replace("{(*)}", group))
else:
lazy_command_script.append(script_block.replace("{(*)}", group))

if greedy_command_args := self.manifest.args.get(greedy_command.name):
self.manifest.args[lazy_command_name] = greedy_command_args

# lazy load
lazy_command = Command(name=lazy_command_name, script=lazy_command_script)
self.commands.append(lazy_command)
self.add_command(lazy_command)
self.add_lazy_command(greedy_command, group)

def is_greedy(self, val: str) -> bool:
"""Greedy strings must contain (*)- marked to be evaluated lazily."""
Expand Down
7 changes: 4 additions & 3 deletions cliffy/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ def print_rich_table(cols: list[str], rows: list[list[str]], styles: list[str])
console.print(table)


def get_installed_pip_packages() -> dict[str, str]:
def get_installed_package_versions() -> dict[str, str]:
reqs = subprocess.check_output([sys.executable, "-m", "pip", "freeze"])
installed_packages = {}
for r in reqs.split():
Expand All @@ -114,10 +114,11 @@ def parse_requirement(requirement: str) -> RequirementSpec:
return RequirementSpec(name=requirement.strip(), operator=None, version=None)


def compare_versions(version1: str, version2: str, op: str) -> bool:
def compare_versions(version1: str, version2: str, op: Optional[str] = "=") -> bool:
v1 = version.parse(version1)
v2 = version.parse(version2)
return OPERATOR_MAP[op](v1, v2)

return OPERATOR_MAP[op](v1, v2) if op else v1 == v2


def out(text: str, **echo_kwargs: Any) -> None:
Expand Down
6 changes: 1 addition & 5 deletions cliffy/homer.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,7 @@ def get_metadata(cli_name: str) -> Optional[CLIMetadata]:
Optional[CLIMetadata]: CLI metadata
"""
cli_path = get_metadata_path(cli_name)
if not cli_path:
return None

path = Path(cli_path)
return get_metadata_bypath(path)
return get_metadata_bypath(Path(cli_path)) if cli_path else None


def get_metadata_path(cli_name: str) -> Optional[str]:
Expand Down
12 changes: 6 additions & 6 deletions cliffy/manifests/v1.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from datetime import datetime
from typing import Any, Literal, Union

from pydantic import BaseModel, Field

from ..helper import wrap_as_comment, wrap_as_var
Expand Down Expand Up @@ -79,11 +78,12 @@ class CLIManifest(BaseModel):
@classmethod
def get_field_description(cls, field_name: str, as_comment: bool = True) -> str:
field = cls.model_fields.get(field_name)
if field and field.description:
if as_comment:
return wrap_as_comment(field.description, split_on=". ")
return field.description
return ""
if not field or not field.description:
return ""

if as_comment:
return wrap_as_comment(field.description, split_on=". ")
return field.description

@classmethod
def get_template(cls, name: str) -> str:
Expand Down
45 changes: 18 additions & 27 deletions cliffy/transformer.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

from .commander import generate_cli
from .commanders.typer import TyperCommander
from .helper import compare_versions, exit_err, get_installed_pip_packages, out, parse_requirement
from .helper import compare_versions, exit_err, get_installed_package_versions, out, parse_requirement
from .manifests import IncludeManifest, Manifest, set_manifest_version
from .merger import cliffy_merger

Expand All @@ -27,45 +27,36 @@ def __init__(self, manifest_io: TextIO, *, as_include: bool = False, validate_re
cliffy_merger.merge(self.command_config, self.includes_config)

set_manifest_version(self.manifest_version)
if as_include:
try:
self.manifest = IncludeManifest(**self.command_config)
except ValidationError as e:
out(f"{e}")
exit_err(f"~ error validating {manifest_io.name}")
else:
try:
self.manifest = Manifest(**self.command_config)
except ValidationError as e:
out(f"{e}")
exit_err(f"~ error validating {manifest_io.name}")

if validate_requires:
self.validate_cli_requires()

manifest_cls = IncludeManifest if as_include else Manifest
try:
self.manifest = manifest_cls(**self.command_config)
except ValidationError as e:
out(f"{e}")
exit_err(f"~ error validating {manifest_io.name}")

if validate_requires:
self.validate_cli_requires()

if isinstance(self.manifest, Manifest):
self.cli = generate_cli(self.manifest, commander_cls=TyperCommander)

def validate_cli_requires(self) -> None:
if not self.manifest.requires:
return

installed_pip_packages = get_installed_pip_packages()
installed_package_versions = get_installed_package_versions()
for dep in self.manifest.requires:
dep_spec = parse_requirement(dep)
if dep_spec.name not in installed_pip_packages:
if dep_spec.name not in installed_package_versions:
exit_err(f"~ missing requirement: `{self.manifest_io.name}` requires `{dep}` to be installed")

if (
dep_spec.version
and dep_spec.operator
and not compare_versions(
installed_pip_packages[dep_spec.name],
dep_spec.version,
dep_spec.operator,
)
if dep_spec.version and not compare_versions(
installed_package_versions[dep_spec.name], dep_spec.version, dep_spec.operator
):
exit_err(
f"~ missing requirement: `{self.manifest_io.name}` requires `{dep}` to be installed"
f" found version `{installed_pip_packages[dep_spec.name]}`"
f" found version `{installed_package_versions[dep_spec.name]}`"
)

def resolve_includes(self) -> dict:
Expand Down
Loading

0 comments on commit 9131e12

Please sign in to comment.