- Implement recursive downloading of nested dependencies from ZON files - Enhance CLI to support downloading from directories containing `build.zig.zon` files - Update README with new usage instructions and command options - Refactor dependency processing to handle both single files and directories
201 lines
5.2 KiB
Python
201 lines
5.2 KiB
Python
"""
|
|
Command-line interface for zig-fetch-py.
|
|
"""
|
|
|
|
import sys
|
|
from pathlib import Path
|
|
from typing import Optional
|
|
|
|
import click
|
|
from loguru import logger
|
|
|
|
from zig_fetch_py.downloader import process_dependencies
|
|
from zig_fetch_py.parser import zon_to_json
|
|
|
|
|
|
def setup_logger(verbose: bool = False):
|
|
"""
|
|
Set up the logger.
|
|
|
|
Args:
|
|
verbose: Whether to enable verbose logging
|
|
"""
|
|
logger.remove()
|
|
log_level = "DEBUG" if verbose else "INFO"
|
|
logger.add(sys.stderr, level=log_level)
|
|
|
|
|
|
def convert_zon_to_json(
|
|
zon_file: Path,
|
|
output: Optional[Path] = None,
|
|
indent: int = 2,
|
|
empty_tuple_as_dict: bool = False,
|
|
verbose: bool = False,
|
|
):
|
|
"""
|
|
Convert a ZON file to JSON.
|
|
|
|
Args:
|
|
zon_file: Path to the ZON file
|
|
output: Output file (default: stdout)
|
|
indent: Indentation for the JSON output
|
|
empty_tuple_as_dict: Parse empty tuples as empty dictionaries
|
|
verbose: Enable verbose logging
|
|
"""
|
|
# Set up logging
|
|
setup_logger(verbose)
|
|
|
|
try:
|
|
# Read the ZON file
|
|
with open(zon_file, "r", encoding="utf-8") as f:
|
|
zon_content = f.read()
|
|
|
|
# Convert to JSON
|
|
json_content = zon_to_json(
|
|
zon_content, indent=indent, empty_tuple_as_dict=empty_tuple_as_dict
|
|
)
|
|
|
|
# Output the JSON
|
|
if output:
|
|
with open(output, "w", encoding="utf-8") as f:
|
|
f.write(json_content)
|
|
logger.info(f"JSON written to {output}")
|
|
return json_content
|
|
else:
|
|
click.echo(json_content)
|
|
return json_content
|
|
|
|
except FileNotFoundError:
|
|
logger.error(f"File not found: {zon_file}")
|
|
sys.exit(1)
|
|
except Exception as e:
|
|
logger.error(f"Error: {e}")
|
|
sys.exit(1)
|
|
|
|
|
|
@click.group()
|
|
@click.option("-v", "--verbose", is_flag=True, help="Enable verbose logging")
|
|
@click.pass_context
|
|
def cli(ctx: click.Context, verbose: bool):
|
|
"""Zig package manager utilities."""
|
|
# Set up logging
|
|
setup_logger(verbose)
|
|
|
|
# Ensure we have a context object
|
|
ctx.ensure_object(dict)
|
|
ctx.obj["VERBOSE"] = verbose
|
|
|
|
|
|
@cli.command()
|
|
@click.argument("zon_file", type=click.Path(exists=True, readable=True, path_type=Path))
|
|
@click.option(
|
|
"--recursive",
|
|
"-r",
|
|
is_flag=True,
|
|
help="Recursively process dependencies from downloaded artifacts or scan directories",
|
|
)
|
|
@click.pass_context
|
|
def download(ctx: click.Context, zon_file: Path, recursive: bool):
|
|
"""
|
|
Download dependencies from a ZON file or directory.
|
|
|
|
If ZON_FILE is a directory, all build.zig.zon files will be processed.
|
|
If --recursive is specified, all dependencies of dependencies will also be processed.
|
|
|
|
ZON_FILE: Path to the ZON file or directory to process
|
|
"""
|
|
logger.info(f"Processing dependencies from {zon_file}")
|
|
|
|
if zon_file.is_dir():
|
|
logger.info(f"{zon_file} is a directory, searching for build.zig.zon files")
|
|
|
|
dependencies = process_dependencies(str(zon_file), recursive=recursive)
|
|
|
|
if dependencies:
|
|
logger.info(f"Successfully processed {len(dependencies)} dependencies:")
|
|
for name, path in dependencies.items():
|
|
logger.info(f" - {name}: {path}")
|
|
else:
|
|
logger.warning("No dependencies were processed")
|
|
|
|
|
|
@cli.command()
|
|
@click.argument("zon_file", type=click.Path(exists=True, readable=True, path_type=Path))
|
|
@click.option(
|
|
"-o",
|
|
"--output",
|
|
type=click.Path(writable=True, path_type=Path),
|
|
help="Output file (default: stdout)",
|
|
)
|
|
@click.option(
|
|
"-i", "--indent", type=int, default=2, help="Indentation for the JSON output"
|
|
)
|
|
@click.option(
|
|
"--empty-tuple-as-dict",
|
|
is_flag=True,
|
|
help="Parse empty tuples as empty dictionaries",
|
|
)
|
|
@click.pass_context
|
|
def convert(
|
|
ctx: click.Context,
|
|
zon_file: Path,
|
|
output: Optional[Path],
|
|
indent: int,
|
|
empty_tuple_as_dict: bool,
|
|
):
|
|
"""
|
|
Convert a ZON file to JSON.
|
|
|
|
ZON_FILE: Path to the ZON file to convert
|
|
"""
|
|
# Use the shared convert function
|
|
convert_zon_to_json(
|
|
zon_file=zon_file,
|
|
output=output,
|
|
indent=indent,
|
|
empty_tuple_as_dict=empty_tuple_as_dict,
|
|
verbose=ctx.obj.get("VERBOSE", False),
|
|
)
|
|
|
|
|
|
@click.command()
|
|
@click.argument("zon_file", type=click.Path(exists=True, readable=True, path_type=Path))
|
|
@click.option(
|
|
"-o",
|
|
"--output",
|
|
type=click.Path(writable=True, path_type=Path),
|
|
help="Output file (default: stdout)",
|
|
)
|
|
@click.option(
|
|
"-i", "--indent", type=int, default=2, help="Indentation for the JSON output"
|
|
)
|
|
@click.option(
|
|
"--empty-tuple-as-dict",
|
|
is_flag=True,
|
|
help="Parse empty tuples as empty dictionaries",
|
|
)
|
|
@click.option("-v", "--verbose", is_flag=True, help="Enable verbose logging")
|
|
def zon2json(zon_file, output, indent, empty_tuple_as_dict, verbose):
|
|
"""
|
|
Convert a ZON file to JSON.
|
|
|
|
ZON_FILE: Path to the ZON file to convert
|
|
"""
|
|
# Use the shared convert function
|
|
convert_zon_to_json(
|
|
zon_file=zon_file,
|
|
output=output,
|
|
indent=indent,
|
|
empty_tuple_as_dict=empty_tuple_as_dict,
|
|
verbose=verbose,
|
|
)
|
|
|
|
|
|
def main():
|
|
"""Entry point for the zig-fetch CLI."""
|
|
cli() # pylint: disable=no-value-for-parameter
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|