Skip to content

Commit

Permalink
Set baseline as cli arg (#11)
Browse files Browse the repository at this point in the history
  • Loading branch information
blablatdinov authored May 27, 2024
1 parent 0bcf589 commit eddb975
Show file tree
Hide file tree
Showing 8 changed files with 186 additions and 4 deletions.
9 changes: 7 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,10 @@ lint:
poetry run flake8 ondivi tests
poetry run mypy ondivi tests --strict

test:
poetry run pytest --cov=ondivi --cov-report=term-missing:skip-covered -vv
test: unit it

unit:
poetry run pytest tests/unit --cov=ondivi --cov-report=term-missing:skip-covered -vv

it: # integration tests
poetry run pytest tests/it -s -vv
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,27 @@ Run the script:
flake8 script.py | ondivi
```

```bash
ondivi -h
```

```
usage: ondivi [-h] [--baseline BASELINE]
Ondivi (Only diff violations).
Python script filtering coding violations, identified by static analysis,
only for changed lines in a Git repo.
Usage example:
flake8 script.py | ondivi
optional arguments:
-h, --help show this help message and exit
--baseline BASELINE Commit or branch which will contain legacy code. Program filter out violations on baseline (default: "origin/master..HEAD")
```

## How it Works

The script parses the Git diff output to identify the changed lines in each file.
Expand Down
26 changes: 25 additions & 1 deletion ondivi/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
only for changed lines in a Git repo.
"""

import argparse
import sys
from contextlib import suppress

Expand Down Expand Up @@ -99,13 +100,36 @@ def controller(diff: Diff, violations: list[str]) -> list[str]:

def main() -> None:
"""Entrypoint."""
parser = argparse.ArgumentParser(
description='\n'.join([
'Ondivi (Only diff violations).\n',
'Python script filtering coding violations, identified by static analysis,',
'only for changed lines in a Git repo.\n',
'Usage example:\n',
'flake8 script.py | ondivi',
]),
formatter_class=argparse.RawTextHelpFormatter,
)
parser.add_argument(
'--baseline',
dest='baseline',
type=str,
default='master',
help=' '.join([
'Commit or branch which will contain legacy code.',
'Program filter out violations on baseline',
'(default: "master")',
]),
)
args = parser.parse_args()
violations = sys.stdin.read().strip().splitlines()
sys.stdout.write('\n'.join(
controller(
Repo('.').git.diff('--unified=0', 'origin/master..HEAD'),
Repo('.').git.diff('--unified=0', args.baseline),
violations,
),
))
sys.stdout.write('\n')


if __name__ == '__main__':
Expand Down
51 changes: 50 additions & 1 deletion poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ pytest-cov = "5.0.0"
mypy = "1.10.0"
deltaver = "0.2.1"
mutmut = "2.5.0"
pytest-randomly = "3.15.0"

[tool.isort]
line_length = 120
Expand All @@ -61,6 +62,7 @@ ignore = [
"ARG002", # Unused method argument
"D203", # no-blank-line-before-class
"D213", # multi-line-summary-first-line
"D401", # First line of docstring should be in imperative mood
"D418", # Function decorated with `@overload` shouldn't contain a docstring
"FBT001", # Boolean-typed positional argument in function definition
"FBT002", # Boolean-typed positional argument in function definition
Expand Down
Binary file added tests/fixtures/ondivi-test-repo.zip
Binary file not shown.
81 changes: 81 additions & 0 deletions tests/it/test_app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# The MIT License (MIT).
#
# Copyright (c) 2024 Almaz Ilaletdinov <[email protected]>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
# OR OTHER DEALINGS IN THE SOFTWARE.

"""Integration test with installing and check on real git repo."""

import os
import subprocess
import zipfile
from pathlib import Path

import pytest
from _pytest.legacypath import TempdirFactory


@pytest.fixture(scope='module')
def current_dir() -> Path:
"""Current directory for installing actual ondivi."""
return Path().absolute()


# flake8: noqa: S603, S607. Not a production code
@pytest.fixture(scope='module')
def _test_repo(tmpdir_factory: TempdirFactory, current_dir: str) -> None:
"""Real git repository."""
tmp_path = tmpdir_factory.mktemp('test')
with zipfile.ZipFile('tests/fixtures/ondivi-test-repo.zip', 'r') as zip_ref:
zip_ref.extractall(tmp_path)
os.chdir(tmp_path / 'ondivi-test-repo')
subprocess.run(['python', '-m', 'venv', 'venv'], check=True)
subprocess.run(['venv/bin/pip', 'install', 'flake8', str(current_dir)], check=True)


@pytest.mark.usefixtures('_test_repo')
def test() -> None:
"""Test script with real git repo."""
got = subprocess.run(
['ondivi', '--baseline', '56faa56'],
stdin=subprocess.Popen(
['venv/bin/flake8', 'file.py'],
stdout=subprocess.PIPE,
).stdout,
stdout=subprocess.PIPE,
check=False,
).stdout.decode('utf-8').strip()

assert got == 'file.py:4:80: E501 line too long (119 > 79 characters)'


@pytest.mark.usefixtures('_test_repo')
def test_baseline_default() -> None:
"""Test baseline default."""
got = subprocess.run(
['ondivi'],
stdin=subprocess.Popen(
['venv/bin/flake8', 'file.py'],
stdout=subprocess.PIPE,
).stdout,
stdout=subprocess.PIPE,
check=False,
).stdout.decode('utf-8').strip()

assert got == 'file.py:4:80: E501 line too long (119 > 79 characters)'
File renamed without changes.

0 comments on commit eddb975

Please sign in to comment.