From aa6abd6c42a52c1f2a50002f8e849ba6620c1746 Mon Sep 17 00:00:00 2001 From: Fraser Langton Date: Thu, 10 Oct 2024 09:24:28 +1100 Subject: [PATCH 1/4] improve setup --- CONTRIBUTING.rst | 27 ++++++++++++++++++++++++--- pyproject.toml | 12 ++++++++++++ requirements-dev.txt | 7 +++++++ setup.cfg | 7 ++++++- tox.ini | 11 +++-------- 5 files changed, 52 insertions(+), 12 deletions(-) create mode 100644 requirements-dev.txt diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 47b94a6f..6eb74fdb 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -52,20 +52,41 @@ To set up `import-linter` for local development: git clone git@github.com:your_name_here/import-linter.git +3. Setup venv:: + + virtualenv venv + + # On macOS/Linux: + source venv/bin/activate + # On Windows: + .\venv\Scripts\activate + + pip install -e . + pip install -r requirements-dev.txt + 3. Create a branch for local development:: git checkout -b name-of-your-bugfix-or-feature Now you can make your changes locally. -4. When you're done making changes, run all the checks with `tox `_ one command:: +4. Run tests/checks:: + + pytest + black src tests + flake8 src tests + mypy src tests + isort src tests + lint-imports + +5. When you're done making changes, run all the checks with `tox `_ one command:: tox -5. Commit your changes and push your branch to GitHub:: +6. Commit your changes and push your branch to GitHub:: git add . git commit -m "Your detailed description of your changes." git push origin name-of-your-bugfix-or-feature -6. Submit a pull request through the GitHub website. +7. Submit a pull request through the GitHub website. diff --git a/pyproject.toml b/pyproject.toml index 373faccc..ab2864dd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -58,17 +58,29 @@ namespaces = false [tool.black] line-length = 99 +extend-exclude = ''' +/( + docs + |venv + |\.tox +)/ +''' [tool.isort] +profile = "black" multi_line_output = 3 include_trailing_comma = "True" force_grid_wrap = 0 use_parentheses = "True" line_length = 99 +skip = ["docs", "venv", ".tox"] [tool.mypy] exclude = [ '^tests/assets/', + '^docs/*', + '^venv/*', + '^\.tox/', ] warn_unused_ignores = true warn_redundant_casts = true diff --git a/requirements-dev.txt b/requirements-dev.txt new file mode 100644 index 00000000..5fd5f356 --- /dev/null +++ b/requirements-dev.txt @@ -0,0 +1,7 @@ +PyYAML~=6.0.1 +black~=22.3.0 +flake8~=4.0.1 +mypy~=0.730 +pytest~=7.4.0 +pytest-cov~=4.1.0 +types-PyYAML diff --git a/setup.cfg b/setup.cfg index 5ed93adb..3bd03996 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,4 +1,9 @@ [flake8] ignore = E731, E203, W503 max-line-length = 100 -exclude = */migrations/*, tests/assets/* +exclude = + */migrations/*, + tests/assets/*, + .tox, + docs, + venv diff --git a/tox.ini b/tox.ini index 07e9b128..8fa0d453 100644 --- a/tox.ini +++ b/tox.ini @@ -22,9 +22,7 @@ passenv = * usedevelop = false deps = - pytest~=7.4.0 - pytest-cov~=4.1.0 - PyYAML~=6.0.1 + -r requirements-dev.txt commands = {posargs:pytest --cov --cov-report=term-missing -vv tests} @@ -32,14 +30,11 @@ commands = [testenv:check] deps = {[testenv]deps} - black~=22.3.0 - flake8~=4.0.1 - mypy~=0.730 - types-PyYAML commands = black --check src tests flake8 src tests - mypy src/importlinter tests + mypy src tests + isort --check src tests lint-imports [testenv:docs] From a3cdf5bce100a21ee9f54d5bd827eb2f93782861 Mon Sep 17 00:00:00 2001 From: Fraser Langton Date: Thu, 10 Oct 2024 10:12:13 +1100 Subject: [PATCH 2/4] do isort --- src/importlinter/adapters/user_options.py | 4 ++-- src/importlinter/application/contract_utils.py | 2 +- .../application/ports/reporting.py | 3 ++- src/importlinter/cli.py | 18 +++++++++++++----- src/importlinter/contracts/independence.py | 7 +------ src/importlinter/contracts/layers.py | 1 - src/importlinter/domain/helpers.py | 7 +------ .../multipleroots/rootpackageblue/one/alpha.py | 1 + tests/assets/testpackage/testpackage/utils.py | 1 - tests/helpers/contracts.py | 3 ++- tests/unit/contracts/test_layers.py | 2 +- 11 files changed, 24 insertions(+), 25 deletions(-) diff --git a/src/importlinter/adapters/user_options.py b/src/importlinter/adapters/user_options.py index 76fefa3d..f294d0d9 100644 --- a/src/importlinter/adapters/user_options.py +++ b/src/importlinter/adapters/user_options.py @@ -1,7 +1,7 @@ -import configparser -from typing import Any, Dict, Optional, List import abc +import configparser import sys +from typing import Any, Dict, List, Optional if sys.version_info >= (3, 11): import tomllib diff --git a/src/importlinter/application/contract_utils.py b/src/importlinter/application/contract_utils.py index b3e6e70d..b2632701 100644 --- a/src/importlinter/application/contract_utils.py +++ b/src/importlinter/application/contract_utils.py @@ -1,11 +1,11 @@ import enum from typing import List, Optional, Sequence, Set +from grimp import ImportGraph from importlinter.domain import helpers from importlinter.domain.helpers import MissingImport from importlinter.domain.imports import ImportExpression -from grimp import ImportGraph class AlertLevel(enum.Enum): diff --git a/src/importlinter/application/ports/reporting.py b/src/importlinter/application/ports/reporting.py index 59648b6b..a2bd4345 100644 --- a/src/importlinter/application/ports/reporting.py +++ b/src/importlinter/application/ports/reporting.py @@ -1,8 +1,9 @@ from typing import Dict, Iterator, List, Tuple -from importlinter.domain.contract import Contract, ContractCheck, InvalidContractOptions from grimp import ImportGraph +from importlinter.domain.contract import Contract, ContractCheck, InvalidContractOptions + class Reporter: ... diff --git a/src/importlinter/cli.py b/src/importlinter/cli.py index 084068b5..fd725fc1 100644 --- a/src/importlinter/cli.py +++ b/src/importlinter/cli.py @@ -1,15 +1,14 @@ import os import sys from logging import config as logging_config -from typing import Optional, Tuple, Type, Union +from typing import NoReturn, Optional, Tuple, Type, Union import click +from importlinter import configuration +from importlinter.application import use_cases from importlinter.application.sentinels import NotSupplied -from . import configuration -from .application import use_cases - configuration.configure() EXIT_STATUS_SUCCESS = 0 @@ -37,6 +36,7 @@ is_flag=True, help="Noisily output progress as we go along.", ) +@click.argument("files", nargs=-1, type=click.Path(exists=True)) def lint_imports_command( config: Optional[str], contract: Tuple[str, ...], @@ -45,7 +45,8 @@ def lint_imports_command( debug: bool, show_timings: bool, verbose: bool, -) -> int: + files: Tuple[str, ...], +) -> NoReturn: """ Check that a project adheres to a set of contracts. """ @@ -57,6 +58,7 @@ def lint_imports_command( is_debug_mode=debug, show_timings=show_timings, verbose=verbose, + files=files, ) sys.exit(exit_code) @@ -69,6 +71,7 @@ def lint_imports( is_debug_mode: bool = False, show_timings: bool = False, verbose: bool = False, + files: Tuple[str, ...] = (), ) -> int: """ Check that a project adheres to a set of contracts. @@ -85,6 +88,7 @@ def lint_imports( show_timings: whether to show the times taken to build the graph and to check each contract. verbose: if True, noisily output progress as it goes along. + files: the files to lint. If not provided, the entire project is linted. Returns: EXIT_STATUS_SUCCESS or EXIT_STATUS_ERROR. @@ -142,3 +146,7 @@ def _configure_logging(verbose: bool) -> None: }, } ) + + +if __name__ == "__main__": + lint_imports_command() diff --git a/src/importlinter/contracts/independence.py b/src/importlinter/contracts/independence.py index 9b60f72a..9835fec1 100644 --- a/src/importlinter/contracts/independence.py +++ b/src/importlinter/contracts/independence.py @@ -13,12 +13,7 @@ from importlinter.domain.helpers import module_expressions_to_modules from importlinter.domain.imports import Module -from ._common import ( - DetailedChain, - Link, - build_detailed_chain_from_route, - render_chain_data, -) +from ._common import DetailedChain, Link, build_detailed_chain_from_route, render_chain_data class _SubpackageChainData(TypedDict): diff --git a/src/importlinter/contracts/layers.py b/src/importlinter/contracts/layers.py index 5237974b..127e94fb 100644 --- a/src/importlinter/contracts/layers.py +++ b/src/importlinter/contracts/layers.py @@ -14,7 +14,6 @@ from ._common import DetailedChain, build_detailed_chain_from_route, render_chain_data - _INDEPENDENT_LAYER_DELIMITER = "|" _NON_INDEPENDENT_LAYER_DELIMITER = ":" diff --git a/src/importlinter/domain/helpers.py b/src/importlinter/domain/helpers.py index c253c64c..075cd37a 100644 --- a/src/importlinter/domain/helpers.py +++ b/src/importlinter/domain/helpers.py @@ -4,12 +4,7 @@ from grimp import DetailedImport, ImportGraph -from importlinter.domain.imports import ( - DirectImport, - ImportExpression, - Module, - ModuleExpression, -) +from importlinter.domain.imports import DirectImport, ImportExpression, Module, ModuleExpression class MissingImport(Exception): diff --git a/tests/assets/multipleroots/rootpackageblue/one/alpha.py b/tests/assets/multipleroots/rootpackageblue/one/alpha.py index cd49af75..e607ee20 100644 --- a/tests/assets/multipleroots/rootpackageblue/one/alpha.py +++ b/tests/assets/multipleroots/rootpackageblue/one/alpha.py @@ -1,4 +1,5 @@ import sys # Standard library import. + import pytest # Third party library import. BAR = "bar" diff --git a/tests/assets/testpackage/testpackage/utils.py b/tests/assets/testpackage/testpackage/utils.py index c34ece04..d157fc12 100644 --- a/tests/assets/testpackage/testpackage/utils.py +++ b/tests/assets/testpackage/testpackage/utils.py @@ -1,3 +1,2 @@ from pytest import mark - from testpackage.high import green diff --git a/tests/helpers/contracts.py b/tests/helpers/contracts.py index ddc83cba..8730bffc 100644 --- a/tests/helpers/contracts.py +++ b/tests/helpers/contracts.py @@ -1,7 +1,8 @@ +from grimp import ImportGraph + from importlinter.application import output from importlinter.domain import fields from importlinter.domain.contract import Contract, ContractCheck -from grimp import ImportGraph class AlwaysPassesContract(Contract): diff --git a/tests/unit/contracts/test_layers.py b/tests/unit/contracts/test_layers.py index 4eec5796..50cec5ff 100644 --- a/tests/unit/contracts/test_layers.py +++ b/tests/unit/contracts/test_layers.py @@ -3,9 +3,9 @@ from importlinter.application.app_config import settings from importlinter.contracts.layers import Layer, LayerField, LayersContract, ModuleTail +from importlinter.domain import fields from importlinter.domain.contract import ContractCheck, InvalidContractOptions from importlinter.domain.helpers import MissingImport -from importlinter.domain import fields from tests.adapters.printing import FakePrinter from tests.adapters.timing import FakeTimer From fef0ca7473b8cd1a214fcd705ba15843d9ebdb86 Mon Sep 17 00:00:00 2001 From: Fraser Langton Date: Thu, 10 Oct 2024 10:22:44 +1100 Subject: [PATCH 3/4] do isort --- src/importlinter/cli.py | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/src/importlinter/cli.py b/src/importlinter/cli.py index fd725fc1..084068b5 100644 --- a/src/importlinter/cli.py +++ b/src/importlinter/cli.py @@ -1,14 +1,15 @@ import os import sys from logging import config as logging_config -from typing import NoReturn, Optional, Tuple, Type, Union +from typing import Optional, Tuple, Type, Union import click -from importlinter import configuration -from importlinter.application import use_cases from importlinter.application.sentinels import NotSupplied +from . import configuration +from .application import use_cases + configuration.configure() EXIT_STATUS_SUCCESS = 0 @@ -36,7 +37,6 @@ is_flag=True, help="Noisily output progress as we go along.", ) -@click.argument("files", nargs=-1, type=click.Path(exists=True)) def lint_imports_command( config: Optional[str], contract: Tuple[str, ...], @@ -45,8 +45,7 @@ def lint_imports_command( debug: bool, show_timings: bool, verbose: bool, - files: Tuple[str, ...], -) -> NoReturn: +) -> int: """ Check that a project adheres to a set of contracts. """ @@ -58,7 +57,6 @@ def lint_imports_command( is_debug_mode=debug, show_timings=show_timings, verbose=verbose, - files=files, ) sys.exit(exit_code) @@ -71,7 +69,6 @@ def lint_imports( is_debug_mode: bool = False, show_timings: bool = False, verbose: bool = False, - files: Tuple[str, ...] = (), ) -> int: """ Check that a project adheres to a set of contracts. @@ -88,7 +85,6 @@ def lint_imports( show_timings: whether to show the times taken to build the graph and to check each contract. verbose: if True, noisily output progress as it goes along. - files: the files to lint. If not provided, the entire project is linted. Returns: EXIT_STATUS_SUCCESS or EXIT_STATUS_ERROR. @@ -146,7 +142,3 @@ def _configure_logging(verbose: bool) -> None: }, } ) - - -if __name__ == "__main__": - lint_imports_command() From 0dee2bd38e68a6b1735a5d352313dd077ebfaaa0 Mon Sep 17 00:00:00 2001 From: Fraser Langton Date: Thu, 10 Oct 2024 10:23:28 +1100 Subject: [PATCH 4/4] improve setup --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 8fa0d453..f987ea34 100644 --- a/tox.ini +++ b/tox.ini @@ -32,9 +32,9 @@ deps = {[testenv]deps} commands = black --check src tests + isort --check src tests flake8 src tests mypy src tests - isort --check src tests lint-imports [testenv:docs]