From c5b9a16a1af1ed4b8bdb435b8b35505ab6369016 Mon Sep 17 00:00:00 2001 From: drorganvidez Date: Mon, 25 Mar 2024 19:25:40 +0100 Subject: [PATCH] feat: Implement rosemary coverage command --- .gitignore | 4 +++- README.md | 25 +++++++++++++++++++++++++ requirements.txt | 2 ++ rosemary/cli.py | 2 ++ rosemary/commands/coverage.py | 30 ++++++++++++++++++++++++++++++ 5 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 rosemary/commands/coverage.py diff --git a/.gitignore b/.gitignore index 8522fcf0..ae63ad2d 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,6 @@ uploads/ app.log .DS_Store rosemary.egg-info/ -build/ \ No newline at end of file +build/ +.coverage +htmlcov/ \ No newline at end of file diff --git a/README.md b/README.md index 967845f1..85d1fb15 100644 --- a/README.md +++ b/README.md @@ -129,6 +129,31 @@ use: rosemary test zenodo ``` +### Code Coverage + +The `rosemary coverage` command facilitates running code coverage analysis for your Flask project using `pytest-cov`. +This command simplifies the process of assessing test coverage. + +#### Command Usage + +- **All Modules**: To run coverage analysis for all modules within the `app/blueprints` directory and generate an HTML report, use: + + ``` + rosemary coverage + ``` + +- **Specific Module**: If you wish to run coverage analysis for a specific module, include the +module name: + + ``` + rosemary coverage + ``` + +#### Command Options + +- **--html**: Generates an HTML coverage report. The report is saved in the `htmlcov` directory +at the root of your project. Example: `rosemary coverage --html` + ## Deploy in production (Docker Compose) ``` diff --git a/requirements.txt b/requirements.txt index a8754311..229d0247 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,6 +4,7 @@ certifi==2024.2.2 cffi==1.16.0 charset-normalizer==3.3.2 click==8.1.7 +coverage==7.4.4 cryptography==42.0.5 dnspython==2.6.1 email_validator==2.1.1 @@ -29,6 +30,7 @@ pycparser==2.21 pyflakes==3.2.0 PyMySQL==1.1.0 pytest==8.1.1 +pytest-cov==5.0.0 python-dotenv==1.0.1 requests==2.31.0 rosemary @ file:///app diff --git a/rosemary/cli.py b/rosemary/cli.py index 96055d3c..a35590bc 100644 --- a/rosemary/cli.py +++ b/rosemary/cli.py @@ -1,5 +1,6 @@ import click +from rosemary.commands.coverage import coverage from rosemary.commands.linter import linter from rosemary.commands.update import update from rosemary.commands.info import info @@ -30,6 +31,7 @@ def cli(): cli.add_command(env) cli.add_command(test) cli.add_command(linter) +cli.add_command(coverage) if __name__ == '__main__': cli() diff --git a/rosemary/commands/coverage.py b/rosemary/commands/coverage.py new file mode 100644 index 00000000..ecbb3661 --- /dev/null +++ b/rosemary/commands/coverage.py @@ -0,0 +1,30 @@ +import click +import subprocess +import os + + +@click.command('coverage', help="Runs pytest coverage on the blueprints directory or a specific module.") +@click.argument('module_name', required=False) +@click.option('--html', is_flag=True, help="Generates an HTML coverage report.") +def coverage(module_name, html): + base_path = 'app/blueprints' + test_path = base_path + + if module_name: + test_path = os.path.join(base_path, module_name) + if not os.path.exists(test_path): + click.echo(click.style(f"Module '{module_name}' does not exist.", fg='red')) + return + click.echo(f"Running coverage for the '{module_name}' module...") + else: + click.echo("Running coverage for all modules...") + + coverage_cmd = ['pytest', '--cov=' + test_path, test_path] + + if html: + coverage_cmd.extend(['--cov-report', 'html']) + + try: + subprocess.run(coverage_cmd, check=True) + except subprocess.CalledProcessError as e: + click.echo(click.style(f"Error running coverage: {e}", fg='red'))