From 6f66f456cf11b02752b09b1c57295dbedb75fda9 Mon Sep 17 00:00:00 2001 From: Nicholas Felt Date: Mon, 12 Aug 2024 08:27:39 -0700 Subject: [PATCH] Add basic linting and formatting checks (#68) * Added configurations for basic linting and formatting checks * simplify the used ruff ruleset for now * Add GitHub Workflow to perform linting and show results --- .github/workflows/code-linting.yml | 25 +++++ .github/workflows/tek-repo-lint.yml | 164 +++++----------------------- .gitignore | 13 +++ .pre-commit-config.yaml | 46 ++++++++ LICENSE.md | 1 - README.md | 6 +- pyproject.toml | 54 +++++++++ 7 files changed, 167 insertions(+), 142 deletions(-) create mode 100644 .github/workflows/code-linting.yml create mode 100644 .gitignore create mode 100644 .pre-commit-config.yaml create mode 100644 pyproject.toml diff --git a/.github/workflows/code-linting.yml b/.github/workflows/code-linting.yml new file mode 100644 index 0000000..e74479c --- /dev/null +++ b/.github/workflows/code-linting.yml @@ -0,0 +1,25 @@ +--- +name: Lint Code +on: + push: + branches: [master] + pull_request: + branches: [master] +# Cancel running jobs for the same workflow and branch. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/master' }} +jobs: + lint-python: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: x # any version + check-latest: true + - name: Install tox + run: python -m pip install tox + - name: Test + run: tox -ve linting diff --git a/.github/workflows/tek-repo-lint.yml b/.github/workflows/tek-repo-lint.yml index a88ddb9..3d41262 100644 --- a/.github/workflows/tek-repo-lint.yml +++ b/.github/workflows/tek-repo-lint.yml @@ -1,151 +1,39 @@ +--- name: tek-repo-lint on: push: - branches: [ "main" ] + branches: [master] pull_request: - branches: [ "main" ] + branches: [master] workflow_dispatch: -# select correct state for repository -env: - # state: private - state: public - jobs: - public-or-private-repo: - runs-on: ubuntu-latest - outputs: - repostate: ${{ steps.repo-state.outputs.repostate }} - steps: - - - name: Repo state - id: repo-state - run: echo "repostate=${{env.state}}" >> $GITHUB_OUTPUT - - name: Repo public? - if: "${{ env.state == 'public' }}" - run: echo "Workflow has repo set as public. If this is incorrect, uncomment line 11." - - name: Repo private? - if: "${{ env.state == 'private' }}" - run: echo "Workflow has repo set as private. If this is incorrect, uncomment line 12." - - check-for-codeowners-file: - runs-on: ubuntu-latest - steps: - - - name: Checkout repo - uses: actions/checkout@v3 - - - name: Check for CODEOWNERS - id: codeowners_file - uses: initialstate/file-check-action@v1 - with: - file: ".github/CODEOWNERS" - - - name: CODEOWNERS file Output Test - run: echo ${{ steps.codeowners_file.outputs.file_exists }} - - - name: CODEOWNERS file exists with content - if: steps.codeowners_file.outputs.file_exists == 'true' - run: echo CODEOWNERS file exists! - - - name: CODEOWNERS file does not exist - if: steps.codeowners_file.outputs.file_exists == 'false' - run: echo CODEOWNERS file does not exist! - - check-for-readme-file: - runs-on: ubuntu-latest - steps: - - - name: Checkout repo - uses: actions/checkout@v3 - - - name: Check for README.md - id: readme_file - uses: initialstate/file-check-action@v1 - with: - file: "README" - - - name: README file Output Test - run: echo ${{ steps.readme_file.outputs.file_exists }} - - - name: README file exists with content - if: steps.readme_file.outputs.file_exists == 'true' - run: echo README file exists! - - - name: README file does not exist - if: steps.readme_file.outputs.file_exists == 'false' - run: echo README file does not exist! - - check-for-license: - needs: public-or-private-repo - if: needs.public-or-private-repo.outputs.repostate == 'public' + check-for-file: runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + filename: + - .github/CODEOWNERS + - README.@(md|rst) + - LICENSE.@(md|rst) + - .github/workflows/codeql.yml steps: - - - name: Checkout repo - uses: actions/checkout@v3 - - - name: Check for LICENSE.md - id: license_file - uses: initialstate/file-check-action@v1 + - uses: actions/checkout@v4 + - name: Ensure ${{ matrix.filename }} exists + uses: andstor/file-existence-action@v3 with: - file: "LICENSE" - - - name: LICENSE file Output Test - run: echo ${{ steps.license_file.outputs.file_exists }} - - - name: LICENSE file exists with content - if: steps.license_file.outputs.file_exists == 'true' - run: echo LICENSE file exists! - - - name: LICENSE file does not exist - if: steps.license_file.outputs.file_exists == 'false' - run: echo LICENSE file does not exist! - - check-for-dependabot-file: + files: ${{ matrix.filename }} + ignore_case: false + follow_symbolic_links: false + fail: true # Set the step to fail if the file doesn't exist + # Check that all jobs passed + check-repo-lint-passed: + if: ${{ !cancelled() }} + needs: [check-for-file] runs-on: ubuntu-latest steps: - - - name: Checkout repo - uses: actions/checkout@v3 - - - name: Check for dependabot.yml - id: dependabot_file - uses: initialstate/file-check-action@v1 + - name: Decide whether the needed jobs succeeded or failed + uses: re-actors/alls-green@release/v1 with: - file: ".github/dependabot.yml" - - - name: dependabot.yml file Output Test - run: echo ${{ steps.dependabot_file.outputs.file_exists }} - - - name: dependabot file exists with content - if: steps.dependabot_file.outputs.file_exists == 'true' - run: echo dependabot file exists! - - - name: dependabot file does not exist - if: steps.dependabot_file.outputs.file_exists == 'false' - run: echo dependabot file does not exist! - - check-for-codeql-file: - runs-on: ubuntu-latest - steps: - - - name: Checkout repo - uses: actions/checkout@v3 - - - name: Check for codeql-analysis.yml - id: codeql-analysis_file - uses: initialstate/file-check-action@v1 - with: - file: ".github/workflows/codeql-analysis.yml" - - - name: codeql-analysis.yml file Output Test - run: echo ${{ steps.codeql-analysis_file.outputs.file_exists }} - - - name: codeql-analysis file exists with content - if: steps.codeql-analysis_file.outputs.file_exists == 'true' - run: echo codeql-analysis file exists! - - - name: codeql-analysis file does not exist - if: steps.codeql-analysis_file.outputs.file_exists == 'false' - run: echo codeql-analysis file does not exist! + jobs: ${{ toJSON(needs) }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..904c6cd --- /dev/null +++ b/.gitignore @@ -0,0 +1,13 @@ +# Ignore IDE config folders +.idea/ +.vscode/ + +# Ignore caches and binaries +.ruff_cache/ +__pycache__/ +*.py[cod] +.tox/ + +# Ignore virtual environments +*env*/ +*venv*/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..0152410 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,46 @@ +--- +default_install_hook_types: [pre-commit] +default_stages: [pre-commit] +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.6.0 + hooks: + - id: check-yaml + args: [--unsafe] + - id: check-toml + - id: check-json + - id: check-xml + - id: requirements-txt-fixer +# - id: trailing-whitespace # TODO: enable +# - id: end-of-file-fixer # TODO: enable + - id: check-case-conflict + - id: check-merge-conflict + - id: forbid-submodules +# TODO: enable these hooks +# - repo: https://github.com/Lucas-C/pre-commit-hooks +# rev: v1.5.5 +# hooks: +# - id: remove-tabs +# - id: forbid-tabs + - repo: https://github.com/python-jsonschema/check-jsonschema + rev: 0.29.0 + hooks: + - id: check-github-workflows + args: [--verbose] + - repo: https://github.com/pappasam/toml-sort + rev: v0.23.1 + hooks: + - id: toml-sort-fix + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.5.4 + hooks: + - id: ruff +# args: [--fix, --exit-non-zero-on-fix] + - id: ruff-format + args: [--check, --diff] + - repo: https://github.com/PyCQA/docformatter + rev: v1.7.5 + hooks: + - id: docformatter + additional_dependencies: [tomli] + args: [--check, --diff] diff --git a/LICENSE.md b/LICENSE.md index daa3d66..f1ec83b 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -9,4 +9,3 @@ TEKTRONIX SAMPLE SOURCE CODE LICENSE AGREEMENT Source code written by Tektronix, Inc. or its affiliates ("Tektronix") that is designated as a "sample," "example," "sample code," or any similar designation will be considered "Sample Source Code." Tektronix grants you a license to download, reproduce, display, distribute, modify, and create derivative works of Tektronix Sample Source Code, only for use in or with Tektronix products. You may not remove or alter any copyright notices or trademarks. SAMPLE SOURCE CODE IS PROVIDED "AS-IS," WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES OF ANY KIND, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT OF INTELLECTUAL PROPERTY. IN NO EVENT SHALL TEKTRONIX, ITS AFFILIATES, OFFICERS, EMPLOYEES, DIRECTORS, AGENTS, SUPPLIERS, OR OTHER THIRD PARTIES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, PUNITIVE, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THIS SAMPLE SOURCE CODE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - diff --git a/README.md b/README.md index e633bb6..7977fd7 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Tek Logo -# Programmatic Control Examples +# Programmatic Control Examples [![CodeFactor](https://www.codefactor.io/repository/github/tektronix/programmatic-control-examples/badge)](https://www.codefactor.io/repository/github/tektronix/programmatic-control-examples) > Code examples sorted by instrument, including examples taken from the User's Manuals. This is a good place to start off learning about programming for an instrument. @@ -52,7 +52,7 @@ You may also recognize some of these examples from the [Tektronix and Keithley W If you don't want to clone this entire repository, it's still possible to take individual files. Navigate to the directory holding the file you want and right-click the file to select _Save link as..._ or some variation on that depending on your browser. The file name will automatically populate and you can save the file where you'd like. Alternatively, you can open the file you want on GitHub and right-click "Raw" at the top of the file to accomplish the same thing. ## Maintainers -Tektronix Product Line Marketing and Application Engineers: +Tektronix Product Line Marketing and Application Engineers: + Jeffrey Miller: [bit-lift](https://github.com/bit-lift) + Carl Murdock: [cbmurdock](https://github.com/cbmurdock) @@ -61,7 +61,7 @@ Tektronix Product Line Marketing and Application Engineers: Licensed under the [Tektronix Sample License](https://www.tek.com/sample-license). ## Contributing -First, please consult the Tektronix [Code of Conduct](https://github.com/tektronix/.github/blob/main/CODE_OF_CONDUCT.md). Contributions in the form of new examples or bug fixes are welcome! Please contribute using [Github Flow](https://guides.github.com/introduction/flow/) and make sure you create your own branch from the `master` branch, and when you are ready to push your changes, just submit a pull request with your changes against the `master` branch. If you see something you're not sure is a bug, or if you'd like to request an example, please submit an Issue via GitHub. +First, please consult the Tektronix [Code of Conduct](https://github.com/tektronix/.github/blob/main/CODE_OF_CONDUCT.md). Contributions in the form of new examples or bug fixes are welcome! Please contribute using [Github Flow](https://guides.github.com/introduction/flow/) and make sure you create your own branch from the `master` branch, and when you are ready to push your changes, just submit a pull request with your changes against the `master` branch. If you see something you're not sure is a bug, or if you'd like to request an example, please submit an Issue via GitHub. If you'd like help from a Tektronix engineer in developing an example, please submit a pull request with what you have so far placed in the proper part of the repository, including any new directories your example may need. diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..e471d6c --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,54 @@ +[tool.docformatter] +close-quotes-on-newline = true +in-place = true +recursive = true +wrap-descriptions = 100 +wrap-summaries = 0 + +[tool.ruff] +line-length = 100 +target-version = "py38" # always generate Python 3.8 compatible code + +[tool.ruff.lint] +fixable = ["ALL"] +flake8-quotes = {docstring-quotes = "double"} +ignore = [ + "T201" # `print` found +] +pydocstyle = {convention = "google"} +# https://beta.ruff.rs/docs/rules/ +select = [ + # "ALL" # TODO: enable ALL + "E", + "F", + "I", + "N", + "PLE", + "Q", + "RUF" +] + +[tool.ruff.lint.isort] +force-sort-within-sections = false +lines-between-types = 1 +order-by-type = false + +[tool.tomlsort] +all = true +in_place = true +spaces_before_inline_comment = 2 + +[tool.tox] +legacy_tox_ini = """ +[tox] +requires = tox>4 +no_package = True +envlist = linting +skip_missing_interpreters = True + +[testenv:linting] +deps = + pre-commit +commands = + pre-commit run --all-files +"""