Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#508] Use setuptools for plugin mechanism. #509

Open
wants to merge 70 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
277020f
Have ruff example unit test file generate an error.
tdenewiler Oct 23, 2023
79fb4f3
Merge remote-tracking branch 'sscpac/main'
tdenewiler Nov 1, 2023
98addb8
Switch to pyproject.toml project with src-based layout.
tdenewiler Nov 22, 2023
d0487e4
Switch from yapsy to standard Python plugins.
tdenewiler Nov 22, 2023
812ded6
Update unit tests to support built-in plugins approach.
tdenewiler Nov 22, 2023
1a027af
Remove use of backports.tempfile. Only needed for Python 3.6 and olde…
tdenewiler Nov 22, 2023
2c02f2f
Temporarily disable statick-md checks.
tdenewiler Nov 22, 2023
b218a90
Remove use of importlib_metadata. Only needed for Python <3.8.
tdenewiler Nov 22, 2023
7bb0d3e
Debug print for importlib version.
tdenewiler Nov 22, 2023
1930561
Try importlib_metadata fix.
tdenewiler Nov 22, 2023
27c5dae
Try mypy on ubuntu only.
tdenewiler Nov 22, 2023
ac34593
Try mypy on only Python 3.11.
tdenewiler Nov 22, 2023
412303a
Revert "Remove use of importlib_metadata. Only needed for Python <3.8."
tdenewiler Nov 22, 2023
d8f55f0
Run mypy on all Python versions.
tdenewiler Nov 22, 2023
5833b49
Install importlib_metadata for older versions of Python.
tdenewiler Nov 22, 2023
10b62f7
Fix syntax.
tdenewiler Nov 22, 2023
e739bfc
Add importlib_metadata to package requirements.
tdenewiler Nov 22, 2023
8502c62
Add Python 3.12.
tdenewiler Nov 22, 2023
7c4f872
Rename plugin unit test directories.
tdenewiler Nov 22, 2023
e45d370
Remove dependency on deprecated.
tdenewiler Nov 22, 2023
7344c6c
Update publish and test github workflow configs.
tdenewiler Nov 23, 2023
5f24a36
Install setuptools for test.
tdenewiler Nov 23, 2023
460d43b
Remove some unused dependencies.
tdenewiler Nov 24, 2023
d7f8302
Remove yapsy from templates.
tdenewiler Nov 24, 2023
5b407f9
Update sphinx docs.
tdenewiler Nov 24, 2023
a63de33
Dependency cleanup.
tdenewiler Nov 26, 2023
aa80b21
Fix tox issue.
tdenewiler Nov 26, 2023
f6ec315
Remove deprecated use of pkg_resources in favor of importlib for vers…
tdenewiler Nov 26, 2023
a38e763
Run isort.
tdenewiler Nov 26, 2023
bfeb382
Delete yapsy-plugin file for example.
tdenewiler Jan 15, 2024
d3555af
Merge in main branch.
tdenewiler Feb 6, 2024
1757246
Black formatting.
tdenewiler Feb 6, 2024
f42a91e
Merge remote-tracking branch 'sscpac/main' into stdlib-plugins
tdenewiler Feb 26, 2024
3beb69c
More files to remove after testing with clean.sh script. Pin pytest.
tdenewiler Apr 18, 2024
9410875
Update clean script. Add some pytest options.
tdenewiler Apr 22, 2024
afbcaa9
Pin pytest.
tdenewiler Apr 22, 2024
e717779
Merge in dev branch.
tdenewiler Apr 28, 2024
ea8e5d5
Merge in upstream main branch.
tdenewiler Jun 26, 2024
d8d1484
Merge remote-tracking branch 'tdenewiler/stdlib-plugins' into stdlib-…
tdenewiler Jun 26, 2024
2cc6ba3
Merge remote-tracking branch 'sscpac/main' into stdlib-plugins
tdenewiler Jul 27, 2024
adc91d1
Ignore requirements.txt. Use pip-compile to generate that file locally.
tdenewiler Jul 27, 2024
2791dab
Rename test input files so they do not have the same filename for mul…
tdenewiler Jul 28, 2024
6555026
Pull in fix from PR to main that fixes ruff tool command.
tdenewiler Jul 28, 2024
040bdf3
Pull in another fix in PR to main.
tdenewiler Jul 28, 2024
85e5be6
Bump versions of GitHub actions.
tdenewiler Jul 28, 2024
2057799
Update more GitHub action versions.
tdenewiler Jul 28, 2024
91c7024
Add ubuntu-24.04 to os list for testing.
tdenewiler Jul 28, 2024
94d2ec4
Use codecov token.
tdenewiler Jul 28, 2024
6834340
Fix code coverage for discovery plugin dependency checks.
tdenewiler Jul 28, 2024
92802e7
Remove commented out pytest option.
tdenewiler Jul 29, 2024
884c20f
Merge in upstream main branch.
tdenewiler Jul 29, 2024
1c2d2ae
Merge in upstream main branch.
tdenewiler Sep 24, 2024
f5d448e
Add Python 3.13 to list for testing and support.
tdenewiler Oct 14, 2024
c4a9cb5
Update readme unit test commands to include src/.
tdenewiler Oct 14, 2024
65c10f1
Fix unit test and type hints.
tdenewiler Oct 15, 2024
40a124f
Drop Python 3.8.
tdenewiler Oct 15, 2024
a8b4a21
Black formatting.
tdenewiler Oct 15, 2024
940f735
Merge in main branch.
tdenewiler Nov 5, 2024
6003d61
Merge remote-tracking branch 'sscpac/main' into stdlib-plugins
tdenewiler Nov 19, 2024
fca629b
Run more CI steps on Ubuntu 24.04.
tdenewiler Jan 3, 2025
9d408c1
Fix typo in CI.
tdenewiler Jan 3, 2025
331db09
Make new function to get version of cppcheck binary. Use that to fix …
tdenewiler Jan 3, 2025
61adf34
Run isort on all unit test files (but not ones with intentional errors).
tdenewiler Jan 3, 2025
6d45c74
Update changelog.
tdenewiler Jan 3, 2025
cd5f09b
Fix README.
tdenewiler Jan 3, 2025
7f946db
Unpin pytest version. Simplify pip install command.
tdenewiler Jan 3, 2025
3126854
Merge in main branch.
tdenewiler Jan 3, 2025
9696360
Update version number.
tdenewiler Jan 3, 2025
9443df2
Update version.
tdenewiler Jan 3, 2025
cdefe55
Use runner.os to simplify Linux-specific action steps.
tdenewiler Jan 6, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
42 changes: 15 additions & 27 deletions .github/workflows/publish.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,53 +9,41 @@ on: # NOLINT
jobs:
build-n-publish:
name: Build and publish Python 🐍 distributions 📦 to PyPI and TestPyPI
runs-on: ubuntu-22.04
runs-on: ubuntu-latest
environment:
name: pypi
url: https://pypi.org/p/statick
permissions:
id-token: write

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Set up Python 3.11
uses: actions/setup-python@v1
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'

- uses: actions/cache@v3
if: startsWith(runner.os, 'Linux')
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
restore-keys: |
${{ runner.os }}-pip-
cache: 'pip'

- name: Install tools
run: |
python -m pip install --upgrade setuptools
python -m pip install --upgrade wheel
python -m pip install -r requirements-docs.txt
python -m pip install -r requirements.txt
pip install .[docs]

- name: Build a binary wheel and a source tarball
run: |
python setup.py sdist bdist_wheel

- name: Publish distribution 📦 to Test PyPI
uses: pypa/gh-action-pypi-publish@master
with:
password: ${{ secrets.PYPI_TEST_TOKEN }}
repository_url: https://test.pypi.org/legacy/
pip install -q build
python -m build

- name: Publish distribution 📦 to PyPI
uses: pypa/gh-action-pypi-publish@master
with:
password: ${{ secrets.PYPI_TOKEN }}
uses: pypa/gh-action-pypi-publish@release/v1

- name: Sphinx lint
uses: ammaraskar/sphinx-action@master
with:
docs-folder: 'docs/'

- name: Publish documentation
uses: peaceiris/actions-gh-pages@v3
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./docs/build/html
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/publish_docker_image.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,32 +11,32 @@ env:

jobs:
build-and-push-image:
runs-on: ubuntu-22.04
runs-on: ubuntu-latest
permissions:
contents: read
packages: write

steps:
- name: Checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: Log in to the Container registry
uses: docker/login-action@v2
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v4
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=semver,pattern={{version}}

- name: Build and push Docker image
uses: docker/build-push-action@v3
uses: docker/build-push-action@v6
with:
context: docker
push: true
Expand Down
79 changes: 24 additions & 55 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,69 +14,36 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [macos-latest, ubuntu-20.04, ubuntu-22.04, windows-latest]
python-version: ['3.9', '3.10', '3.11']
os: [macos-latest, ubuntu-20.04, ubuntu-22.04, ubuntu-24.04, windows-latest]
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- uses: actions/setup-node@v3
- uses: actions/setup-node@v4
with:
node-version: '16'

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- uses: actions/cache@v3
if: startsWith(runner.os, 'Linux')
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
restore-keys: |
${{ runner.os }}-pip-

- uses: actions/cache@v3
if: startsWith(runner.os, 'macOS')
with:
path: ~/Library/Caches/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
restore-keys: |
${{ runner.os }}-pip-

- uses: actions/cache@v3
if: startsWith(runner.os, 'Windows')
with:
path: ~\AppData\Local\pip\Cache
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
restore-keys: |
${{ runner.os }}-pip-
cache: 'pip'

- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install --upgrade -r requirements.txt
python -m pip install --upgrade mypy
python -m pip install --upgrade setuptools
python -m pip install --upgrade tox
python -m pip install --upgrade tox-gh-actions
python -m pip install --upgrade types-deprecated
python -m pip install --upgrade types-PyYAML
python -m pip install --upgrade types-tabulate
python -m pip install --upgrade wheel
pip install --upgrade pip
pip install .[docs,test]

# Remove apt repos that are known to break from time to time.
# See https://github.com/actions/virtual-environments/issues/323
- name: Remove broken apt repos [Ubuntu]
if: matrix.os == 'ubuntu-20.04' || matrix.os == 'ubuntu-22.04'
if: runner.os == 'Linux'
run: |
for apt_file in `grep -lr microsoft /etc/apt/sources.list.d/`; do sudo rm $apt_file; done

# Use apt-get instead of apt as apt does not have a stable CLI interface. The apt tool prints out
# "WARNING: apt does not have a stable CLI interface. Use with caution in scripts."
- name: Install tools (Linux)
if: matrix.os == 'ubuntu-20.04' || matrix.os == 'ubuntu-22.04'
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install cccc
Expand All @@ -98,24 +65,25 @@ jobs:
sudo apt-get install clang-format-14
sudo apt-get install clang-tidy-14

# Have to install newer version from non-apt source due to SSL library compatibility issues.
- name: Install node
if: matrix.os == 'ubuntu-20.04' || matrix.os == 'ubuntu-22.04'
- name: Install node tools
if: runner.os == 'Linux'
run: |
npm install -g [email protected]
npm install -g npm-groovy-lint

- name: Test with mypy
run: |
mypy --ignore-missing-imports --strict statick statick_tool/
mypy --ignore-missing-imports --strict src/statick_tool/

- name: Statick markdown
if: matrix.os == 'ubuntu-20.04' || matrix.os == 'ubuntu-22.04'
run: |
statick . --check --profile documentation.yaml
# Re-enable this step when statick-md switches from yapsy to entry points plugin approach.
# - name: Statick markdown
xydesa marked this conversation as resolved.
Show resolved Hide resolved
# if: runner.os == 'Linux'
# run: |
# pip install statick-md
# statick . --check --profile documentation.yaml

- name: Sphinx lint
if: matrix.os == 'ubuntu-20.04' || matrix.os == 'ubuntu.22.04'
if: runner.os == 'Linux'
uses: ammaraskar/sphinx-action@master
with:
docs-folder: 'docs/'
Expand All @@ -125,12 +93,13 @@ jobs:
python -m tox

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
uses: codecov/codecov-action@v4
with:
fail_ci_if_error: false
token: ${{ secrets.CODECOV_TOKEN }}

- name: Self check
if: matrix.os == 'ubuntu-20.04' || matrix.os == 'ubuntu-22.04'
if: runner.os == 'Linux'
run: |
mkdir statick-output
./statick . --output-directory statick-output --check --profile self_check.yaml --log INFO
statick . --output-directory statick-output --check --profile self_check.yaml --log INFO
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ build/
dist/
*.egg-info/
MANIFEST
requirements.txt

docs/_build

Expand Down
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,19 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

## Unreleased

### Added

- Use of `pyproject.toml` instead of `setup.py` and `requirements.txt`.
- Added support for Python 3.12 and 3.13.
- Switched from yapsy to setuptools for plugin mechanism. (#508)

### Fixed

- Run `isort` on unit test files.
- Handle updated warning type from `cppcheck` introduced in version 2.8.

## v0.10.0 - 2025-01-03

### Added
Expand Down
67 changes: 41 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,6 @@ Each _tool_ plugin provides the types of files it can analyze, then the output o
determine the specific files that should be analyzed by each tool.

The _tool_ plugin can also specify any other tools that are required to run before the current tool can act.
For example, `cppcheck` depends on the output of the `make` tool.

The _tool_ plugin then scans each package by invoking the binary associated with the tool.
The output of the scan is parsed to generate the list of issues discovered by Statick.
Expand Down Expand Up @@ -418,10 +417,14 @@ $ statick . --output-directory /tmp/x --timings

## Advanced Installation

To install Statick from source on your system and make it part of your `$PATH`:
To install from source best practices is to use a virtual environment.
These instructions are for Linux, activating a virtual environment on Mac/Windows is similar.
To install Statick from source on your system:

```shell
sudo python3 setup.py install
python3 -m venv venv
. venv/bin/activate
pip install .
```

## Existing Plugins
Expand Down Expand Up @@ -648,34 +651,43 @@ The resource file (in your _user path_) must be named `_clang-format`.

If you have the need to support any type of _discovery_, _tool_, or _reporting_ plugin that does not come built-in
with Statick then you can write a custom plugin.
Declare the plugin module as a [module entry point] in `pyproject.toml` and provide the path according to plugin type
(_discovery_, _tool_, _reporting_).

Plugins consist of both a Python file and a `yapsy` file.
For a description of how yapsy works, check out the [yapsy documentation](http://yapsy.sourceforge.net/).

A _user path_ with some custom plugins may look like
A _user path_ with custom plugins and configuration files may look like

```shell
my_custom_config
setup.py
|- plugins
|- my_discovery_plugin
|- my_discovery_plugin.py
|- my_discovery_plugin.yapsy
|- my_tool_plugins
|- my_tool_plugin.py
|- my_tool_plugin.yapsy
|- my_other_tool_plugin.py
|- my_other_tool_plugin.yapsy
|- rsc
|- config.yaml
|- exceptions.yaml
my-custom-project
pyproject.toml
|- src
|- statick_tool
|- plugins
|- discovery
|- my_discovery_plugin.py
|- tool
|- my_tool_plugin.py
|- my_other_tool_plugin.py
|- rsc
|- config.yaml
|- exceptions.yaml
```

In `pyproject.toml` declare the plugins as entry points.

```toml
[project.entry-points."statick_tool.plugins.discovery"]
my_discovery_name = "statick_tool.plugins.discovery.my_discovery_plugin:MyDiscoveryPlugin"

[project.entry-points."statick_tool.plugins.tool"]
my_tool_name = "statick_tool.plugins.tool.my_tool_plugin:MyToolPlugin"
my_other_tool_name = "statick_tool.plugins.tool.my_other_tool_plugin:MyOtherToolPlugin"
```

For the actual implementation of a plugin, it is recommended to copy a suitable default plugin provided by Statick and
modify as needed.

For the contents of `setup.py`, it is recommended to copy a working external plugin.
Some examples are [statick-fortify](https://github.com/soartech/statick-fortify) and [statick-tex](https://github.com/tdenewiler/statick-tex).
For the contents of `pyproject.toml`, it is recommended to copy a working external plugin.
Some examples are [statick-md] and [statick-tex].
Those plugins are set up in such a way that they work with Statick when released on PyPI.

## Examples
Expand Down Expand Up @@ -834,14 +846,14 @@ If you have a unit test file at `tests/my_module/test_my_module.py` you can easi
and save yourself a lot of time during development.

```shell
python3 -m pytest --cov=statick_tool/ tests/my_module/test_my_module.py
python3 -m pytest --cov=src/statick_tool/ tests/my_module/test_my_module.py
```

To run all the tests and get a report with branch coverage specify the `tests` directory.
Any subdirectory will run all the tests in that subdirectory.

```shell
python3 -m pytest --cov=statick_tool/ --cov-report term-missing --cov-report html --cov-branch tests/
python3 -m pytest --cov=src/statick_tool/ --cov-report term-missing --cov-report html --cov-branch tests/
```

### Mypy
Expand Down Expand Up @@ -893,6 +905,7 @@ His commits were scrubbed from git history upon the initial public release.
[lizard]: https://github.com/terryyin/lizard
[logging]: https://docs.python.org/3/howto/logging.html
[make]: https://gcc.gnu.org/onlinedocs/libstdc++/index.html
[module entry point]: https://setuptools.pypa.io/en/latest/userguide/entry_point.html#entry-points-syntax
[mypy]: https://github.com/python/mypy
[npm-groovy-lint]: https://nvuillam.github.io/npm-groovy-lint/
[perlcritic]: http://perlcritic.com/
Expand All @@ -902,10 +915,12 @@ His commits were scrubbed from git history upon the initial public release.
[pydocstyle]: http://www.pydocstyle.org/en/stable/
[pyflakes]: https://github.com/PyCQA/pyflakes
[pylint]: https://pylint.org/
[ruff]: https://github.com/charliermarsh/ruff
[ros]: https://www.ros.org/
[ruff]: https://github.com/charliermarsh/ruff
[shellcheck]: https://github.com/koalaman/shellcheck
[spotbugs]: https://github.com/spotbugs/spotbugs
[statick-md]: https://github.com/sscpac/statick-md
[statick-tex]: https://github.com/tdenewiler/statick-tex
[uncrustify]: https://github.com/uncrustify/uncrustify
[xmllint]: http://xmlsoft.org/
[yamllint]: https://yamllint.readthedocs.io/en/stable/
1 change: 0 additions & 1 deletion docker/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,3 @@ statick-web
tabulate
xmltodict
yamllint
yapsy
Loading