diff --git a/.codecov.yml b/.codecov.yml new file mode 100644 index 0000000..dc436e9 --- /dev/null +++ b/.codecov.yml @@ -0,0 +1,6 @@ +coverage: + status: + project: + default: + target: 0% + threshold: null diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index ba639ce..26a7b5a 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -1,7 +1,7 @@ --- name: Publish Python 🐍 distributions 📦 to PyPI and TestPyPI -on: # NOLINT +on: # NOLINT push: tags: - "*" @@ -10,6 +10,11 @@ jobs: build-n-publish: name: Build and publish Python 🐍 distributions 📦 to PyPI and TestPyPI runs-on: ubuntu-latest + environment: + name: pypi + url: https://pypi.org/p/statick-md + permissions: + id-token: write steps: - uses: actions/checkout@v3 @@ -18,47 +23,16 @@ jobs: uses: actions/setup-python@v4 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- - - - 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 tools run: | - python -m pip install --upgrade setuptools - python -m pip install --upgrade wheel + pip install .[dist] - 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@release/v1 - 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@release/v1 - with: - password: ${{ secrets.PYPI_TOKEN }} diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index ae4adcd..deff181 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -14,86 +14,55 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [macos-latest, ubuntu-20.04, ubuntu-22.04, windows-latest] - python-version: ['3.8', '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' + node-version: '20' - 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 setuptools - python -m pip install --upgrade wheel - python -m pip install --upgrade coverage - python -m pip install --upgrade mypy - python -m pip install --upgrade types-docutils - python -m pip install --upgrade tox - python -m pip install --upgrade tox-gh-actions - python -m pip install --upgrade virtualenv + pip install .[docs,test] - # Have to install newer version from non-apt source due to SSL library compatibility issues. - - name: Install Node and node-based tools (Linux) - if: matrix.os == 'ubuntu-20.04' || matrix.os == 'ubuntu-22.04' + - name: Install Node tools (Linux) + if: runner.os == 'Linux' run: | npm install -g markdownlint-cli npm install -g write-good - name: Mypy run: | - mypy --ignore-missing-imports --strict src/ + mypy --ignore-missing-imports --strict src/statick_tool/ - name: Tox run: | python -m tox - name: Upload coverage to Codecov - uses: codecov/codecov-action@v3 + uses: codecov/codecov-action@v5 with: fail_ci_if_error: false - name: Statick Documentation - if: matrix.os == 'ubuntu-20.04' || matrix.os == 'ubuntu-22.04' + if: runner.os == 'Linux' uses: sscpac/statick-action@v0.9.2 with: profile: documentation.yaml timings: true - name: Self check - if: matrix.os == 'ubuntu-20.04' || matrix.os == 'ubuntu-22.04' + if: runner.os == 'Linux' uses: sscpac/statick-action@v0.9.2 with: profile: self_check.yaml diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ea01bb..39ffb14 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,28 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) ## Unreleased +### Added + +- Support for Python 3.12 and 3.13. +- Use of `pyproject.toml` instead of `setup.py` and `requirements.txt`. +- Supports new plugin discovery mechanism for the main Statick tool. + - Switched from yapsy to setuptools for plugin mechanism. (sscpac/statick#508) + +### Changed + +- Disabled code coverage requirements in CI for now. + - Unable to get line coverage working with new plugin mechanism. + Unit tests still work to find problems. +- Updated README to use more modern approach to installing Python and NPM packages. +- Rename plugin modules so they are shorter and less redundant. + +### Removed + +- No longer support Python 3.8. +- Proselint tool removed. + - Unable to resolve type hint and unit test issues. + Tool not used as far as Statick developers are aware. + ## v0.2.0 - 2025-01-03 ### Removed diff --git a/README.md b/README.md index ea7b2bf..8d35ba0 100644 --- a/README.md +++ b/README.md @@ -18,38 +18,61 @@ Custom exceptions can be applied the same way they are with ## Table of Contents -* [Installation](#installation) -* [Usage](#usage) -* [Existing Plugins](#existing-plugins) - * [Discovery Plugins](#discovery-plugins) - * [Tool Plugins](#tool-plugins) -* [Contributing](#contributing) - * [Mypy](#mypy) - * [Formatting](#formatting) +- [Statick Markdown Plugins](#statick-markdown-plugins) + - [Table of Contents](#table-of-contents) + - [Installation](#installation) + - [Usage](#usage) + - [Dependency Versions](#dependency-versions) + - [Pip Install](#pip-install) + - [Pip Install and Custom Configuration](#pip-install-and-custom-configuration) + - [Existing Plugins](#existing-plugins) + - [Discovery Plugins](#discovery-plugins) + - [Tool Plugins](#tool-plugins) + - [Contributing](#contributing) + - [Mypy](#mypy) + - [Formatting](#formatting) ## Installation The recommended method to install these Statick plugins is via pip: ```shell -python3 -m pip install statick-md +pip install statick-md ``` You can also clone the repository and use it locally. ## Usage -Make sure you install all the dependencies from apt/npm: +Make sure you install all the dependencies from apt/npm. +See for Node/npm installation instructions. + +Configure npm to allow a non-root user to install packages. + +```shell +npm config set prefix '~/.local/' +``` + +Make sure `~/.local/bin` exists. +Check your `PATH` with `echo $PATH`. +If `~/.local/bin` is not listed then add it to your `PATH`. ```shell -cat install.txt | xargs sudo apt-get install -y -cat npm-deps.txt | xargs sudo npm install -g +mkdir -p ~/.local/bin +echo 'export PATH="$HOME/.local/bin/:$PATH"' >> ~/.bashrc +``` + +Install packages. + +```shell +npm install -g markdownlint-cli +npm install -g write-good ``` ### Dependency Versions Markdownlint-cli has occasionally changed defaults via an upgrade that results in lots of new warnings. -To mitigate this you can pin the version of markdownlint-cli in npm-deps.txt by changing `markdownlint-cli` to `markdownlint-cli@0.19`. +To mitigate this you can pin the version of markdownlint-cli when installing by changing `markdownlint-cli` to `markdownlint-cli@0.19`. ### Pip Install @@ -59,13 +82,12 @@ In that case your directory structure will look like the following: ```shell project-root |- md-project - |- statick-output ``` To run with the default configuration for the statick-md tools use: ```shell -statick md-project/ --output-directory statick-output/ --profile md-profile.yaml --config md-config.yaml +statick md-project/ -o /tmp/statick-output/ --level md --log info ``` ### Pip Install and Custom Configuration @@ -77,40 +99,16 @@ This example will have custom exceptions in the md-project, such that the direct ```shell project-root - |- md-project - |- statick-config - |- rsc - |- exceptions.yaml - |- statick-output +|- md-project + |- statick-config + |- rsc + |- exceptions.yaml ``` For this setup you will run the following: ```shell -statick md-project/ --output-directory statick-output/ --user-paths md-project/statick-config/ --profile md-profile.yaml --config md-config.yaml -``` - -### Source Install and Custom Configuration - -The last type of setup will be to have all of the tools available from cloning repositories, not installing from pip. -The directory structure will look like: - -```shell -project-root - |- md-project - |- statick-config - |- rsc - |- exceptions.yaml - |- statick-output - |- statick - |- statick-md -``` - -Using the example where we want to override the default exceptions with -custom ones in the md-project, the command to run would be: - -```shell -./statick/statick md-project/ --output-directory statick-output/ --user-paths statick-md/,statick-md/src/statick_md,md-project/statick-config/ --profile md-profile.yaml --config md-config.yaml +statick md-project/ --o /tmp/statick-output/ -u md-project/statick-config/ --level md ``` ## Existing Plugins @@ -127,7 +125,6 @@ reStructuredText | `.rst` Tool | About :--- | :---- [markdownlint][markdownlint] | A Node.js style checker and lint tool for Markdown/CommonMark files. -[proselint][proselint] | A linter for prose. [rstcheck][rstcheck] | Checks syntax of reStructuredText and code blocks nested within it. [rst-lint][rst-lint] | Checks syntax of reStructuredText and code blocks nested within it. [write-good] | Naive linter for English prose. @@ -150,25 +147,22 @@ To determine if proper types are being used in Statick Markdown the following co types of reports that can be viewed with a text editor or web browser. ```shell -python3 -m pip install mypy +pip install mypy mkdir report -mypy --ignore-missing-imports --strict --html-report report/ --txt-report report src +mypy --ignore-missing-imports --strict src ``` -It is hoped that in the future we will generate coverage reports from mypy and use those to check for regressions. - ### Formatting Statick code is formatted using [black](https://github.com/psf/black). To fix locally use ```shell -python3 -m pip install black +pip install black black src tests ``` [markdownlint]: https://github.com/igorshubovych/markdownlint-cli -[proselint]: https://github.com/amperser/proselint [rstcheck]: https://github.com/myint/rstcheck [rst-lint]: https://github.com/twolfson/restructuredtext-lint [write-good]: https://github.com/btford/write-good diff --git a/clean.sh b/clean.sh index 8972b13..7745be0 100644 --- a/clean.sh +++ b/clean.sh @@ -1,5 +1,5 @@ #!/bin/bash -rm -rf build/ dist/ output-py* .pytest_cache statick_md.egg-info/ statick_output/* .tox/ +rm -rf build/ .coverage dist/ output-py* .pytest_cache statick_md.egg-info/ statick_output/* .tox/ ./*.log find . -type d -name .mypy_cache -exec rm -rf {} +; find . -type d -name __pycache__ -exec rm -rf {} +; diff --git a/install.txt b/install.txt deleted file mode 100644 index b235581..0000000 --- a/install.txt +++ /dev/null @@ -1 +0,0 @@ -npm diff --git a/npm-deps.txt b/npm-deps.txt deleted file mode 100644 index ab2dfd7..0000000 --- a/npm-deps.txt +++ /dev/null @@ -1 +0,0 @@ -markdownlint-cli diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..7af8fd1 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,68 @@ +[build-system] +requires = ["setuptools", "wheel"] +build-backend = "setuptools.build_meta" + +[project] +name = "statick-md" +authors = [{name = "NIWC Pacific"}] +description="Statick analysis plugins for Markdown files." +version = "0.1.3" +readme = "README.md" +requires-python = ">=3.9" +license = {text = "CC0-1.0"} +classifiers = [ + "License :: CC0 1.0 Universal (CC0 1.0) Public Domain Dedication", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Topic :: Software Development :: Testing", +] +dependencies = [ + "importlib_metadata", + "restructuredtext-lint", + "rstcheck", + "sphinx", + "statick", + "types-docutils", +] + +[tool.setuptools.package-data] +statick_tool = [ + "rsc/*", + "rsc/.*", +] + +[project.entry-points."statick_tool.plugins.discovery"] +markdown = "statick_tool.plugins.discovery.markdown:MarkdownDiscoveryPlugin" +rst = "statick_tool.plugins.discovery.rst:RstDiscoveryPlugin" + +[project.entry-points."statick_tool.plugins.tool"] +markdownlint = "statick_tool.plugins.tool.markdownlint:MarkdownlintToolPlugin" +rstcheck = "statick_tool.plugins.tool.rstcheck:RstcheckToolPlugin" +rstlint = "statick_tool.plugins.tool.rstlint:RstlintToolPlugin" +writegood = "statick_tool.plugins.tool.writegood:WriteGoodToolPlugin" + +[project.urls] +"Homepage" = "https://github.com/sscpac/statick-md" +"Bug Tracker" = "https://github.com/sscpac/statick-md/issues" + +[project.optional-dependencies] +test = [ + "coverage", + "lark", + "mock", + "pytest", + "pytest-cov", + "tox", + "tox-gh-actions", +] +docs = [ + "sphinx==1.7.9", + "yaml-1.3", +] + +[tool.isort] +profile = "black" diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 173cd39..0000000 --- a/requirements.txt +++ /dev/null @@ -1,5 +0,0 @@ -statick -proselint -restructuredtext-lint -rstcheck -sphinx diff --git a/setup.py b/setup.py deleted file mode 100644 index a6bfe70..0000000 --- a/setup.py +++ /dev/null @@ -1,58 +0,0 @@ -"""Setup.""" - - -from setuptools import setup - -with open("README.md", encoding="utf8") as fid: - long_description = fid.read() # pylint: disable=invalid-name - -TEST_DEPS = [ - "mock", - "pytest", -] - -EXTRAS = { - "test": TEST_DEPS, -} - -setup( - author="NIWC Pacific", - name="statick-md", - description="Statick analysis plugins for Markdown files.", - version="0.2.0", - packages=[ - "statick_tool", - "statick_tool.plugins.discovery", - "statick_tool.plugins.tool", - ], - package_dir={ - "statick_tool": ".", - "statick_tool.plugins.discovery": "src/statick_md/plugins/discovery", - "statick_tool.plugins.tool": "src/statick_md/plugins/tool", - }, - package_data={ - "statick_tool": ["rsc/.*", "rsc/*"], - "statick_tool.plugins.discovery": ["*.yapsy-plugin"], - "statick_tool.plugins.tool": ["*.yapsy-plugin"], - }, - long_description=long_description, - long_description_content_type="text/markdown", - install_requires=[ - "proselint", - "restructuredtext-lint", - "rstcheck", - "sphinx", - "statick", - ], - tests_require=TEST_DEPS, - extras_require=EXTRAS, - url="https://github.com/sscpac/statick-md", - classifiers=[ - "License :: CC0 1.0 Universal (CC0 1.0) Public Domain Dedication", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Topic :: Software Development :: Testing", - ], -) diff --git a/src/statick_md/__init__.py b/src/statick_md/__init__.py deleted file mode 100644 index 5da5b0e..0000000 --- a/src/statick_md/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Statick tool.""" diff --git a/src/statick_md/plugins/__init__.py b/src/statick_md/plugins/__init__.py deleted file mode 100644 index 9e74282..0000000 --- a/src/statick_md/plugins/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Markdown plugins for Statick.""" diff --git a/src/statick_md/plugins/discovery/__init__.py b/src/statick_md/plugins/discovery/__init__.py deleted file mode 100644 index 878179b..0000000 --- a/src/statick_md/plugins/discovery/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Md file discovery plugins.""" diff --git a/src/statick_md/plugins/discovery/markdown_discovery_plugin.yapsy-plugin b/src/statick_md/plugins/discovery/markdown_discovery_plugin.yapsy-plugin deleted file mode 100644 index 9c99fbf..0000000 --- a/src/statick_md/plugins/discovery/markdown_discovery_plugin.yapsy-plugin +++ /dev/null @@ -1,3 +0,0 @@ -[Core] -Name = Markdown Discovery Plugin -Module = markdown_discovery_plugin diff --git a/src/statick_md/plugins/discovery/rst_discovery_plugin.yapsy-plugin b/src/statick_md/plugins/discovery/rst_discovery_plugin.yapsy-plugin deleted file mode 100644 index 1d00ea8..0000000 --- a/src/statick_md/plugins/discovery/rst_discovery_plugin.yapsy-plugin +++ /dev/null @@ -1,3 +0,0 @@ -[Core] -Name = rst Discovery Plugin -Module = rst_discovery_plugin diff --git a/src/statick_md/plugins/tool/__init__.py b/src/statick_md/plugins/tool/__init__.py deleted file mode 100644 index ef93d6a..0000000 --- a/src/statick_md/plugins/tool/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Md tool plugins.""" diff --git a/src/statick_md/plugins/tool/markdownlint_tool_plugin.yapsy-plugin b/src/statick_md/plugins/tool/markdownlint_tool_plugin.yapsy-plugin deleted file mode 100644 index c7afe77..0000000 --- a/src/statick_md/plugins/tool/markdownlint_tool_plugin.yapsy-plugin +++ /dev/null @@ -1,3 +0,0 @@ -[Core] -Name = Markdownlint Tool Plugin -Module = markdownlint_tool_plugin diff --git a/src/statick_md/plugins/tool/proselint_tool_plugin.py b/src/statick_md/plugins/tool/proselint_tool_plugin.py deleted file mode 100644 index 54b5c6d..0000000 --- a/src/statick_md/plugins/tool/proselint_tool_plugin.py +++ /dev/null @@ -1,101 +0,0 @@ -"""Apply proselint tool and gather results. - -Website: http://proselint.com/ -Github: https://github.com/amperser/proselint - -The tool uses the default proselint configuration file. -On Ubuntu this is at `~/.config/proselint/config`. - -https://github.com/amperser/proselint#checks -""" -import json -import logging -from typing import Any, Dict, List, Optional - -import proselint -from proselint.config import default as proselint_default - -from statick_tool.issue import Issue -from statick_tool.package import Package -from statick_tool.tool_plugin import ToolPlugin - - -class ProselintToolPlugin(ToolPlugin): # type: ignore - """Apply proselint tool and gather results.""" - - def get_name(self) -> str: - """Get name of tool.""" - return "proselint" - - def scan(self, package: Package, level: str) -> Optional[List[Issue]]: - """Run tool and gather output.""" - if "md_src" not in package or not package["md_src"]: - return [] - - files: List[str] = [] - if "md_src" in package: - files += package["md_src"] - - # The JSON output does not include the filename so we have to run each file - # one at a time, and store the output along with the filename in a dictionary. - # The filename may be added to JSON output in the future: - # https://github.com/amperser/proselint/issues/355 - output: Dict[str, Any] = {} - for filename in files: - with open(filename, encoding="utf8") as fid: - errors = proselint.tools.errors_to_json( - proselint.tools.lint(fid, config=proselint_default) - ) - output[filename] = errors - - for key, value in output.items(): - logging.debug("%s: %s", key, value) - - with open(self.get_name() + ".log", "w", encoding="utf8") as fid: - for key, value in output.items(): - combined = key + value - fid.write(combined) - - issues: List[Issue] = self.parse_tool_output(output) - return issues - - def parse_tool_output(self, output: Dict[str, Any]) -> List[Issue]: - """Parse tool output and report issues.""" - issues: List[Issue] = [] - for key, value in output.items(): - try: - data = json.loads(value)["data"]["errors"] - except KeyError as ex: - logging.warning("%s exception: %s", self.get_name(), ex) - continue - for item in data: - if ( - "check" not in item - or "line" not in item - or "message" not in item - or "severity" not in item - ): - logging.debug(" Found invalid proselint output: %s", item) - continue - if item["severity"] == "suggestion": - warning_level = "1" - elif item["severity"] == "warning": - warning_level = "3" - elif item["severity"] == "error": - warning_level = "5" - else: - warning_level = "3" - - issue = Issue( - key, - str(item["line"]), - self.get_name(), - item["check"], - warning_level, - item["message"], - None, - ) - - issues.append(issue) - - return issues diff --git a/src/statick_md/plugins/tool/proselint_tool_plugin.yapsy-plugin b/src/statick_md/plugins/tool/proselint_tool_plugin.yapsy-plugin deleted file mode 100644 index 5ca6563..0000000 --- a/src/statick_md/plugins/tool/proselint_tool_plugin.yapsy-plugin +++ /dev/null @@ -1,3 +0,0 @@ -[Core] -Name = Proselint Tool Plugin -Module = proselint_tool_plugin diff --git a/src/statick_md/plugins/tool/rstcheck_tool_plugin.yapsy-plugin b/src/statick_md/plugins/tool/rstcheck_tool_plugin.yapsy-plugin deleted file mode 100644 index dbba29d..0000000 --- a/src/statick_md/plugins/tool/rstcheck_tool_plugin.yapsy-plugin +++ /dev/null @@ -1,3 +0,0 @@ -[Core] -Name = rstcheck Tool Plugin -Module = rstcheck_tool_plugin diff --git a/src/statick_md/plugins/tool/rstlint_tool_plugin.yapsy-plugin b/src/statick_md/plugins/tool/rstlint_tool_plugin.yapsy-plugin deleted file mode 100644 index cac6ffd..0000000 --- a/src/statick_md/plugins/tool/rstlint_tool_plugin.yapsy-plugin +++ /dev/null @@ -1,3 +0,0 @@ -[Core] -Name = rstlint Tool Plugin -Module = rstlint_tool_plugin diff --git a/src/statick_md/plugins/tool/writegood_tool_plugin.yapsy-plugin b/src/statick_md/plugins/tool/writegood_tool_plugin.yapsy-plugin deleted file mode 100644 index 91bbd46..0000000 --- a/src/statick_md/plugins/tool/writegood_tool_plugin.yapsy-plugin +++ /dev/null @@ -1,3 +0,0 @@ -[Core] -Name = WriteGood Tool Plugin -Module = writegood_tool_plugin diff --git a/src/statick_md/plugins/discovery/markdown_discovery_plugin.py b/src/statick_tool/plugins/discovery/markdown.py similarity index 100% rename from src/statick_md/plugins/discovery/markdown_discovery_plugin.py rename to src/statick_tool/plugins/discovery/markdown.py diff --git a/src/statick_md/plugins/discovery/rst_discovery_plugin.py b/src/statick_tool/plugins/discovery/rst.py similarity index 100% rename from src/statick_md/plugins/discovery/rst_discovery_plugin.py rename to src/statick_tool/plugins/discovery/rst.py diff --git a/src/statick_md/plugins/tool/markdownlint_tool_plugin.py b/src/statick_tool/plugins/tool/markdownlint.py similarity index 100% rename from src/statick_md/plugins/tool/markdownlint_tool_plugin.py rename to src/statick_tool/plugins/tool/markdownlint.py diff --git a/src/statick_md/plugins/tool/rstcheck_tool_plugin.py b/src/statick_tool/plugins/tool/rstcheck.py similarity index 100% rename from src/statick_md/plugins/tool/rstcheck_tool_plugin.py rename to src/statick_tool/plugins/tool/rstcheck.py diff --git a/src/statick_md/plugins/tool/rstlint_tool_plugin.py b/src/statick_tool/plugins/tool/rstlint.py similarity index 99% rename from src/statick_md/plugins/tool/rstlint_tool_plugin.py rename to src/statick_tool/plugins/tool/rstlint.py index ee1d9db..3649932 100644 --- a/src/statick_md/plugins/tool/rstlint_tool_plugin.py +++ b/src/statick_tool/plugins/tool/rstlint.py @@ -5,7 +5,6 @@ import restructuredtext_lint from docutils.utils import SystemMessage - from statick_tool.issue import Issue from statick_tool.package import Package from statick_tool.tool_plugin import ToolPlugin diff --git a/src/statick_md/plugins/tool/writegood_tool_plugin.py b/src/statick_tool/plugins/tool/writegood.py similarity index 100% rename from src/statick_md/plugins/tool/writegood_tool_plugin.py rename to src/statick_tool/plugins/tool/writegood.py diff --git a/rsc/.markdownlintrc b/src/statick_tool/rsc/.markdownlintrc similarity index 100% rename from rsc/.markdownlintrc rename to src/statick_tool/rsc/.markdownlintrc diff --git a/rsc/markdownlint-profile.yaml b/src/statick_tool/rsc/markdownlint-profile.yaml similarity index 100% rename from rsc/markdownlint-profile.yaml rename to src/statick_tool/rsc/markdownlint-profile.yaml diff --git a/rsc/md-config.yaml b/src/statick_tool/rsc/md-config.yaml similarity index 87% rename from rsc/md-config.yaml rename to src/statick_tool/rsc/md-config.yaml index 3362779..b438a96 100644 --- a/rsc/md-config.yaml +++ b/src/statick_tool/rsc/md-config.yaml @@ -7,14 +7,6 @@ levels: markdownlint: flags: "" - proselint: - discovery: - markdown: - flags: "" - tool: - proselint: - flags: "" - rst: discovery: rst: @@ -60,8 +52,6 @@ levels: tool: markdownlint: flags: "" - proselint: - flags: "" rstcheck: flags: "" rstlint: diff --git a/rsc/md-profile.yaml b/src/statick_tool/rsc/md-profile.yaml similarity index 100% rename from rsc/md-profile.yaml rename to src/statick_tool/rsc/md-profile.yaml diff --git a/rsc/rst-profile.yaml b/src/statick_tool/rsc/rst-profile.yaml similarity index 100% rename from rsc/rst-profile.yaml rename to src/statick_tool/rsc/rst-profile.yaml diff --git a/rsc/rstcheck-profile.yaml b/src/statick_tool/rsc/rstcheck-profile.yaml similarity index 100% rename from rsc/rstcheck-profile.yaml rename to src/statick_tool/rsc/rstcheck-profile.yaml diff --git a/rsc/rstlint-profile.yaml b/src/statick_tool/rsc/rstlint-profile.yaml similarity index 100% rename from rsc/rstlint-profile.yaml rename to src/statick_tool/rsc/rstlint-profile.yaml diff --git a/rsc/writegood-profile.yaml b/src/statick_tool/rsc/writegood-profile.yaml similarity index 100% rename from rsc/writegood-profile.yaml rename to src/statick_tool/rsc/writegood-profile.yaml diff --git a/tests/discovery/markdown_discovery_plugin/exceptions.yaml b/tests/discovery/markdown/exceptions.yaml similarity index 100% rename from tests/discovery/markdown_discovery_plugin/exceptions.yaml rename to tests/discovery/markdown/exceptions.yaml diff --git a/tests/discovery/markdown_discovery_plugin/invalid_package/test.aux b/tests/discovery/markdown/invalid_package/test.aux similarity index 100% rename from tests/discovery/markdown_discovery_plugin/invalid_package/test.aux rename to tests/discovery/markdown/invalid_package/test.aux diff --git a/tests/discovery/markdown_discovery_plugin/invalid_package/test.cls b/tests/discovery/markdown/invalid_package/test.cls similarity index 100% rename from tests/discovery/markdown_discovery_plugin/invalid_package/test.cls rename to tests/discovery/markdown/invalid_package/test.cls diff --git a/tests/discovery/markdown_discovery_plugin/invalid_package/test.log b/tests/discovery/markdown/invalid_package/test.log similarity index 100% rename from tests/discovery/markdown_discovery_plugin/invalid_package/test.log rename to tests/discovery/markdown/invalid_package/test.log diff --git a/tests/discovery/markdown_discovery_plugin/invalid_package/test.sty b/tests/discovery/markdown/invalid_package/test.sty similarity index 100% rename from tests/discovery/markdown_discovery_plugin/invalid_package/test.sty rename to tests/discovery/markdown/invalid_package/test.sty diff --git a/tests/discovery/markdown_discovery_plugin/test_markdown_discovery_plugin.py b/tests/discovery/markdown/test_markdown_discovery_plugin.py similarity index 67% rename from tests/discovery/markdown_discovery_plugin/test_markdown_discovery_plugin.py rename to tests/discovery/markdown/test_markdown_discovery_plugin.py index 27a1c5e..c2c907f 100644 --- a/tests/discovery/markdown_discovery_plugin/test_markdown_discovery_plugin.py +++ b/tests/discovery/markdown/test_markdown_discovery_plugin.py @@ -1,40 +1,26 @@ """Unit tests for the markdown discovery plugin.""" import os +import sys -from yapsy.PluginManager import PluginManager - -import statick_tool -from statick_tool.discovery_plugin import DiscoveryPlugin from statick_tool.exceptions import Exceptions from statick_tool.package import Package -from statick_tool.plugins.discovery.markdown_discovery_plugin import ( - MarkdownDiscoveryPlugin, -) +from statick_tool.plugins.discovery.markdown import MarkdownDiscoveryPlugin + +if sys.version_info < (3, 10): + from importlib_metadata import entry_points +else: + from importlib.metadata import entry_points def test_markdown_plugin_found(): """Test that the plugin manager finds the markdown discovery plugin.""" - manager = PluginManager() - # Get the path to statick_tool/__init__.py, get the directory part, and - # add 'plugins' to that to get the standard plugins dir - manager.setPluginPlaces( - [os.path.join(os.path.dirname(statick_tool.__file__), "plugins")] - ) - manager.setCategoriesFilter( - { - "Discovery": DiscoveryPlugin, - } - ) - manager.collectPlugins() - # Verify that a plugin's get_name() function returns "markdown" - assert any( - plugin_info.plugin_object.get_name() == "markdown" - for plugin_info in manager.getPluginsOfCategory("Discovery") - ) - # While we're at it, verify that a plugin is named markdown Discovery Plugin + discovery_plugins = {} + plugins = entry_points(group="statick_tool.plugins.discovery") + for plugin_type in plugins: + plugin = plugin_type.load() + discovery_plugins[plugin_type.name] = plugin() assert any( - plugin_info.name == "Markdown Discovery Plugin" - for plugin_info in manager.getPluginsOfCategory("Discovery") + plugin.get_name() == "markdown" for _, plugin in list(discovery_plugins.items()) ) diff --git a/tests/discovery/markdown_discovery_plugin/valid_package/ignore_this/ignoreme.md b/tests/discovery/markdown/valid_package/ignore_this/ignoreme.md similarity index 100% rename from tests/discovery/markdown_discovery_plugin/valid_package/ignore_this/ignoreme.md rename to tests/discovery/markdown/valid_package/ignore_this/ignoreme.md diff --git a/tests/discovery/markdown_discovery_plugin/valid_package/test.md b/tests/discovery/markdown/valid_package/test.md similarity index 100% rename from tests/discovery/markdown_discovery_plugin/valid_package/test.md rename to tests/discovery/markdown/valid_package/test.md diff --git a/tests/discovery/rst_discovery_plugin/exceptions.yaml b/tests/discovery/rst/exceptions.yaml similarity index 100% rename from tests/discovery/rst_discovery_plugin/exceptions.yaml rename to tests/discovery/rst/exceptions.yaml diff --git a/tests/discovery/rst_discovery_plugin/invalid_package/test.aux b/tests/discovery/rst/invalid_package/test.aux similarity index 100% rename from tests/discovery/rst_discovery_plugin/invalid_package/test.aux rename to tests/discovery/rst/invalid_package/test.aux diff --git a/tests/discovery/rst_discovery_plugin/invalid_package/test.cls b/tests/discovery/rst/invalid_package/test.cls similarity index 100% rename from tests/discovery/rst_discovery_plugin/invalid_package/test.cls rename to tests/discovery/rst/invalid_package/test.cls diff --git a/tests/discovery/rst_discovery_plugin/invalid_package/test.sty b/tests/discovery/rst/invalid_package/test.sty similarity index 100% rename from tests/discovery/rst_discovery_plugin/invalid_package/test.sty rename to tests/discovery/rst/invalid_package/test.sty diff --git a/tests/discovery/rst_discovery_plugin/test_rst_discovery_plugin.py b/tests/discovery/rst/test_rst_discovery_plugin.py similarity index 73% rename from tests/discovery/rst_discovery_plugin/test_rst_discovery_plugin.py rename to tests/discovery/rst/test_rst_discovery_plugin.py index d8d2e32..52453ea 100644 --- a/tests/discovery/rst_discovery_plugin/test_rst_discovery_plugin.py +++ b/tests/discovery/rst/test_rst_discovery_plugin.py @@ -1,38 +1,26 @@ """Unit tests for the rst discovery plugin.""" import os +import sys -from yapsy.PluginManager import PluginManager - -import statick_tool -from statick_tool.discovery_plugin import DiscoveryPlugin from statick_tool.exceptions import Exceptions from statick_tool.package import Package -from statick_tool.plugins.discovery.rst_discovery_plugin import RstDiscoveryPlugin +from statick_tool.plugins.discovery.rst import RstDiscoveryPlugin + +if sys.version_info < (3, 10): + from importlib_metadata import entry_points +else: + from importlib.metadata import entry_points def test_rst_discovery_plugin_found(): """Test that the plugin manager finds the rst discovery plugin.""" - manager = PluginManager() - # Get the path to statick_tool/__init__.py, get the directory part, and - # add 'plugins' to that to get the standard plugins dir - manager.setPluginPlaces( - [os.path.join(os.path.dirname(statick_tool.__file__), "plugins")] - ) - manager.setCategoriesFilter( - { - "Discovery": DiscoveryPlugin, - } - ) - manager.collectPlugins() - # Verify that a plugin's get_name() function returns "rst" - assert any( - plugin_info.plugin_object.get_name() == "rst" - for plugin_info in manager.getPluginsOfCategory("Discovery") - ) - # While we're at it, verify that a plugin is named rst Discovery Plugin + discovery_plugins = {} + plugins = entry_points(group="statick_tool.plugins.discovery") + for plugin_type in plugins: + plugin = plugin_type.load() + discovery_plugins[plugin_type.name] = plugin() assert any( - plugin_info.name == "rst Discovery Plugin" - for plugin_info in manager.getPluginsOfCategory("Discovery") + plugin.get_name() == "rst" for _, plugin in list(discovery_plugins.items()) ) diff --git a/tests/discovery/rst_discovery_plugin/valid_package/ignore_this/ignoreme.rst b/tests/discovery/rst/valid_package/ignore_this/ignoreme.rst similarity index 100% rename from tests/discovery/rst_discovery_plugin/valid_package/ignore_this/ignoreme.rst rename to tests/discovery/rst/valid_package/ignore_this/ignoreme.rst diff --git a/tests/discovery/rst_discovery_plugin/valid_package/test.rst b/tests/discovery/rst/valid_package/test.rst similarity index 100% rename from tests/discovery/rst_discovery_plugin/valid_package/test.rst rename to tests/discovery/rst/valid_package/test.rst diff --git a/tests/tool/markdownlint_tool_plugin/test_markdownlint_tool_plugin.py b/tests/tool/markdownlint/test_markdownlint_tool_plugin.py similarity index 82% rename from tests/tool/markdownlint_tool_plugin/test_markdownlint_tool_plugin.py rename to tests/tool/markdownlint/test_markdownlint_tool_plugin.py index 465deae..ea89184 100644 --- a/tests/tool/markdownlint_tool_plugin/test_markdownlint_tool_plugin.py +++ b/tests/tool/markdownlint/test_markdownlint_tool_plugin.py @@ -1,20 +1,22 @@ """Unit tests for the markdownlint plugin.""" - import argparse -import os -import subprocess - import mock +import os import pytest -from yapsy.PluginManager import PluginManager +import subprocess +import sys import statick_tool from statick_tool.config import Config from statick_tool.package import Package from statick_tool.plugin_context import PluginContext -from statick_tool.plugins.tool.markdownlint_tool_plugin import MarkdownlintToolPlugin +from statick_tool.plugins.tool.markdownlint import MarkdownlintToolPlugin from statick_tool.resources import Resources -from statick_tool.tool_plugin import ToolPlugin + +if sys.version_info < (3, 10): + from importlib_metadata import entry_points +else: + from importlib.metadata import entry_points def setup_markdownlint_tool_plugin(): @@ -43,27 +45,13 @@ def setup_markdownlint_tool_plugin(): def test_markdownlint_tool_plugin_found(): """Test that the plugin manager can find the markdownlint plugin.""" - manager = PluginManager() - # Get the path to statick_tool/__init__.py, get the directory part, and - # add 'plugins' to that to get the standard plugins dir - manager.setPluginPlaces( - [os.path.join(os.path.dirname(statick_tool.__file__), "plugins")] - ) - manager.setCategoriesFilter( - { - "Tool": ToolPlugin, - } - ) - manager.collectPlugins() - # Verify that a plugin's get_name() function returns "markdownlint" - assert any( - plugin_info.plugin_object.get_name() == "markdownlint" - for plugin_info in manager.getPluginsOfCategory("Tool") - ) - # While we're at it, verify that a plugin is named markdownlint Tool Plugin + plugins = {} + tool_plugins = entry_points(group="statick_tool.plugins.tool") + for plugin_type in tool_plugins: + plugin = plugin_type.load() + plugins[plugin_type.name] = plugin() assert any( - plugin_info.name == "Markdownlint Tool Plugin" - for plugin_info in manager.getPluginsOfCategory("Tool") + plugin.get_name() == "markdownlint" for _, plugin in list(plugins.items()) ) @@ -122,7 +110,7 @@ def test_markdownlint_tool_plugin_parse_invalid(): @mock.patch( - "statick_tool.plugins.tool.markdownlint_tool_plugin.subprocess.check_output" + "statick_tool.plugins.tool.markdownlint.subprocess.check_output" ) def test_markdownlint_tool_plugin_scan_calledprocesserror(mock_subprocess_check_output): """ @@ -151,7 +139,7 @@ def test_markdownlint_tool_plugin_scan_calledprocesserror(mock_subprocess_check_ @mock.patch( - "statick_tool.plugins.tool.markdownlint_tool_plugin.subprocess.check_output" + "statick_tool.plugins.tool.markdownlint.subprocess.check_output" ) def test_markdownlint_tool_plugin_scan_nodejs_error(mock_subprocess_check_output): """ @@ -185,7 +173,7 @@ def test_markdownlint_tool_plugin_scan_nodejs_error(mock_subprocess_check_output @mock.patch( - "statick_tool.plugins.tool.markdownlint_tool_plugin.subprocess.check_output" + "statick_tool.plugins.tool.markdownlint.subprocess.check_output" ) def test_markdownlint_tool_plugin_scan_oserror(mock_subprocess_check_output): """ diff --git a/tests/tool/markdownlint_tool_plugin/valid_package/rsc/.markdownlintrc b/tests/tool/markdownlint/valid_package/rsc/.markdownlintrc similarity index 100% rename from tests/tool/markdownlint_tool_plugin/valid_package/rsc/.markdownlintrc rename to tests/tool/markdownlint/valid_package/rsc/.markdownlintrc diff --git a/tests/tool/markdownlint_tool_plugin/valid_package/rsc/config.yaml b/tests/tool/markdownlint/valid_package/rsc/config.yaml similarity index 100% rename from tests/tool/markdownlint_tool_plugin/valid_package/rsc/config.yaml rename to tests/tool/markdownlint/valid_package/rsc/config.yaml diff --git a/tests/tool/markdownlint_tool_plugin/valid_package/test.md b/tests/tool/markdownlint/valid_package/test.md similarity index 100% rename from tests/tool/markdownlint_tool_plugin/valid_package/test.md rename to tests/tool/markdownlint/valid_package/test.md diff --git a/tests/tool/markdownlint_tool_plugin/valid_package/test_no_issues.md b/tests/tool/markdownlint/valid_package/test_no_issues.md similarity index 100% rename from tests/tool/markdownlint_tool_plugin/valid_package/test_no_issues.md rename to tests/tool/markdownlint/valid_package/test_no_issues.md diff --git a/tests/tool/proselint_tool_plugin/test_proselint_tool_plugin.py b/tests/tool/proselint_tool_plugin/test_proselint_tool_plugin.py deleted file mode 100644 index a014938..0000000 --- a/tests/tool/proselint_tool_plugin/test_proselint_tool_plugin.py +++ /dev/null @@ -1,171 +0,0 @@ -"""Unit tests for the proselint plugin.""" - -import argparse -import json -import os - -import pytest -from yapsy.PluginManager import PluginManager - -import statick_tool -from statick_tool.config import Config -from statick_tool.package import Package -from statick_tool.plugin_context import PluginContext -from statick_tool.plugins.tool.proselint_tool_plugin import ProselintToolPlugin -from statick_tool.resources import Resources -from statick_tool.tool_plugin import ToolPlugin - - -def setup_proselint_tool_plugin(): - """Initialize and return an instance of the proselint plugin.""" - arg_parser = argparse.ArgumentParser() - arg_parser.add_argument( - "--show-tool-output", - dest="show_tool_output", - action="store_false", - help="Show tool output", - ) - - resources = Resources( - [ - os.path.join(os.path.dirname(statick_tool.__file__), "plugins"), - os.path.join(os.path.dirname(__file__), "valid_package"), - ] - ) - config = Config(resources.get_file("config.yaml")) - plugin_context = PluginContext(arg_parser.parse_args([]), resources, config) - plugin = ProselintToolPlugin() - plugin.set_plugin_context(plugin_context) - return plugin - - -def test_proselint_tool_plugin_found(): - """Test that the plugin manager can find the proselint plugin.""" - manager = PluginManager() - # Get the path to statick_tool/__init__.py, get the directory part, and - # add 'plugins' to that to get the standard plugins dir - manager.setPluginPlaces( - [os.path.join(os.path.dirname(statick_tool.__file__), "plugins")] - ) - manager.setCategoriesFilter( - { - "Tool": ToolPlugin, - } - ) - manager.collectPlugins() - # Verify that a plugin's get_name() function returns "proselint" - assert any( - plugin_info.plugin_object.get_name() == "proselint" - for plugin_info in manager.getPluginsOfCategory("Tool") - ) - # While we're at it, verify that a plugin is named proselint Tool Plugin - assert any( - plugin_info.name == "Proselint Tool Plugin" - for plugin_info in manager.getPluginsOfCategory("Tool") - ) - - -def test_proselint_tool_plugin_scan_valid(): - """Integration test: Make sure the proselint output hasn't changed.""" - plugin = setup_proselint_tool_plugin() - if not plugin.command_exists("proselint"): - pytest.skip("Missing proselint executable.") - package = Package( - "valid_package", os.path.join(os.path.dirname(__file__), "valid_package") - ) - package["md_src"] = [ - os.path.join(os.path.dirname(__file__), "valid_package", "test_no_issues.md") - ] - issues = plugin.scan(package, "level") - assert not issues - - -def test_proselint_tool_plugin_scan_missing_src(): - """No issues should be found if no input files are provided.""" - plugin = setup_proselint_tool_plugin() - if not plugin.command_exists("proselint"): - pytest.skip("Missing proselint executable.") - package = Package( - "valid_package", os.path.join(os.path.dirname(__file__), "valid_package") - ) - issues = plugin.scan(package, "level") - assert not issues - - package["md_src"] = [] - issues = plugin.scan(package, "level") - assert not issues - - -def test_proselint_tool_plugin_scan_valid_with_issues(): - """Integration test: Make sure the proselint output hasn't changed.""" - plugin = setup_proselint_tool_plugin() - if not plugin.command_exists("proselint"): - pytest.skip("Missing proselint executable.") - package = Package( - "valid_package", os.path.join(os.path.dirname(__file__), "valid_package") - ) - package["md_src"] = [ - os.path.join(os.path.dirname(__file__), "valid_package", "test.md") - ] - issues = plugin.scan(package, "level") - assert len(issues) == 2 - - -def test_proselint_tool_plugin_parse_valid(): - """Verify that we can parse the expected output of proselint.""" - plugin = setup_proselint_tool_plugin() - output = {} - errors = {"data": {"errors": [{"check": "lexical_illusions.misc", "column": 48, "end": 5231, "extent": 12, "line": 154, "message": "There's a lexical illusion here: a word is repeated.", "replacements": None, "severity": "warning", "start": 5219}]}, "status": "success"} - output["test.md"] = json.dumps(errors) - issues = plugin.parse_tool_output(output) - assert len(issues) == 1 - assert issues[0].filename == "test.md" - assert issues[0].line_number == "154" - assert issues[0].tool == "proselint" - assert issues[0].issue_type == "lexical_illusions.misc" - assert issues[0].severity == "3" - assert issues[0].message == "There's a lexical illusion here: a word is repeated." - - errors = {"data": {"errors": []}, "status": "success"} - output["test.md"] = json.dumps(errors) - issues = plugin.parse_tool_output(output) - assert not issues - - errors = {"data": {"errors": [{"severity": "suggestion", "check": None, "line": None, "message": None}]}, "status": "success"} - output["test.md"] = json.dumps(errors) - issues = plugin.parse_tool_output(output) - assert len(issues) == 1 - assert issues[0].severity == "1" - - errors = {"data": {"errors": [{"severity": "warning", "check": None, "line": None, "message": None}]}, "status": "success"} - output["test.md"] = json.dumps(errors) - issues = plugin.parse_tool_output(output) - assert len(issues) == 1 - assert issues[0].severity == "3" - - errors = {"data": {"errors": [{"severity": "error", "check": None, "line": None, "message": None}]}, "status": "success"} - output["test.md"] = json.dumps(errors) - issues = plugin.parse_tool_output(output) - assert len(issues) == 1 - assert issues[0].severity == "5" - - errors = {"data": {"errors": [{"severity": "not_a_valid_severity", "check": None, "line": None, "message": None}]}, "status": "success"} - output["test.md"] = json.dumps(errors) - issues = plugin.parse_tool_output(output) - assert len(issues) == 1 - assert issues[0].severity == "3" - - -def test_proselint_tool_plugin_parse_invalid(): - """Verify that invalid output of proselint is ignored.""" - plugin = setup_proselint_tool_plugin() - output = {} - errors = {} - output["test.md"] = json.dumps(errors) - issues = plugin.parse_tool_output(output) - assert not issues - - errors = {"data": {"errors": [{}]}, "status": "success"} - output["test.md"] = json.dumps(errors) - issues = plugin.parse_tool_output(output) - assert not issues diff --git a/tests/tool/proselint_tool_plugin/valid_package/test.md b/tests/tool/proselint_tool_plugin/valid_package/test.md deleted file mode 100644 index fe4b3c1..0000000 --- a/tests/tool/proselint_tool_plugin/valid_package/test.md +++ /dev/null @@ -1,6 +0,0 @@ -# Test Markdown file: - - -Hello World. - -This sentence is very unique diff --git a/tests/tool/proselint_tool_plugin/valid_package/test_no_issues.md b/tests/tool/proselint_tool_plugin/valid_package/test_no_issues.md deleted file mode 100644 index 446f154..0000000 --- a/tests/tool/proselint_tool_plugin/valid_package/test_no_issues.md +++ /dev/null @@ -1,3 +0,0 @@ -# Test Markdown file - -Hello World. diff --git a/tests/tool/rstcheck_tool_plugin/test_rstcheck_tool_plugin.py b/tests/tool/rstcheck/test_rstcheck_tool_plugin.py similarity index 80% rename from tests/tool/rstcheck_tool_plugin/test_rstcheck_tool_plugin.py rename to tests/tool/rstcheck/test_rstcheck_tool_plugin.py index d455f9a..9802490 100644 --- a/tests/tool/rstcheck_tool_plugin/test_rstcheck_tool_plugin.py +++ b/tests/tool/rstcheck/test_rstcheck_tool_plugin.py @@ -1,20 +1,22 @@ """Unit tests for the rstcheck plugin.""" - import argparse -import os -import subprocess - import mock +import os import pytest -from yapsy.PluginManager import PluginManager +import subprocess +import sys import statick_tool from statick_tool.config import Config from statick_tool.package import Package from statick_tool.plugin_context import PluginContext -from statick_tool.plugins.tool.rstcheck_tool_plugin import RstcheckToolPlugin +from statick_tool.plugins.tool.rstcheck import RstcheckToolPlugin from statick_tool.resources import Resources -from statick_tool.tool_plugin import ToolPlugin + +if sys.version_info < (3, 10): + from importlib_metadata import entry_points +else: + from importlib.metadata import entry_points def setup_rstcheck_tool_plugin(): @@ -43,27 +45,13 @@ def setup_rstcheck_tool_plugin(): def test_rstcheck_tool_plugin_found(): """Test that the plugin manager can find the rstcheck plugin.""" - manager = PluginManager() - # Get the path to statick_tool/__init__.py, get the directory part, and - # add 'plugins' to that to get the standard plugins dir - manager.setPluginPlaces( - [os.path.join(os.path.dirname(statick_tool.__file__), "plugins")] - ) - manager.setCategoriesFilter( - { - "Tool": ToolPlugin, - } - ) - manager.collectPlugins() - # Verify that a plugin's get_name() function returns "rstcheck" - assert any( - plugin_info.plugin_object.get_name() == "rstcheck" - for plugin_info in manager.getPluginsOfCategory("Tool") - ) - # While we're at it, verify that a plugin is named rstcheck Tool Plugin + plugins = {} + tool_plugins = entry_points(group="statick_tool.plugins.tool") + for plugin_type in tool_plugins: + plugin = plugin_type.load() + plugins[plugin_type.name] = plugin() assert any( - plugin_info.name == "rstcheck Tool Plugin" - for plugin_info in manager.getPluginsOfCategory("Tool") + plugin.get_name() == "rstcheck" for _, plugin in list(plugins.items()) ) @@ -119,7 +107,7 @@ def test_rstcheck_tool_plugin_parse_invalid(): assert not issues -@mock.patch("statick_tool.plugins.tool.rstcheck_tool_plugin.subprocess.check_output") +@mock.patch("statick_tool.plugins.tool.rstcheck.subprocess.check_output") def test_rstcheck_tool_plugin_scan_calledprocesserror(mock_subprocess_check_output): """ Test what happens when a CalledProcessError is raised (usually means rstcheck hit an error). @@ -146,7 +134,7 @@ def test_rstcheck_tool_plugin_scan_calledprocesserror(mock_subprocess_check_outp assert not issues -@mock.patch("statick_tool.plugins.tool.rstcheck_tool_plugin.subprocess.check_output") +@mock.patch("statick_tool.plugins.tool.rstcheck.subprocess.check_output") def test_rstcheck_tool_plugin_scan_oserror(mock_subprocess_check_output): """ Test what happens when an OSError is raised (usually means rstcheck doesn't exist). diff --git a/tests/tool/rstcheck_tool_plugin/valid_package/ignore_this/ignoreme.rst b/tests/tool/rstcheck/valid_package/ignore_this/ignoreme.rst similarity index 100% rename from tests/tool/rstcheck_tool_plugin/valid_package/ignore_this/ignoreme.rst rename to tests/tool/rstcheck/valid_package/ignore_this/ignoreme.rst diff --git a/tests/tool/rstcheck_tool_plugin/valid_package/oddextensionrst.source b/tests/tool/rstcheck/valid_package/oddextensionrst.source similarity index 100% rename from tests/tool/rstcheck_tool_plugin/valid_package/oddextensionrst.source rename to tests/tool/rstcheck/valid_package/oddextensionrst.source diff --git a/tests/tool/rstcheck_tool_plugin/valid_package/test.rst b/tests/tool/rstcheck/valid_package/test.rst similarity index 100% rename from tests/tool/rstcheck_tool_plugin/valid_package/test.rst rename to tests/tool/rstcheck/valid_package/test.rst diff --git a/tests/tool/rstcheck_tool_plugin/valid_package/test_no_issues.rst b/tests/tool/rstcheck/valid_package/test_no_issues.rst similarity index 100% rename from tests/tool/rstcheck_tool_plugin/valid_package/test_no_issues.rst rename to tests/tool/rstcheck/valid_package/test_no_issues.rst diff --git a/tests/tool/rstlint_tool_plugin/test_rstlint_tool_plugin.py b/tests/tool/rstlint/test_rstlint_tool_plugin.py similarity index 70% rename from tests/tool/rstlint_tool_plugin/test_rstlint_tool_plugin.py rename to tests/tool/rstlint/test_rstlint_tool_plugin.py index fe36a25..5339de4 100644 --- a/tests/tool/rstlint_tool_plugin/test_rstlint_tool_plugin.py +++ b/tests/tool/rstlint/test_rstlint_tool_plugin.py @@ -1,18 +1,20 @@ """Unit tests for the rstlint plugin.""" - import argparse import os - import pytest -from yapsy.PluginManager import PluginManager +import sys import statick_tool from statick_tool.config import Config from statick_tool.package import Package from statick_tool.plugin_context import PluginContext -from statick_tool.plugins.tool.rstlint_tool_plugin import RstlintToolPlugin +from statick_tool.plugins.tool.rstlint import RstlintToolPlugin from statick_tool.resources import Resources -from statick_tool.tool_plugin import ToolPlugin + +if sys.version_info < (3, 10): + from importlib_metadata import entry_points +else: + from importlib.metadata import entry_points def setup_rstlint_tool_plugin(): @@ -40,27 +42,13 @@ def setup_rstlint_tool_plugin(): def test_rstlint_tool_plugin_found(): """Test that the plugin manager can find the rstlint plugin.""" - manager = PluginManager() - # Get the path to statick_tool/__init__.py, get the directory part, and - # add 'plugins' to that to get the standard plugins dir - manager.setPluginPlaces( - [os.path.join(os.path.dirname(statick_tool.__file__), "plugins")] - ) - manager.setCategoriesFilter( - { - "Tool": ToolPlugin, - } - ) - manager.collectPlugins() - # Verify that a plugin's get_name() function returns "rstlint" - assert any( - plugin_info.plugin_object.get_name() == "rstlint" - for plugin_info in manager.getPluginsOfCategory("Tool") - ) - # While we're at it, verify that a plugin is named rstlint Tool Plugin + plugins = {} + tool_plugins = entry_points(group="statick_tool.plugins.tool") + for plugin_type in tool_plugins: + plugin = plugin_type.load() + plugins[plugin_type.name] = plugin() assert any( - plugin_info.name == "rstlint Tool Plugin" - for plugin_info in manager.getPluginsOfCategory("Tool") + plugin.get_name() == "rstlint" for _, plugin in list(plugins.items()) ) diff --git a/tests/tool/rstlint_tool_plugin/valid_package/ignore_this/ignoreme.rst b/tests/tool/rstlint/valid_package/ignore_this/ignoreme.rst similarity index 100% rename from tests/tool/rstlint_tool_plugin/valid_package/ignore_this/ignoreme.rst rename to tests/tool/rstlint/valid_package/ignore_this/ignoreme.rst diff --git a/tests/tool/rstlint_tool_plugin/valid_package/oddextensionrst.source b/tests/tool/rstlint/valid_package/oddextensionrst.source similarity index 100% rename from tests/tool/rstlint_tool_plugin/valid_package/oddextensionrst.source rename to tests/tool/rstlint/valid_package/oddextensionrst.source diff --git a/tests/tool/rstlint_tool_plugin/valid_package/test.rst b/tests/tool/rstlint/valid_package/test.rst similarity index 100% rename from tests/tool/rstlint_tool_plugin/valid_package/test.rst rename to tests/tool/rstlint/valid_package/test.rst diff --git a/tests/tool/rstlint_tool_plugin/valid_package/test_no_issues.rst b/tests/tool/rstlint/valid_package/test_no_issues.rst similarity index 100% rename from tests/tool/rstlint_tool_plugin/valid_package/test_no_issues.rst rename to tests/tool/rstlint/valid_package/test_no_issues.rst diff --git a/tests/tool/writegood_tool_plugin/test_writegood_tool_plugin.py b/tests/tool/writegood/test_writegood_tool_plugin.py similarity index 87% rename from tests/tool/writegood_tool_plugin/test_writegood_tool_plugin.py rename to tests/tool/writegood/test_writegood_tool_plugin.py index c62b70c..5714108 100644 --- a/tests/tool/writegood_tool_plugin/test_writegood_tool_plugin.py +++ b/tests/tool/writegood/test_writegood_tool_plugin.py @@ -1,20 +1,22 @@ """Unit tests for the writegood plugin.""" - import argparse -import os -import subprocess - import mock +import os import pytest -from yapsy.PluginManager import PluginManager +import subprocess +import sys import statick_tool from statick_tool.config import Config from statick_tool.package import Package from statick_tool.plugin_context import PluginContext -from statick_tool.plugins.tool.writegood_tool_plugin import WriteGoodToolPlugin +from statick_tool.plugins.tool.writegood import WriteGoodToolPlugin from statick_tool.resources import Resources -from statick_tool.tool_plugin import ToolPlugin + +if sys.version_info < (3, 10): + from importlib_metadata import entry_points +else: + from importlib.metadata import entry_points def setup_writegood_tool_plugin(): @@ -43,27 +45,13 @@ def setup_writegood_tool_plugin(): def test_writegood_tool_plugin_found(): """Test that the plugin manager can find the writegood plugin.""" - manager = PluginManager() - # Get the path to statick_tool/__init__.py, get the directory part, and - # add 'plugins' to that to get the standard plugins dir - manager.setPluginPlaces( - [os.path.join(os.path.dirname(statick_tool.__file__), "plugins")] - ) - manager.setCategoriesFilter( - { - "Tool": ToolPlugin, - } - ) - manager.collectPlugins() - # Verify that a plugin's get_name() function returns "writegood" - assert any( - plugin_info.plugin_object.get_name() == "writegood" - for plugin_info in manager.getPluginsOfCategory("Tool") - ) - # While we're at it, verify that a plugin is named writegood Tool Plugin + plugins = {} + tool_plugins = entry_points(group="statick_tool.plugins.tool") + for plugin_type in tool_plugins: + plugin = plugin_type.load() + plugins[plugin_type.name] = plugin() assert any( - plugin_info.name == "WriteGood Tool Plugin" - for plugin_info in manager.getPluginsOfCategory("Tool") + plugin.get_name() == "writegood" for _, plugin in list(plugins.items()) ) @@ -173,7 +161,7 @@ def test_writegood_tool_plugin_parse_invalid(): @mock.patch( - "statick_tool.plugins.tool.writegood_tool_plugin.subprocess.check_output" + "statick_tool.plugins.tool.writegood.subprocess.check_output" ) def test_writegood_tool_plugin_scan_calledprocesserror(mock_subprocess_check_output): """ @@ -214,7 +202,7 @@ def test_writegood_tool_plugin_scan_calledprocesserror(mock_subprocess_check_out @mock.patch( - "statick_tool.plugins.tool.writegood_tool_plugin.subprocess.check_output" + "statick_tool.plugins.tool.writegood.subprocess.check_output" ) def test_writegood_tool_plugin_scan_oserror(mock_subprocess_check_output): """ diff --git a/tests/tool/writegood_tool_plugin/valid_package/rsc/config.yaml b/tests/tool/writegood/valid_package/rsc/config.yaml similarity index 100% rename from tests/tool/writegood_tool_plugin/valid_package/rsc/config.yaml rename to tests/tool/writegood/valid_package/rsc/config.yaml diff --git a/tests/tool/writegood_tool_plugin/valid_package/test.md b/tests/tool/writegood/valid_package/test.md similarity index 100% rename from tests/tool/writegood_tool_plugin/valid_package/test.md rename to tests/tool/writegood/valid_package/test.md diff --git a/tests/tool/writegood_tool_plugin/valid_package/test.rst b/tests/tool/writegood/valid_package/test.rst similarity index 100% rename from tests/tool/writegood_tool_plugin/valid_package/test.rst rename to tests/tool/writegood/valid_package/test.rst diff --git a/tests/tool/writegood_tool_plugin/valid_package/test_no_issues.md b/tests/tool/writegood/valid_package/test_no_issues.md similarity index 100% rename from tests/tool/writegood_tool_plugin/valid_package/test_no_issues.md rename to tests/tool/writegood/valid_package/test_no_issues.md diff --git a/tox.ini b/tox.ini index d11cd4a..14ff8b9 100644 --- a/tox.ini +++ b/tox.ini @@ -1,50 +1,28 @@ [tox] -envlist = py38, py39, py310, py311 +envlist = py39, py310, py311, py312, py313 skip_missing_interpreters = true [pytest] -norecursedirs = .tox - -# To work with black a specific configuration is required. -# https://github.com/psf/black#how-black-wraps-lines -[isort] -known_first_party = statick_tool -multi_line_output = 3 -include_trailing_comma = True -force_grid_wrap = 0 -use_parentheses = True -line_length = 88 +norecursedirs = .tox build [gh-actions] python = - 3.8: py38 3.9: py39 3.10: py310 3.11: py311 + 3.12: py312 + 3.13: py313 [testenv] changedir = {toxinidir}/output-{envname} -passenv = CI -setenv = PY_IGNORE_IMPORTMISMATCH = 1 deps = - pycodestyle - pydocstyle - pytest - pytest-cov - pytest-isort .[test] commands = - pydocstyle ../src/ - pycodestyle --ignore=E203,E501,W503 ../src/ - pytest --isort \ - --cov=statick_tool.plugins.discovery.markdown_discovery_plugin \ - --cov=statick_tool.plugins.discovery.rst_discovery_plugin \ - --cov=statick_tool.plugins.tool.markdownlint_tool_plugin \ - --cov=statick_tool.plugins.tool.proselint_tool_plugin \ - --cov=statick_tool.plugins.tool.rstlint_tool_plugin \ - --cov=statick_tool.plugins.tool.rstcheck_tool_plugin \ - --cov=statick_tool.plugins.tool.writegood_tool_plugin \ + pytest \ + --cov={toxinidir}/src/statick_tool \ --cov-report term-missing \ --doctest-modules \ + --junit-xml=statick-{envname}-junit.xml \ + --junit-prefix={envname} \ {toxinidir} {posargs} coverage xml