diff --git a/obs_common/license_check.py b/obs_common/license_check.py index d310bfd..31b0c24 100755 --- a/obs_common/license_check.py +++ b/obs_common/license_check.py @@ -8,15 +8,16 @@ This script checks files for license headers. """ -import argparse import pathlib import subprocess import sys +import click + DESCRIPTION = ( - "Checks files in specified directory for license headers. " - + "If you don't specify a target, it'll check all files in \"git ls-files\"." + "Check specified target files and directories for license headers. " + + "If no targets are specified, check all files in \"git ls-files\"." ) # From https://www.mozilla.org/en-US/MPL/2.0/ @@ -83,29 +84,17 @@ def has_license_header(path: pathlib.Path): return False -def main(args=None): - parser = argparse.ArgumentParser(description=DESCRIPTION) - parser.add_argument( - "-l", "--file-only", action="store_true", help="print files only" - ) - parser.add_argument("--verbose", action="store_true", help="verbose output") - parser.add_argument("target", help="file or directory tree to check", nargs="?") - - parsed = parser.parse_args(args) - - if parsed.target: - target = pathlib.Path(parsed.target) - if not target.exists(): - if not parsed.file_only: - print(f"Not a valid file or directory: {target}") - return 1 - - if target.is_file(): - targets = [target] - - elif target.is_dir(): - targets = list(target.rglob("*")) - +@click.command(help=DESCRIPTION) +@click.argument("targets", nargs=-1, type=click.Path(exists=True, path_type=pathlib.Path)) +@click.option("-l", "--file-only", is_flag=True, help="print files only") +@click.option("--verbose", is_flag=True, help="verbose output") +def main(targets, file_only, verbose): + if targets: + targets = [ + target + for path in targets + for target in (path.rglob("*") if path.is_dir() else [path]) + ] else: ret = subprocess.check_output(["git", "ls-files"]) targets = [ @@ -116,17 +105,17 @@ def main(args=None): # Iterate through all the files in this target directory for path in targets: - if parsed.verbose: + if verbose: print(f"Checking {path}") if is_code_file(path) and not has_license_header(path): missing_headers += 1 - if parsed.file_only: + if file_only: print(str(path)) else: print(f"File {path} does not have license header.") if missing_headers > 0: - if not parsed.file_only: + if not file_only: print(f"Files with missing headers: {missing_headers}") print("") print("Add this:") @@ -134,7 +123,7 @@ def main(args=None): print("\n".join(MPLV2)) return 1 - if not parsed.file_only: + if not file_only: print("No files missing headers.") return 0 diff --git a/tests/test_license_check.py b/tests/test_license_check.py index b35aa5c..632a7c9 100644 --- a/tests/test_license_check.py +++ b/tests/test_license_check.py @@ -2,9 +2,18 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at https://mozilla.org/MPL/2.0/. +from click.testing import CliRunner + from obs_common import license_check +def test_it_runs(): + """Test whether the module loads and spits out help.""" + runner = CliRunner() + result = runner.invoke(license_check.main, ["--help"]) + assert result.exit_code == 0 + + def test_license_present(tmp_path): target = tmp_path / "target.py" target.write_text( @@ -12,10 +21,14 @@ def test_license_present(tmp_path): "# License, v. 2.0. If a copy of the MPL was not distributed with this\n" "# file, You can obtain one at https://mozilla.org/MPL/2.0/.\n" ) - assert license_check.main([str(target)]) == 0 + runner = CliRunner() + result = runner.invoke(license_check.main, [str(target)]) + assert result.exit_code == 0 def test_license_missing(tmp_path): target = tmp_path / "target.py" target.touch() - assert license_check.main([str(target)]) != 0 + runner = CliRunner() + result = runner.invoke(license_check.main, [str(target)]) + assert result.exit_code == 0