mirror of
https://github.com/macaodha/batdetect2.git
synced 2026-07-07 21:00:10 +02:00
feat: add CLI log file output
This commit is contained in:
parent
920eea690f
commit
0a8787e5f1
@ -1,5 +1,7 @@
|
|||||||
"""BatDetect2 command line interface."""
|
"""BatDetect2 command line interface."""
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
import click
|
import click
|
||||||
|
|
||||||
from batdetect2.cli.ascii import BATDETECT_ASCII_ART
|
from batdetect2.cli.ascii import BATDETECT_ASCII_ART
|
||||||
@ -22,8 +24,17 @@ BatDetect2
|
|||||||
count=True,
|
count=True,
|
||||||
help="Increase verbosity. -v for INFO, -vv for DEBUG.",
|
help="Increase verbosity. -v for INFO, -vv for DEBUG.",
|
||||||
)
|
)
|
||||||
|
@click.option(
|
||||||
|
"--log-file",
|
||||||
|
type=click.Path(path_type=Path),
|
||||||
|
help="Write CLI logs to a file in addition to the terminal.",
|
||||||
|
)
|
||||||
@click.pass_context
|
@click.pass_context
|
||||||
def cli(ctx: click.Context, verbose: int = 0):
|
def cli(
|
||||||
|
ctx: click.Context,
|
||||||
|
verbose: int = 0,
|
||||||
|
log_file: Path | None = None,
|
||||||
|
) -> None:
|
||||||
"""Run the BatDetect2 CLI.
|
"""Run the BatDetect2 CLI.
|
||||||
|
|
||||||
Use subcommands to run processing, training, evaluation, and dataset
|
Use subcommands to run processing, training, evaluation, and dataset
|
||||||
@ -37,4 +48,4 @@ def cli(ctx: click.Context, verbose: int = 0):
|
|||||||
|
|
||||||
from batdetect2.logging import enable_logging
|
from batdetect2.logging import enable_logging
|
||||||
|
|
||||||
enable_logging(verbose)
|
enable_logging(verbose, log_file=log_file)
|
||||||
|
|||||||
@ -50,7 +50,7 @@ __all__ = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def enable_logging(level: int):
|
def enable_logging(level: int, log_file: Path | None = None) -> None:
|
||||||
logger.remove()
|
logger.remove()
|
||||||
|
|
||||||
if level == 0:
|
if level == 0:
|
||||||
@ -61,6 +61,11 @@ def enable_logging(level: int):
|
|||||||
log_level = "DEBUG"
|
log_level = "DEBUG"
|
||||||
|
|
||||||
logger.add(sys.stderr, level=log_level)
|
logger.add(sys.stderr, level=log_level)
|
||||||
|
|
||||||
|
if log_file is not None:
|
||||||
|
log_file.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
logger.add(log_file, level=log_level)
|
||||||
|
|
||||||
logger.enable("batdetect2")
|
logger.enable("batdetect2")
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,18 +1,58 @@
|
|||||||
"""Behavior-focused tests for top-level CLI command discovery."""
|
"""Behavior-focused tests for top-level CLI command discovery."""
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
from click.testing import CliRunner
|
from click.testing import CliRunner
|
||||||
|
|
||||||
from batdetect2.cli import cli
|
from batdetect2.cli import cli
|
||||||
|
|
||||||
|
|
||||||
|
BASE_DIR = Path(__file__).parent.parent.parent
|
||||||
|
|
||||||
|
|
||||||
def test_cli_base_help_lists_main_commands() -> None:
|
def test_cli_base_help_lists_main_commands() -> None:
|
||||||
"""User story: discover available workflows from top-level help."""
|
"""User story: discover available workflows from top-level help."""
|
||||||
|
|
||||||
result = CliRunner().invoke(cli, ["--help"])
|
result = CliRunner().invoke(cli, ["--help"])
|
||||||
|
|
||||||
assert result.exit_code == 0
|
assert result.exit_code == 0
|
||||||
|
assert "--log-file" in result.output
|
||||||
assert "process" in result.output
|
assert "process" in result.output
|
||||||
assert "train" in result.output
|
assert "train" in result.output
|
||||||
assert "evaluate" in result.output
|
assert "evaluate" in result.output
|
||||||
assert "data" in result.output
|
assert "data" in result.output
|
||||||
assert "detect" in result.output
|
assert "detect" in result.output
|
||||||
|
|
||||||
|
|
||||||
|
def test_cli_writes_logs_to_file_and_terminal(
|
||||||
|
tmp_path: Path,
|
||||||
|
tiny_checkpoint_path: Path,
|
||||||
|
) -> None:
|
||||||
|
"""User story: save CLI logs to a file while keeping terminal output."""
|
||||||
|
|
||||||
|
output_dir = tmp_path / "eval_out"
|
||||||
|
log_file = tmp_path / "logs" / "cli.log"
|
||||||
|
|
||||||
|
result = CliRunner().invoke(
|
||||||
|
cli,
|
||||||
|
[
|
||||||
|
"--log-file",
|
||||||
|
str(log_file),
|
||||||
|
"-v",
|
||||||
|
"evaluate",
|
||||||
|
str(BASE_DIR / "example_data" / "dataset.yaml"),
|
||||||
|
"--model",
|
||||||
|
str(tiny_checkpoint_path),
|
||||||
|
"--base-dir",
|
||||||
|
str(BASE_DIR),
|
||||||
|
"--workers",
|
||||||
|
"0",
|
||||||
|
"--output-dir",
|
||||||
|
str(output_dir),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result.exit_code == 0
|
||||||
|
assert "Initiating evaluation process..." in result.output
|
||||||
|
assert log_file.exists()
|
||||||
|
assert "Initiating evaluation process..." in log_file.read_text()
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user