tux.cli.dev
¶
Development tools and utilities for Tux.
Functions:
Name | Description |
---|---|
lint | Run linting with Ruff. |
lint_fix | Run linting with Ruff and apply fixes. |
format_code | Format code with Ruff. |
type_check | Check types with Pyright. |
check | Run pre-commit checks. |
test | Run tests with coverage. |
test_quick | Run tests without coverage (faster). |
coverage | Generate coverage reports with various options. |
coverage_clean | Clean coverage files and reports. |
coverage_open | Open HTML coverage report in browser. |
Functions¶
lint() -> int
¶
lint_fix() -> int
¶
format_code() -> int
¶
type_check() -> int
¶
check() -> int
¶
test() -> int
¶
test_quick() -> int
¶
_build_coverage_command(specific: str | None, quick: bool, report_format: str, fail_under: int | None) -> list[str]
¶
Build the pytest coverage command with options.
Source code in tux/cli/dev.py
Python
def _build_coverage_command(specific: str | None, quick: bool, report_format: str, fail_under: int | None) -> list[str]:
"""Build the pytest coverage command with options."""
cmd = ["pytest"]
# Set coverage path (specific or default)
if specific:
logger.info(f"๐ Running coverage for specific path: {specific}")
cmd.append(f"--cov={specific}")
else:
cmd.append("--cov=tux")
# Handle quick mode (no reports)
if quick:
logger.info("โก Quick coverage check (no reports)...")
cmd.append("--cov-report=")
return cmd
# Add report format
_add_report_format(cmd, report_format)
# Add fail-under if specified
if fail_under is not None:
logger.info(f"๐ฏ Running with {fail_under}% coverage threshold...")
cmd.extend(["--cov-fail-under", str(fail_under)])
return cmd
_add_report_format(cmd: list[str], report_format: str) -> None
¶
Add report format option to command.
Source code in tux/cli/dev.py
Python
def _add_report_format(cmd: list[str], report_format: str) -> None:
"""Add report format option to command."""
match report_format:
case "term":
logger.info("๐ Running tests with terminal coverage report...")
cmd.append("--cov-report=term-missing")
case "html":
logger.info("๐ Generating HTML coverage report...")
cmd.append("--cov-report=html")
case "xml":
logger.info("๐ Generating XML coverage report...")
cmd.append("--cov-report=xml")
case "json":
logger.info("๐ Generating JSON coverage report...")
cmd.append("--cov-report=json")
case _:
# Default case - should not happen due to click choices
cmd.append("--cov-report=term-missing")
_handle_post_coverage_actions(result: int, report_format: str, open_browser: bool) -> None
¶
Handle post-command actions after coverage run.
Source code in tux/cli/dev.py
Python
def _handle_post_coverage_actions(result: int, report_format: str, open_browser: bool) -> None:
"""Handle post-command actions after coverage run."""
if result != 0:
return
match report_format:
case "html":
logger.success("โ
HTML report generated at: htmlcov/index.html")
if open_browser:
logger.info("๐ Opening HTML coverage report...")
try:
webbrowser.open("htmlcov/index.html")
except Exception:
logger.warning("Could not open browser. HTML report is available at htmlcov/index.html")
case "xml":
logger.success("โ
XML report generated at: coverage.xml")
case "json":
logger.success("โ
JSON report generated at: coverage.json")
case _:
# For terminal or other formats, no specific post-action needed
pass
coverage(report_format: str, fail_under: int | None, open: bool, quick: bool, clean: bool, specific: str | None) -> int
¶
Generate coverage reports with various options.
Source code in tux/cli/dev.py
Python
@command_registration_decorator(dev_group, name="coverage")
@click.option(
"--format",
"report_format",
type=click.Choice(["term", "html", "xml", "json"], case_sensitive=False),
default="term",
help="Coverage report format",
)
@click.option(
"--fail-under",
type=click.IntRange(0, 100),
help="Fail if coverage is below this percentage",
)
@click.option(
"--open",
is_flag=True,
help="Open HTML report in browser (only with --format=html)",
)
@click.option(
"--quick",
is_flag=True,
help="Quick coverage check without generating reports",
)
@click.option(
"--clean",
is_flag=True,
help="Clean coverage files before running",
)
@click.option(
"--specific",
type=str,
help="Run coverage for specific path (e.g., tux/utils)",
)
def coverage(
report_format: str,
fail_under: int | None,
open: bool, # noqa: A002
quick: bool,
clean: bool,
specific: str | None,
) -> int:
"""Generate coverage reports with various options."""
# Clean first if requested
if clean:
logger.info("๐งน Cleaning coverage files...")
coverage_clean()
# Build and run command
cmd = _build_coverage_command(specific, quick, report_format, fail_under)
result = run_command(cmd)
# Handle post-command actions
_handle_post_coverage_actions(result, report_format, open)
return result
coverage_clean() -> int
¶
Clean coverage files and reports.
Source code in tux/cli/dev.py
Python
@command_registration_decorator(dev_group, name="coverage-clean")
def coverage_clean() -> int:
"""Clean coverage files and reports."""
logger.info("๐งน Cleaning coverage files...")
files_to_remove = [".coverage", "coverage.xml", "coverage.json"]
dirs_to_remove = ["htmlcov"]
# Remove individual files
for file_name in files_to_remove:
file_path = Path(file_name)
try:
if file_path.exists():
file_path.unlink()
logger.info(f"Removed {file_name}")
except OSError as e:
logger.error(f"Error removing {file_name}: {e}")
# Remove directories
for dir_name in dirs_to_remove:
dir_path = Path(dir_name)
try:
if dir_path.exists():
shutil.rmtree(dir_path)
logger.info(f"Removed {dir_name}")
except OSError as e:
logger.error(f"Error removing {dir_name}: {e}")
# Remove .coverage.* pattern files using Path.glob
cwd = Path()
for coverage_file in cwd.glob(".coverage.*"):
try:
coverage_file.unlink()
logger.info(f"Removed {coverage_file.name}")
except OSError as e:
logger.error(f"Error removing {coverage_file.name}: {e}")
logger.success("โ
Coverage files cleaned")
return 0
coverage_open() -> int
¶
Open HTML coverage report in browser.
Source code in tux/cli/dev.py
Python
@command_registration_decorator(dev_group, name="coverage-open")
def coverage_open() -> int:
"""Open HTML coverage report in browser."""
html_report = Path("htmlcov/index.html")
if not html_report.exists():
logger.error("โ HTML report not found. Run 'poetry run tux dev coverage --format=html' first")
return 1
logger.info("๐ Opening HTML coverage report...")
try:
webbrowser.open(str(html_report))
except Exception as e:
logger.error(f"Could not open browser: {e}")
logger.info(f"HTML report is available at: {html_report}")
return 1
else:
logger.success("โ
Coverage report opened in browser")
return 0