diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..50a37d9 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,20 @@ +# configuring pre-commit hooks for chasten. +# this ensures users do not commit problematic code +repos: +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.5.0 + hooks: + - id: check-ast + files: '\.py$' + - id: check-case-conflict + - id: check-merge-conflict + - id: forbid-submodules + - id: trailing-whitespace + +- repo: local + hooks: + - id: fix-linting + files: '\.py$' + entry: poetry run task lint --fix + language: system + name: Fix Linting diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 53df780..e1a2eba 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -28,6 +28,21 @@ If the issue already exists, share any helpful information that you have gained Any changes being made to our program must first be done in a branch or fork. Once you (and your fellow contributors) are done making changes, you may create a pull request (PR) to the [main repository](https://github.com/AstuteSource/chasten). +### Pre-Commit Hooks + +Enabling pre-commit hooks on your system will save you from accidentally making +unwanted changes, such as incorrect formatting, committing merge conflicts, etc. + +You can enable pre-commit hooks after installing `poetry`: + +```sh +poetry install +poetry run task pre-commit-install # this sets up pre-commit hooks +``` + +Now, when you make commits, our specific checks will run. This will give you +greater confidence that your contributions align with our standards! + ### Branches Branches are one of the possible features of GitHub that you could use to make changes to our project. Learn about branches [here](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-branches). diff --git a/chasten/configApp.py b/chasten/configApp.py index 2177f78..6093195 100644 --- a/chasten/configApp.py +++ b/chasten/configApp.py @@ -111,7 +111,7 @@ class config_App(App): color: black; } """ - Check: ClassVar = ["", "1", False] # noqa: RUF012 + Check: ClassVar = ["", "1", False] Valid: bool = False def on_input_changed(self, event: Input.Changed) -> None: diff --git a/chasten/output.py b/chasten/output.py index bfa8bb0..f0b1e64 100644 --- a/chasten/output.py +++ b/chasten/output.py @@ -39,7 +39,7 @@ def setup( def print_diagnostics(verbose: bool, **configurations: Any) -> None: """Display all variables input to the function.""" - global console # noqa: disable=PLW0603 + global console # noqa: PLW0602 # display diagnostic information for each configuration keyword argument if verbose: console.print(":sparkles: Configured with these parameters:") @@ -53,7 +53,7 @@ def print_diagnostics(verbose: bool, **configurations: Any) -> None: def opt_print_log(verbose: bool, **contents: Any) -> None: """Produce logging information and only print when not verbose.""" - global console # noqa: disable=PLW0603 + global console # noqa: PLW0602 # iterate through each of the configuration keyword arguments for current in contents: # print the name and the value of the keyword argument @@ -66,7 +66,7 @@ def opt_print_log(verbose: bool, **contents: Any) -> None: def print_header() -> None: """Display tool details in the header.""" - global console # noqa: disable=PLW0603 + global console # noqa: PLW0602 console.print() console.print( constants.chasten.Emoji + constants.markers.Space + constants.chasten.Tagline @@ -76,21 +76,21 @@ def print_header() -> None: def print_server() -> None: """Display server details in the header.""" - global console # noqa: disable=PLW0603 + global console # noqa: PLW0602 console.print(constants.output.Syslog) console.print() def print_test_start() -> None: """Display details about the test run.""" - global console # noqa: disable=PLW0603 + global console # noqa: PLW0602 console.print(constants.output.Test_Start) console.print() def print_test_finish() -> None: """Display details about the test run.""" - global console # noqa: disable=PLW0603 + global console # noqa: PLW0602 console.print() console.print(":sparkles: Finished running test suite for the specified program") console.print() @@ -98,7 +98,7 @@ def print_test_finish() -> None: def print_footer() -> None: """Display concluding details in the footer.""" - global console # noqa: disable=PLW0603 + global console # noqa: PLW0602 console.print() @@ -136,7 +136,7 @@ def shorten_file_name(file_name: str, max_length: int) -> str: def print_list_contents(container: List[Path]) -> None: """Display the contents of the list in an easy-to-read fashion.""" - global console # noqa: disable=PLW0603 + global console # noqa: PLW0602 # group all of the files by the directory that contains them; # note that this is important because the contain can contain # paths that specify files in different directories @@ -159,7 +159,7 @@ def print_list_contents(container: List[Path]) -> None: def print_analysis_details(chasten: results.Chasten, verbose: bool = False) -> None: """Print all of the verbose debugging details for the results of an analysis.""" - global console # noqa: disable=PLW0603 + global console # noqa: PLW0602 # 1) Note: see the BaseModel definitions in results.py for more details # about the objects and their relationships # 2) Note: the _match object that is inside of a Match BaseModel subclass diff --git a/chasten/server.py b/chasten/server.py index acf7511..af3fe24 100644 --- a/chasten/server.py +++ b/chasten/server.py @@ -18,7 +18,7 @@ class SyslogUDPHandler(socketserver.BaseRequestHandler): def handle(self): """Receive a message and then display it in output and log it to a file.""" - global logger # noqa: disable=PLW0603 + global logger # noqa: PLW0602 # receive the message from the syslog logging client message = bytes.decode( self.request[0].strip(), encoding=constants.server.Utf8_Encoding @@ -38,7 +38,7 @@ def handle(self): def start_syslog_server(): """Start a syslog server.""" - global logger # noqa: disable=PLW0603 + global logger # noqa: PLW0602 # always log all of the messages to a file logger.setLevel(logging.DEBUG) # create a RotatingFileHandler such that: diff --git a/poetry.lock b/poetry.lock index 2b35ccc..56843ba 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.7.0 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. [[package]] name = "aiofiles" @@ -275,6 +275,7 @@ files = [ {file = "black-23.11.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5133f5507007ba08d8b7b263c7aa0f931af5ba88a29beacc4b2dc23fcefe9c06"}, {file = "black-23.11.0-cp39-cp39-win_amd64.whl", hash = "sha256:421f3e44aa67138ab1b9bfbc22ee3780b22fa5b291e4db8ab7eee95200726b07"}, {file = "black-23.11.0-py3-none-any.whl", hash = "sha256:54caaa703227c6e0c87b76326d0862184729a69b73d3b7305b6288e1d830067e"}, + {file = "black-23.11.0.tar.gz", hash = "sha256:4c68855825ff432d197229846f971bc4d6666ce90492e5b02013bcaca4d9ab05"}, ] [package.dependencies] @@ -376,6 +377,17 @@ files = [ [package.dependencies] pycparser = "*" +[[package]] +name = "cfgv" +version = "3.4.0" +description = "Validate configuration and produce human readable error messages." +optional = false +python-versions = ">=3.8" +files = [ + {file = "cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9"}, + {file = "cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560"}, +] + [[package]] name = "charset-normalizer" version = "3.3.2" @@ -842,6 +854,17 @@ sqlite-regex = "*" [package.extras] test = ["pytest"] +[[package]] +name = "distlib" +version = "0.3.7" +description = "Distribution utilities" +optional = false +python-versions = "*" +files = [ + {file = "distlib-0.3.7-py2.py3-none-any.whl", hash = "sha256:2e24928bc811348f0feb63014e97aaae3037f2cf48712d51ae61df7fd6075057"}, + {file = "distlib-0.3.7.tar.gz", hash = "sha256:9dafe54b34a028eafd95039d5e5d4851a13734540f1331060d31c9916e7147a8"}, +] + [[package]] name = "elementpath" version = "4.1.5" @@ -870,6 +893,22 @@ files = [ [package.extras] testing = ["hatch", "pre-commit", "pytest", "tox"] +[[package]] +name = "filelock" +version = "3.13.1" +description = "A platform independent file lock." +optional = false +python-versions = ">=3.8" +files = [ + {file = "filelock-3.13.1-py3-none-any.whl", hash = "sha256:57dbda9b35157b05fb3e58ee91448612eb674172fab98ee235ccb0b5bee19a1c"}, + {file = "filelock-3.13.1.tar.gz", hash = "sha256:521f5f56c50f8426f5e03ad3b281b490a87ef15bc6c526f168290f0c7148d44e"}, +] + +[package.extras] +docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.24)"] +testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)"] +typing = ["typing-extensions (>=4.8)"] + [[package]] name = "flask" version = "3.0.0" @@ -1167,6 +1206,20 @@ files = [ hypothesis = ">=6.31.6" jsonschema = ">=4.0.0" +[[package]] +name = "identify" +version = "2.5.32" +description = "File identification library for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "identify-2.5.32-py2.py3-none-any.whl", hash = "sha256:0b7656ef6cba81664b783352c73f8c24b39cf82f926f78f4550eda928e5e0545"}, + {file = "identify-2.5.32.tar.gz", hash = "sha256:5d9979348ec1a21c768ae07e0a652924538e8bce67313a73cb0f681cf08ba407"}, +] + +[package.extras] +license = ["ukkonen"] + [[package]] name = "idna" version = "3.4" @@ -1987,6 +2040,20 @@ files = [ {file = "nest_asyncio-1.5.8.tar.gz", hash = "sha256:25aa2ca0d2a5b5531956b9e273b45cf664cae2b145101d73b86b199978d48fdb"}, ] +[[package]] +name = "nodeenv" +version = "1.8.0" +description = "Node.js virtual environment builder" +optional = false +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*" +files = [ + {file = "nodeenv-1.8.0-py2.py3-none-any.whl", hash = "sha256:df865724bb3c3adc86b3876fa209771517b0cfe596beff01a92700e0e8be4cec"}, + {file = "nodeenv-1.8.0.tar.gz", hash = "sha256:d51e0c37e64fbf47d017feac3145cdbb58836d7eee8c6f6d3b6880c5456227d2"}, +] + +[package.dependencies] +setuptools = "*" + [[package]] name = "numpy" version = "1.26.2" @@ -2293,6 +2360,24 @@ files = [ {file = "pprintpp-0.4.0.tar.gz", hash = "sha256:ea826108e2c7f49dc6d66c752973c3fc9749142a798d6b254e1e301cfdbc6403"}, ] +[[package]] +name = "pre-commit" +version = "3.5.0" +description = "A framework for managing and maintaining multi-language pre-commit hooks." +optional = false +python-versions = ">=3.8" +files = [ + {file = "pre_commit-3.5.0-py2.py3-none-any.whl", hash = "sha256:841dc9aef25daba9a0238cd27984041fa0467b4199fc4852e27950664919f660"}, + {file = "pre_commit-3.5.0.tar.gz", hash = "sha256:5804465c675b659b0862f07907f96295d490822a450c4c40e747d0b1c6ebcb32"}, +] + +[package.dependencies] +cfgv = ">=2.0.0" +identify = ">=1.0.0" +nodeenv = ">=0.11.1" +pyyaml = ">=5.1" +virtualenv = ">=20.10.0" + [[package]] name = "psutil" version = "5.9.6" @@ -2990,28 +3075,28 @@ files = [ [[package]] name = "ruff" -version = "0.0.277" -description = "An extremely fast Python linter, written in Rust." +version = "0.1.7" +description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.0.277-py3-none-macosx_10_7_x86_64.whl", hash = "sha256:3250b24333ef419b7a232080d9724ccc4d2da1dbbe4ce85c4caa2290d83200f8"}, - {file = "ruff-0.0.277-py3-none-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:3e60605e07482183ba1c1b7237eca827bd6cbd3535fe8a4ede28cbe2a323cb97"}, - {file = "ruff-0.0.277-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7baa97c3d7186e5ed4d5d4f6834d759a27e56cf7d5874b98c507335f0ad5aadb"}, - {file = "ruff-0.0.277-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:74e4b206cb24f2e98a615f87dbe0bde18105217cbcc8eb785bb05a644855ba50"}, - {file = "ruff-0.0.277-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:479864a3ccd8a6a20a37a6e7577bdc2406868ee80b1e65605478ad3b8eb2ba0b"}, - {file = "ruff-0.0.277-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:468bfb0a7567443cec3d03cf408d6f562b52f30c3c29df19927f1e0e13a40cd7"}, - {file = "ruff-0.0.277-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f32ec416c24542ca2f9cc8c8b65b84560530d338aaf247a4a78e74b99cd476b4"}, - {file = "ruff-0.0.277-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:14a7b2f00f149c5a295f188a643ac25226ff8a4d08f7a62b1d4b0a1dc9f9b85c"}, - {file = "ruff-0.0.277-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9879f59f763cc5628aa01c31ad256a0f4dc61a29355c7315b83c2a5aac932b5"}, - {file = "ruff-0.0.277-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:f612e0a14b3d145d90eb6ead990064e22f6f27281d847237560b4e10bf2251f3"}, - {file = "ruff-0.0.277-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:323b674c98078be9aaded5b8b51c0d9c424486566fb6ec18439b496ce79e5998"}, - {file = "ruff-0.0.277-py3-none-musllinux_1_2_i686.whl", hash = "sha256:3a43fbe026ca1a2a8c45aa0d600a0116bec4dfa6f8bf0c3b871ecda51ef2b5dd"}, - {file = "ruff-0.0.277-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:734165ea8feb81b0d53e3bf523adc2413fdb76f1264cde99555161dd5a725522"}, - {file = "ruff-0.0.277-py3-none-win32.whl", hash = "sha256:88d0f2afb2e0c26ac1120e7061ddda2a566196ec4007bd66d558f13b374b9efc"}, - {file = "ruff-0.0.277-py3-none-win_amd64.whl", hash = "sha256:6fe81732f788894a00f6ade1fe69e996cc9e485b7c35b0f53fb00284397284b2"}, - {file = "ruff-0.0.277-py3-none-win_arm64.whl", hash = "sha256:2d4444c60f2e705c14cd802b55cd2b561d25bf4311702c463a002392d3116b22"}, - {file = "ruff-0.0.277.tar.gz", hash = "sha256:2dab13cdedbf3af6d4427c07f47143746b6b95d9e4a254ac369a0edb9280a0d2"}, + {file = "ruff-0.1.7-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:7f80496854fdc65b6659c271d2c26e90d4d401e6a4a31908e7e334fab4645aac"}, + {file = "ruff-0.1.7-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:1ea109bdb23c2a4413f397ebd8ac32cb498bee234d4191ae1a310af760e5d287"}, + {file = "ruff-0.1.7-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b0c2de9dd9daf5e07624c24add25c3a490dbf74b0e9bca4145c632457b3b42a"}, + {file = "ruff-0.1.7-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:69a4bed13bc1d5dabf3902522b5a2aadfebe28226c6269694283c3b0cecb45fd"}, + {file = "ruff-0.1.7-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:de02ca331f2143195a712983a57137c5ec0f10acc4aa81f7c1f86519e52b92a1"}, + {file = "ruff-0.1.7-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:45b38c3f8788a65e6a2cab02e0f7adfa88872696839d9882c13b7e2f35d64c5f"}, + {file = "ruff-0.1.7-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6c64cb67b2025b1ac6d58e5ffca8f7b3f7fd921f35e78198411237e4f0db8e73"}, + {file = "ruff-0.1.7-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9dcc6bb2f4df59cb5b4b40ff14be7d57012179d69c6565c1da0d1f013d29951b"}, + {file = "ruff-0.1.7-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:df2bb4bb6bbe921f6b4f5b6fdd8d8468c940731cb9406f274ae8c5ed7a78c478"}, + {file = "ruff-0.1.7-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:276a89bcb149b3d8c1b11d91aa81898fe698900ed553a08129b38d9d6570e717"}, + {file = "ruff-0.1.7-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:90c958fe950735041f1c80d21b42184f1072cc3975d05e736e8d66fc377119ea"}, + {file = "ruff-0.1.7-py3-none-musllinux_1_2_i686.whl", hash = "sha256:6b05e3b123f93bb4146a761b7a7d57af8cb7384ccb2502d29d736eaade0db519"}, + {file = "ruff-0.1.7-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:290ecab680dce94affebefe0bbca2322a6277e83d4f29234627e0f8f6b4fa9ce"}, + {file = "ruff-0.1.7-py3-none-win32.whl", hash = "sha256:416dfd0bd45d1a2baa3b1b07b1b9758e7d993c256d3e51dc6e03a5e7901c7d80"}, + {file = "ruff-0.1.7-py3-none-win_amd64.whl", hash = "sha256:4af95fd1d3b001fc41325064336db36e3d27d2004cdb6d21fd617d45a172dd96"}, + {file = "ruff-0.1.7-py3-none-win_arm64.whl", hash = "sha256:0683b7bfbb95e6df3c7c04fe9d78f631f8e8ba4868dfc932d43d690698057e2e"}, + {file = "ruff-0.1.7.tar.gz", hash = "sha256:dffd699d07abf54833e5f6cc50b85a6ff043715da8788c4a79bcd4ab4734d306"}, ] [[package]] @@ -3442,6 +3527,26 @@ h11 = ">=0.8" [package.extras] standard = ["colorama (>=0.4)", "httptools (>=0.5.0)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "watchfiles (>=0.13)", "websockets (>=10.4)"] +[[package]] +name = "virtualenv" +version = "20.24.7" +description = "Virtual Python Environment builder" +optional = false +python-versions = ">=3.7" +files = [ + {file = "virtualenv-20.24.7-py3-none-any.whl", hash = "sha256:a18b3fd0314ca59a2e9f4b556819ed07183b3e9a3702ecfe213f593d44f7b3fd"}, + {file = "virtualenv-20.24.7.tar.gz", hash = "sha256:69050ffb42419c91f6c1284a7b24e0475d793447e35929b488bf6a0aade39353"}, +] + +[package.dependencies] +distlib = ">=0.3.7,<1" +filelock = ">=3.12.2,<4" +platformdirs = ">=3.9.1,<5" + +[package.extras] +docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] +test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"] + [[package]] name = "werkzeug" version = "3.0.1" @@ -3575,4 +3680,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "919229c283aae8adf17519b2722864f93f07b41cee22c9cced339ef555027dd0" +content-hash = "de2cf9d7203422aa78a6c8a26d8b893b6bf1ac81ef0548ce0272540b7b57e67a" diff --git a/pyproject.toml b/pyproject.toml index bb7654a..edc9079 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -42,7 +42,7 @@ numpy = "^1.25.2" [tool.poetry.group.dev.dependencies] pytest = "^7.4.0" black = "^23.3.0" -ruff = "^0.0.277" +ruff = "^0.1.7" taskipy = "^1.11.0" mypy = "^1.4.1" isort = "^5.12.0" @@ -53,6 +53,7 @@ types-pyyaml = "^6.0.12.10" types-jsonschema = "^4.17.0.9" types-requests = "^2.31.0.10" hypothesis-jsonschema = "^0.22.1" +pre-commit = "^3.5.0" pytest-clarity = "^1.0.1" pytest-randomly = "^3.13.0" pytest-pretty = "^1.2.0" @@ -119,6 +120,7 @@ test-api = { cmd = "{openai-test}", help = "Run openai powered test cases", use_ not-openai-test = { cmd = "{not-openai-test}", help = "Run openai powered test cases", use_vars = true } test-coverage = { cmd = "{coverage-test-command}", help = "Run coverage monitoring for the test suite", use_vars = true } test-coverage-silent = { cmd = "{coverage-test-command-silent}", help = "Run coverage monitoring for tests without output", use_vars = true } +pre-commit-install = { cmd = "pre-commit install", help = "Install or update pre-commit hooks" } [build-system] requires = ["poetry-core"]