diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 37454a5..092bc62 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -1,3 +1,4 @@ +--- name: Run tests on: @@ -6,31 +7,7 @@ on: pull_request: jobs: - setup: - runs-on: ubuntu-latest - outputs: - strategy: ${{steps.load.outputs.strategy}} - - steps: - - uses: actions/checkout@v2 - with: - repository: colcon/ci - - id: load - run: echo "::set-output name=strategy::$(echo $(cat strategy.json))" - pytest: - needs: [setup] - strategy: ${{fromJson(needs.setup.outputs.strategy)}} - runs-on: ${{matrix.os}} - - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-python@v2 - with: - python-version: ${{matrix.python}} - - uses: colcon/ci@v1 - - uses: actions/upload-artifact@v2 - with: - name: coverage - path: ./**/coverage.xml - - uses: codecov/codecov-action@v3 + uses: colcon/ci/.github/workflows/pytest.yaml@main + with: + codecov: true diff --git a/publish-python.yaml b/publish-python.yaml new file mode 100644 index 0000000..0f65d5c --- /dev/null +++ b/publish-python.yaml @@ -0,0 +1,14 @@ +artifacts: + - type: wheel + uploads: + - type: pypi + - type: stdeb + uploads: + - type: packagecloud + config: + repository: dirk-thomas/colcon + distributions: + - ubuntu:jammy + - ubuntu:noble + - debian:bookworm + - debian:trixie diff --git a/setup.cfg b/setup.cfg index 75863d0..596c261 100644 --- a/setup.cfg +++ b/setup.cfg @@ -22,19 +22,23 @@ classifiers = license = Apache License, Version 2.0 description = Extension for colcon to cache the processing of packages. long_description = file: README.md +long_description_content_type = text/markdown keywords = colcon [options] +python_requires = >=3.6 install_requires = colcon-core>=0.5.2 dirhash GitPython + scantree<0.0.2a0 scandir;platform_system=='Windows' packages = find: zip_safe = true [options.extras_require] test = + colcon-defaults colcon-package-information>=0.3.3 colcon-package-selection>=0.2.10 colcon-recursive-crawl @@ -60,11 +64,15 @@ exclude = test [tool:pytest] filterwarnings = error + ignore::DeprecationWarning:colcon_defaults: ignore::DeprecationWarning:flake8: ignore::DeprecationWarning:scantree.*: ignore:lib2to3 package is deprecated::scspell ignore::pytest.PytestUnraisableExceptionWarning junit_suite_name = colcon-cache +markers = + flake8 + linter [options.entry_points] colcon_core.event_handler = diff --git a/stdeb.cfg b/stdeb.cfg index b175016..7184942 100644 --- a/stdeb.cfg +++ b/stdeb.cfg @@ -1,5 +1,5 @@ [colcon-cache] No-Python2: Depends3: python3-colcon-core (>= 0.5.2), python3-dirhash, python3-scantree -Suite: jammy +Suite: jammy noble bookworm trixie X-Python3-Version: >= 3.6 diff --git a/test/spell_check.words b/test/spell_check.words index 38d7f1e..e7ebb19 100644 --- a/test/spell_check.words +++ b/test/spell_check.words @@ -23,6 +23,7 @@ hexdigest hexsha https iterdir +linter lockfile lockfiles mkdtemp @@ -30,6 +31,7 @@ nargs noqa pathlib plugin +pydocstyle pytest rmtree rtype diff --git a/test/test_copyright_license.py b/test/test_copyright_license.py index e701370..dffe460 100644 --- a/test/test_copyright_license.py +++ b/test/test_copyright_license.py @@ -4,7 +4,10 @@ from pathlib import Path import sys +import pytest + +@pytest.mark.linter def test_copyright_license(): missing = check_files([Path(__file__).parents[1]]) assert not len(missing), \ @@ -25,8 +28,8 @@ def check_files(paths): if not content: continue lines = content.splitlines() - has_copyright = \ - any(line for line in lines if line.startswith('# Copyright')) + has_copyright = any(filter( + lambda line: line.startswith('# Copyright'), lines)) has_license = \ '# Licensed under the Apache License, Version 2.0' in lines if not has_copyright or not has_license: diff --git a/test/test_flake8.py b/test/test_flake8.py index f820191..ab5980f 100644 --- a/test/test_flake8.py +++ b/test/test_flake8.py @@ -5,15 +5,21 @@ from pathlib import Path import sys -from flake8 import LOG -from flake8.api.legacy import get_style_guide +import pytest -# avoid debug and info messages from flake8 internals -LOG.setLevel(logging.WARN) +@pytest.mark.flake8 +@pytest.mark.linter +def test_flake8(): + from flake8.api.legacy import get_style_guide + # avoid debug / info / warning messages from flake8 internals + logging.getLogger('flake8').setLevel(logging.ERROR) + + # for some reason the pydocstyle logger changes to an effective level of 1 + # set higher level to prevent the output to be flooded with debug messages + logging.getLogger('pydocstyle').setLevel(logging.WARNING) -def test_flake8(): style_guide = get_style_guide( extend_ignore=['D100', 'D104'], show_source=True, @@ -43,9 +49,6 @@ def test_flake8(): if report_tests.total_errors: report_tests._application.formatter.show_statistics( report_tests._stats) - print( - 'flake8 reported {total_errors} errors' - .format_map(locals()), file=sys.stderr) + print(f'flake8 reported {total_errors} errors', file=sys.stderr) - assert not total_errors, \ - 'flake8 reported {total_errors} errors'.format_map(locals()) + assert not total_errors, f'flake8 reported {total_errors} errors' diff --git a/test/test_spell_check.py b/test/test_spell_check.py index f1a8e64..48624b3 100644 --- a/test/test_spell_check.py +++ b/test/test_spell_check.py @@ -4,10 +4,6 @@ from pathlib import Path import pytest -from scspell import Report -from scspell import SCSPELL_BUILTIN_DICT -from scspell import spell_check - spell_check_words_path = Path(__file__).parent / 'spell_check.words' @@ -18,7 +14,12 @@ def known_words(): return spell_check_words_path.read_text().splitlines() +@pytest.mark.linter def test_spell_check(known_words): + from scspell import Report + from scspell import SCSPELL_BUILTIN_DICT + from scspell import spell_check + source_filenames = [Path(__file__).parents[1] / 'setup.py'] + \ list( (Path(__file__).parents[1] / 'colcon_cache') @@ -36,21 +37,23 @@ def test_spell_check(known_words): unknown_word_count = len(report.unknown_words) assert unknown_word_count == 0, \ - 'Found {unknown_word_count} unknown words: '.format_map(locals()) + \ + f'Found {unknown_word_count} unknown words: ' + \ ', '.join(sorted(report.unknown_words)) unused_known_words = set(known_words) - report.found_known_words unused_known_word_count = len(unused_known_words) assert unused_known_word_count == 0, \ - '{unused_known_word_count} words in the word list are not used: ' \ - .format_map(locals()) + ', '.join(sorted(unused_known_words)) + f'{unused_known_word_count} words in the word list are not used: ' + \ + ', '.join(sorted(unused_known_words)) +@pytest.mark.linter def test_spell_check_word_list_order(known_words): assert known_words == sorted(known_words), \ 'The word list should be ordered alphabetically' +@pytest.mark.linter def test_spell_check_word_list_duplicates(known_words): assert len(known_words) == len(set(known_words)), \ 'The word list should not contain duplicates'