diff --git a/.github/actionlint.yaml b/.github/actionlint.yaml index a38f874bd..cb72013d0 100644 --- a/.github/actionlint.yaml +++ b/.github/actionlint.yaml @@ -3,6 +3,7 @@ self-hosted-runner: labels: - ubuntu-x64 - macOS + - ubuntu-latest # Configuration variables in array of strings defined in your repository or # organization. `null` means disabling configuration variables check. # Empty array means no configuration variable is allowed. diff --git a/.github/actions/linter_tests/action.yaml b/.github/actions/linter_tests/action.yaml index 0bc5897ff..6ce930423 100644 --- a/.github/actions/linter_tests/action.yaml +++ b/.github/actions/linter_tests/action.yaml @@ -36,19 +36,30 @@ runs: with: node-version: 18 + # NOTE: tzdata is a dependency of php, but without the DEBIAN_FRONTEND=noninteractive + # it will prompt for a timezone selection - name: Install packages and specify defaults run: | echo "CLI_PATH=${{ inputs.cli-path }}" >> "$GITHUB_ENV" case "$RUNNER_OS" in Linux) + # Cleanup any existing apt locks + sudo killall apt-get || true + sudo rm /var/lib/apt/lists/lock || true + + # Install non-hermetic linters sudo apt-get update - sudo apt-get -y install libperl-critic-perl perltidy zlib1g-dev + sudo apt-get -y install libperl-critic-perl perltidy zlib1g-dev software-properties-common + DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC sudo apt-get -y install tzdata + sudo add-apt-repository ppa:ondrej/php + sudo apt install -y php8.0-fpm php8.0-xml php8.0-mbstring php8.0-curl ;; macOS) brew install cpm cpm install -g --no-test --color Perl::Critic Perl::Tidy brew unlink perl && brew link perl + brew install php gnupg ;; Windows) echo "PLATFORM_APPEND_ARGS=--maxWorkers=5" >> "$GITHUB_ENV" @@ -64,6 +75,11 @@ runs: shell: bash working-directory: ${{ inputs.path }} + - name: Clean jest cache + run: npx jest --clearCache + shell: bash + working-directory: ${{ inputs.path }} + - name: Run plugin tests if: runner.os == 'Windows' run: npm test ${{ inputs.append-args }} ${{ env.PLATFORM_APPEND_ARGS }} --ci @@ -87,7 +103,7 @@ runs: working-directory: ${{ inputs.path }} trunk-token: ${{ inputs.trunk-token }} org: trunk-staging-org - run: npm test ${{ inputs.append-args }} ${{ env.PLATFORM_APPEND_ARGS }} --ci + run: npm test ${{ inputs.append-args }} ${{ env.PLATFORM_APPEND_ARGS }} --ci --runInBand env: PLUGINS_TEST_LINTER_VERSION: ${{ inputs.linter-version }} PLUGINS_TEST_CLI_VERSION: ${{ inputs.cli-version }} diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml index d6b401a61..71d8bd7c0 100644 --- a/.github/dependabot.yaml +++ b/.github/dependabot.yaml @@ -7,7 +7,6 @@ updates: day: sunday # trunk-ignore(yamllint/quoted-strings) time: "08:00" # UTC - labels: [🤖 dependabot] groups: dependencies: patterns: @@ -21,9 +20,11 @@ updates: day: sunday # trunk-ignore(yamllint/quoted-strings) time: "08:00" # UTC - labels: [🤖 dependabot] groups: dependencies: patterns: - "*" + # TODO(Tyler): Readd once eslint9 is resolved. + ignore: + - dependency-name: eslint open-pull-requests-limit: 2 diff --git a/.github/workflows/annotate_pr.yaml b/.github/workflows/annotate_pr.yaml index ec05aa67c..ccd507cf4 100644 --- a/.github/workflows/annotate_pr.yaml +++ b/.github/workflows/annotate_pr.yaml @@ -18,7 +18,7 @@ jobs: uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Trunk Check - uses: trunk-io/trunk-action@65228585e2c6128315f0f2d5190e2eae7f5c32c6 # v1.1.10 + uses: trunk-io/trunk-action@da67635060feab46c164bc130690e61864a5d13b # v1.1.13 with: post-annotations: true # This job may fail when the PR was not run on a fork, and that's okay diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 5eb4a60d7..ed448edfb 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -34,7 +34,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@3ab4101902695724f9365a384f86c1074d94e18c # v3.24.7 + uses: github/codeql-action/init@c7f9125735019aa87cfc361530512d50ea439c71 # v3.25.1 # Override language selection by uncommenting this and choosing your languages with: languages: javascript @@ -42,7 +42,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java). # If this step fails, then you should remove it and run the build manually (see below). - name: Autobuild - uses: github/codeql-action/autobuild@3ab4101902695724f9365a384f86c1074d94e18c # v3.24.7 + uses: github/codeql-action/autobuild@c7f9125735019aa87cfc361530512d50ea439c71 # v3.25.1 # â„šī¸ Command-line programs to run using the OS shell. # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun @@ -56,4 +56,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@3ab4101902695724f9365a384f86c1074d94e18c # v3.24.7 + uses: github/codeql-action/analyze@c7f9125735019aa87cfc361530512d50ea439c71 # v3.25.1 diff --git a/.github/workflows/nightly.yaml b/.github/workflows/nightly.yaml index 3fc46c6f0..f41a3dc78 100644 --- a/.github/workflows/nightly.yaml +++ b/.github/workflows/nightly.yaml @@ -35,7 +35,7 @@ jobs: fail-fast: false matrix: linter-version: [Snapshots, Latest] - os: [ubuntu-x64, macOS, windows-latest] + os: [ubuntu-latest, macOS, windows-latest] steps: - name: Checkout uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 @@ -43,7 +43,7 @@ jobs: - name: Cache tool downloads # ubuntu runner has persistent cache if: matrix.os == 'windows-latest' - uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 # v4.0.1 + uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 with: path: /tmp/plugins_testing_download_cache # No need to key on trunk version unless we change how we store downloads. @@ -80,10 +80,10 @@ jobs: fail-fast: false matrix: linter-version: [Snapshots, Latest] - os: [ubuntu-x64, macOS, windows-latest] + os: [ubuntu-latest, macOS, windows-latest] include: # Normalize the filenames as inputs for ease of parsing - - os: ubuntu-x64 + - os: ubuntu-latest results-file: ubuntu-latest - os: macOS results-file: macos-latest @@ -127,11 +127,6 @@ jobs: with: ref: ${{ steps.get-release.outputs.tag }} clean: false - sparse_checkout: | - plugin.yaml - linters - actions - tools - name: Overwrite test runners with latest behavior shell: bash @@ -154,7 +149,7 @@ jobs: - name: Cache tool downloads # ubuntu, mac runners have persistent cache if: matrix.os == 'windows-latest' - uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 # v4.0.1 + uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 with: path: /tmp/plugins_testing_download_cache # No need to key on trunk version unless we change how we store downloads. @@ -162,12 +157,11 @@ jobs: - name: Delete cache # For now, avoid deleting cache on pull request changes to nightly. This improves PR experience. - if: env.TRIGGER != 'pull_request' run: | - if [ -d "/tmp/plugins_testing_download_cache" ] + if [ -d "${TMPDIR:-/tmp}/plugins_testing_download_cache" ] then - tmp_dir=/tmp/${GITHUB_RUN_ID}-${GITHUB_RUN_NUMBER}-${GITHUB_RUN_ATTEMPT} - mv "/tmp/plugins_testing_download_cache" ${tmp_dir} + tmp_dir=${TMPDIR:-/tmp}/${GITHUB_RUN_ID}-${GITHUB_RUN_NUMBER}-${GITHUB_RUN_ATTEMPT} + mv "${TMPDIR:-/tmp}/plugins_testing_download_cache" ${tmp_dir} chmod -R u+w ${tmp_dir} rm -rf ${tmp_dir} fi @@ -185,7 +179,7 @@ jobs: - name: Upload Test Outputs for Upload Job # Only upload results from latest. Always run, except when cancelled. if: (failure() || success()) && matrix.linter-version == 'Latest' - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 + uses: actions/upload-artifact@1746f4ab65b179e0ea60a494b83293b640dd5bba # v4.3.2 with: name: ${{ matrix.results-file }}-test-results path: ${{ matrix.results-file }}-res.json @@ -220,10 +214,10 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-x64, macOS, windows-latest] + os: [ubuntu-latest, macOS, windows-latest] include: # Normalize the filenames as inputs for ease of parsing - - os: ubuntu-x64 + - os: ubuntu-latest results-file: ubuntu-latest - os: macOS results-file: macos-latest @@ -244,7 +238,7 @@ jobs: - name: Upload Test Outputs for Notification Job # Always run, except when cancelled. if: (failure() || success()) - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 + uses: actions/upload-artifact@1746f4ab65b179e0ea60a494b83293b640dd5bba # v4.3.2 with: name: tools-${{ matrix.results-file }}-test-results path: ${{ matrix.results-file }}-res.json @@ -273,7 +267,7 @@ jobs: action_tests_main: name: Action Tests Main - runs-on: [self-hosted, Linux] + runs-on: [ubuntu-latest] timeout-minutes: 30 steps: - name: Checkout diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index 4e4241a72..d1a661a45 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -117,7 +117,7 @@ jobs: # Run tests against all linters for known_good_version and latest version linter_tests: name: Linter Tests ${{ matrix.os }} - runs-on: [self-hosted, "${{ matrix.os }}"] + runs-on: ${{ matrix.os }} needs: detect_changes if: needs.detect_changes.outputs.linters == 'true' || needs.detect_changes.outputs.all-linters == @@ -126,11 +126,25 @@ jobs: strategy: fail-fast: false matrix: - os: [Linux, macOS] + os: [ubuntu-latest, macOS] steps: - name: Checkout uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + # TODO(Tyler): Remove this once the cache has stabilized + - name: Delete cache (mac only) + if: matrix.os == 'macOS' + # For now, avoid deleting cache on pull request changes to nightly. This improves PR experience. + run: | + if [ -d "${TMPDIR:-/tmp}/plugins_testing_download_cache" ] + then + tmp_dir=${TMPDIR:-/tmp}/${GITHUB_RUN_ID}-${GITHUB_RUN_NUMBER}-${GITHUB_RUN_ATTEMPT} + mv "${TMPDIR:-/tmp}/plugins_testing_download_cache" ${tmp_dir} + chmod -R u+w ${tmp_dir} + rm -rf ${tmp_dir} + fi + shell: bash + - name: Linter Tests # Run tests using KnownGoodVersion with any modified linters and conditionally all linters uses: ./.github/actions/linter_tests @@ -156,7 +170,7 @@ jobs: tool_tests: name: Tool Tests - runs-on: [self-hosted, "${{ matrix.os }}"] + runs-on: ${{ matrix.os }} needs: detect_changes if: needs.detect_changes.outputs.tools == 'true' || needs.detect_changes.outputs.all-tools == @@ -165,7 +179,7 @@ jobs: strategy: fail-fast: false matrix: - os: [Linux, macOS] + os: [ubuntu-latest, macOS] steps: - name: Checkout uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 @@ -182,7 +196,7 @@ jobs: action_tests: name: Action Tests - runs-on: [self-hosted, Linux] + runs-on: ubuntu-latest needs: detect_changes if: needs.detect_changes.outputs.actions == 'true' || needs.detect_changes.outputs.all-actions == @@ -214,7 +228,7 @@ jobs: lfs: true - name: Trunk Check - uses: trunk-io/trunk-action@65228585e2c6128315f0f2d5190e2eae7f5c32c6 + uses: trunk-io/trunk-action@da67635060feab46c164bc130690e61864a5d13b env: TRUNK_GITHUB_CHECK_RUN_TITLE: Trunk Check @@ -231,7 +245,7 @@ jobs: uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Cache tool downloads - uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 # v4.0.1 + uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 with: path: /tmp/plugins_testing_download_cache key: trunk-${{ runner.os }} @@ -257,7 +271,7 @@ jobs: uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Cache tool downloads - uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 # v4.0.1 + uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 with: path: /tmp/plugins_testing_download_cache key: trunk-${{ runner.os }} diff --git a/.github/workflows/repo_tests.reusable.yaml b/.github/workflows/repo_tests.reusable.yaml index b930aa75c..1b0814136 100644 --- a/.github/workflows/repo_tests.reusable.yaml +++ b/.github/workflows/repo_tests.reusable.yaml @@ -13,12 +13,14 @@ on: required: false type: string -permissions: read-all +permissions: + contents: read + statuses: read jobs: plugins_test: name: Plugin Tests - runs-on: ubuntu-x64 + runs-on: ubuntu-latest timeout-minutes: 15 steps: diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 8ef7c18be..9000fe624 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -57,7 +57,7 @@ jobs: # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF # format to the repository Actions tab. - name: Upload artifact - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 + uses: actions/upload-artifact@1746f4ab65b179e0ea60a494b83293b640dd5bba # v4.3.2 with: name: SARIF file path: results.sarif @@ -65,6 +65,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: Upload to code-scanning - uses: github/codeql-action/upload-sarif@3ab4101902695724f9365a384f86c1074d94e18c # v3.24.7 + uses: github/codeql-action/upload-sarif@c7f9125735019aa87cfc361530512d50ea439c71 # v3.25.1 with: sarif_file: results.sarif diff --git a/.github/workflows/upgrade_trunk.yaml b/.github/workflows/upgrade_trunk.yaml index ba325590e..07cb87ff4 100644 --- a/.github/workflows/upgrade_trunk.yaml +++ b/.github/workflows/upgrade_trunk.yaml @@ -26,7 +26,7 @@ jobs: private_key: ${{ secrets.TRUNK_OPEN_PR_APP_PRIVATE_KEY }} - name: Trunk Upgrade - uses: trunk-io/trunk-action/upgrade@65228585e2c6128315f0f2d5190e2eae7f5c32c6 + uses: trunk-io/trunk-action/upgrade@da67635060feab46c164bc130690e61864a5d13b with: arguments: -n --bleeding-edge github-token: ${{ steps.generate-token.outputs.token }} diff --git a/.github/workflows/upload_results.reusable.yaml b/.github/workflows/upload_results.reusable.yaml index 6fe46d6d1..bd50432f3 100644 --- a/.github/workflows/upload_results.reusable.yaml +++ b/.github/workflows/upload_results.reusable.yaml @@ -39,12 +39,16 @@ on: TRUNK_DEBUGGER_TOKEN: required: false -permissions: read-all +permissions: + actions: write + contents: read + statuses: read + pull-requests: write jobs: upload_test_results: name: Upload Test Results - runs-on: ubuntu-x64 + runs-on: ubuntu-latest timeout-minutes: 10 env: SLACK_CHANNEL_ID: plugins-notifications @@ -56,21 +60,21 @@ jobs: - name: Retrieve Test Outputs ubuntu id: download-ubuntu - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 + uses: actions/download-artifact@8caf195ad4b1dee92908e23f56eeb0696f1dd42d # v4.1.5 continue-on-error: true with: name: ${{ inputs.results-prefix }}ubuntu-latest-test-results - name: Retrieve Test Outputs macOS id: download-macos - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 + uses: actions/download-artifact@8caf195ad4b1dee92908e23f56eeb0696f1dd42d # v4.1.5 continue-on-error: true with: name: ${{ inputs.results-prefix }}macos-latest-test-results - name: Retrieve Test Outputs Windows id: download-windows - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 + uses: actions/download-artifact@8caf195ad4b1dee92908e23f56eeb0696f1dd42d # v4.1.5 continue-on-error: true with: name: ${{ inputs.results-prefix }}windows-latest-test-results @@ -92,7 +96,7 @@ jobs: echo "::endgroup::" - name: Slack Notification For Missing Artifacts - uses: slackapi/slack-github-action@6c661ce58804a1a20f6dc5fbee7f0381b469e001 # v1.25.0 + uses: slackapi/slack-github-action@70cd7be8e40a46e8b0eced40b0de447bdb42f68e # v1.26.0 if: steps.download-ubuntu.outcome == 'failure' || steps.download-macos.outcome == 'failure' || steps.download-windows.outcome == 'failure' @@ -175,7 +179,7 @@ jobs: # Slack notifications - name: Slack Notification For Failures - uses: slackapi/slack-github-action@6c661ce58804a1a20f6dc5fbee7f0381b469e001 # v1.25.0 + uses: slackapi/slack-github-action@70cd7be8e40a46e8b0eced40b0de447bdb42f68e # v1.26.0 if: always() && steps.parse.outputs.failures == 'true' with: channel-id: ${{ env.SLACK_CHANNEL_ID }} @@ -184,7 +188,7 @@ jobs: SLACK_BOT_TOKEN: ${{ secrets.TRUNKBOT_SLACK_BOT_TOKEN }} - name: Slack Notification For Staging Upload Failure - uses: slackapi/slack-github-action@6c661ce58804a1a20f6dc5fbee7f0381b469e001 # v1.25.0 + uses: slackapi/slack-github-action@70cd7be8e40a46e8b0eced40b0de447bdb42f68e # v1.26.0 if: inputs.upload-validated-versions == true && steps.upload-staging.outcome == 'failure' with: channel-id: ${{ env.SLACK_CHANNEL_ID }} @@ -205,7 +209,7 @@ jobs: SLACK_BOT_TOKEN: ${{ secrets.TRUNKBOT_SLACK_BOT_TOKEN }} - name: Slack Notification For Prod Upload Failure - uses: slackapi/slack-github-action@6c661ce58804a1a20f6dc5fbee7f0381b469e001 # v1.25.0 + uses: slackapi/slack-github-action@70cd7be8e40a46e8b0eced40b0de447bdb42f68e # v1.26.0 if: inputs.upload-validated-versions == true && steps.upload-prod.outcome == 'failure' with: channel-id: ${{ env.SLACK_CHANNEL_ID }} @@ -226,7 +230,7 @@ jobs: SLACK_BOT_TOKEN: ${{ secrets.TRUNKBOT_SLACK_BOT_TOKEN }} generate_snapshots_pr: name: Generate Snapshots PR - runs-on: ubuntu-x64 + runs-on: ubuntu-latest timeout-minutes: 30 needs: upload_test_results if: needs.upload_test_results.outputs.reruns != '' diff --git a/.github/workflows/windows_nightly.yaml b/.github/workflows/windows_nightly.yaml index 6af54a00c..9c0fa7a7b 100644 --- a/.github/workflows/windows_nightly.yaml +++ b/.github/workflows/windows_nightly.yaml @@ -21,7 +21,7 @@ jobs: uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Cache tool downloads - uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 # v4.0.1 + uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 with: path: /tmp/plugins_testing_download_cache # No need to key on trunk version unless we change how we store downloads. @@ -60,7 +60,7 @@ jobs: uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Cache tool downloads - uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 # v4.0.1 + uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 with: path: /tmp/plugins_testing_download_cache # No need to key on trunk version unless we change how we store downloads. diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index eb1b61faf..2560edf1d 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -2,7 +2,7 @@ version: 0.1 # version used for local trunk runs and testing cli: - version: 1.20.2-beta.4 + version: 1.21.1-beta.43 shell_hooks: enforce: true @@ -17,7 +17,7 @@ plugins: - id: configs uri: https://github.com/trunk-io/configs - ref: v1.0.2 + ref: v1.0.4 lint: # enabled linters inherited from github.com/trunk-io/configs plugin @@ -79,8 +79,8 @@ actions: - tool-test-helper tools: enabled: - - clangd-indexing-tools@17.0.3 - - clangd@17.0.3 + - clangd-indexing-tools@18.1.3 + - clangd@18.1.3 runtimes: # expose shims in .trunk/tools - node diff --git a/README.md b/README.md index 25535fcfa..47e20065f 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,7 @@ trunk check enable {linter} | Nix | [nixpkgs-fmt] | | package.json | [sort-package-json] | | Perl | [perlcritic], [perltidy] | +| PHP | [phpstan] | | PNG | [oxipng] | | PowerShell | [psscriptanalyzer] | | Prisma | [prisma] | @@ -80,24 +81,24 @@ trunk check enable {linter} | SQL | [sqlfluff], [sqlfmt], [sql-formatter] | | SVG | [svgo] | | Swift | [stringslint], [swiftlint], [swiftformat] | -| Terraform | [terraform] (validate and fmt), [checkov], [tflint],[tfsec],[terrascan] | +| Terraform | [terraform] (validate and fmt), [checkov], [tflint], [tfsec], [terrascan], [tofu] | | Terragrunt | [terragrunt] | | Textproto | [txtpbfmt] | | TOML | [taplo] | | Typescript | [deno], [eslint], [prettier], [rome], [semgrep] | | YAML | [prettier], [semgrep], [yamllint] | -[actionlint]: https://github.com/rhysd/actionlint#readme +[actionlint]: https://trunk.io/linters/infra/actionlint [ansible-lint]: https://github.com/ansible/ansible-lint#readme [autopep8]: https://github.com/hhatto/autopep8#readme -[bandit]: https://github.com/PyCQA/bandit#readme +[bandit]: https://trunk.io/linters/python/bandit [biome]: https://github.com/biomejs/biome#readme [black]: https://github.com/psf/black#readme -[brakeman]: https://github.com/presidentbeef/brakeman#readme +[brakeman]: https://trunk.io/linters/security/brakeman [buf]: https://github.com/bufbuild/buf#readme [buildifier]: https://github.com/bazelbuild/buildtools/blob/master/buildifier/README.md [cfnlint]: https://github.com/aws-cloudformation/cfn-lint#readme -[checkov]: https://github.com/bridgecrewio/checkov#readme +[checkov]: https://trunk.io/linters/security/checkov [circleci]: https://github.com/CircleCI-Public/circleci-cli#readme [clang-format]: https://clang.llvm.org/docs/ClangFormat.html [clang-tidy]: https://clang.llvm.org/extra/clang-tidy/ @@ -114,9 +115,9 @@ trunk check enable {linter} [dotnet-format]: https://github.com/dotnet/format#readme [dustilock]: https://github.com/Checkmarx/dustilock [eslint]: https://github.com/eslint/eslint#readme -[flake8]: https://github.com/PyCQA/flake8#readme +[flake8]: https://trunk.io/linters/python/flake8 [git-diff-check]: https://git-scm.com/docs/git-diff -[gitleaks]: https://github.com/zricethezav/gitleaks#readme +[gitleaks]: https://trunk.io/linters/security/gitleaks [gofmt]: https://pkg.go.dev/cmd/gofmt [gofumpt]: https://pkg.go.dev/mvdan.cc/gofumpt [goimports]: https://pkg.go.dev/golang.org/x/tools/cmd/goimports @@ -138,10 +139,11 @@ trunk check enable {linter} [nancy]: https://github.com/sonatype-nexus-community/nancy#readme [nixpkgs-fmt]: https://github.com/nix-community/nixpkgs-fmt [opa]: https://www.openpolicyagent.org/docs/latest/cli/ -[osv-scanner]: https://github.com/google/osv-scanner +[osv-scanner]: https://trunk.io/linters/security/osv-scanner [oxipng]: https://github.com/shssoichiro/oxipng#readme [perlcritic]: https://metacpan.org/pod/Perl::Critic [perltidy]: https://metacpan.org/dist/Perl-Tidy/view/bin/perltidy +[phpstan]: https://phpstan.org/ [pmd]: https://pmd.github.io/ [pragma-once]: linters/pragma-once/README.md [prettier]: https://github.com/prettier/prettier#readme @@ -155,12 +157,12 @@ trunk check enable {linter} [renovate]: https://github.com/renovatebot/renovate#readme [rome]: https://github.com/rome/tools#readme [rubocop]: https://github.com/rubocop/rubocop#readme -[ruff]: https://github.com/charliermarsh/ruff +[ruff]: https://trunk.io/linters/python/ruff [rufo]: https://github.com/ruby-formatter/rufo#readme [rustfmt]: https://github.com/rust-lang/rustfmt#readme [scalafmt]: https://github.com/scalameta/scalafmt#readme [semgrep]: https://github.com/returntocorp/semgrep#readme -[shellcheck]: https://github.com/koalaman/shellcheck#readme +[shellcheck]: https://trunk.io/linters/shell/shellcheck [shfmt]: https://github.com/mvdan/sh#readme [sort-package-json]: https://github.com/keithamus/sort-package-json#readme [sql-formatter]: https://github.com/sql-formatter-org/sql-formatter#readme @@ -171,20 +173,21 @@ trunk check enable {linter} [stylelint]: https://github.com/stylelint/stylelint#readme [stylua]: https://github.com/JohnnyMorganz/StyLua/tree/main [sourcery]: https://sourcery.ai/ -[svgo]: https://github.com/svg/svgo#readme +[svgo]: https://trunk.io/linters/nodejs/svgo [swiftformat]: https://github.com/nicklockwood/SwiftFormat#readme [swiftlint]: https://github.com/realm/SwiftLint#readme [taplo]: https://github.com/tamasfe/taplo#readme [terrascan]: https://github.com/tenable/terrascan#readme [terraform]: https://developer.hashicorp.com/terraform/cli/code +[tofu]: https://opentofu.org/ [terragrunt]: https://terragrunt.gruntwork.io/docs/getting-started/quick-start/ [tflint]: https://github.com/terraform-linters/tflint#readme [tfsec]: https://github.com/aquasecurity/tfsec -[trivy]: https://github.com/aquasecurity/trivy#readme -[trufflehog]: https://github.com/trufflesecurity/trufflehog#readme +[trivy]: https://trunk.io/linters/security/trivy +[trufflehog]: https://trunk.io/linters/security/trufflehog [trunk-toolbox]: https://github.com/trunk-io/toolbox#readme [txtpbfmt]: https://github.com/protocolbuffers/txtpbfmt#readme -[yamllint]: https://github.com/adrienverge/yamllint#readme +[yamllint]: https://trunk.io/linters/yaml/yamllint [yapf]: https://github.com/google/yapf#readme
@@ -201,16 +204,17 @@ Enable trunk actions via: trunk actions enable {action} ``` -| action | description | -| -------------------------------------------------------------------- | ---------------------------------------------------------- | -| [`buf-gen`](actions/buf/README.md) | run `buf` on .proto file change | -| [`commitizen`](actions/commitizen/README.md) | enforce conventional commits and manage releases | -| [`commitlint`](https://github.com/conventional-changelog/commitlint) | enforce conventional commit message for your local commits | -| [`go-mod-tidy`](actions/go-mod-tidy/README.md) | automatically tidy go.mod file | -| [`go-mod-tidy-vendor`](actions/go-mod-tidy-vendor/README.md) | automatically tidy and vendor go.mod file | -| [`git-blame-ignore-revs`](actions/git-blame-ignore-revs/README.md) | automatically configure git to use .git-blame-ignore-revs | -| [`npm-check`](actions/npm-check/README.md) | check whether NPM installation is up to date | -| [`yarn-check`](actions/yarn-check/README.md) | check whether Yarn installation is up to date | +| action | description | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------- | +| [`buf-gen`](actions/buf/README.md) | run `buf` on .proto file change | +| [`commitizen`](actions/commitizen/README.md) | enforce conventional commits and manage releases | +| [`commitlint`](https://github.com/conventional-changelog/commitlint) | enforce conventional commit message for your local commits | +| [`go-mod-tidy`](actions/go-mod-tidy/README.md) | automatically tidy go.mod file | +| [`go-mod-tidy-vendor`](actions/go-mod-tidy-vendor/README.md) | automatically tidy and vendor go.mod file | +| [`git-blame-ignore-revs`](actions/git-blame-ignore-revs/README.md) | automatically configure git to use .git-blame-ignore-revs | +| [`npm-check`](actions/npm-check/README.md) | check whether NPM installation is up to date | +| [`poetry-check`](actions/poetry/README.md), [`poetry-lock`](actions/poetry/README.md), [`poetry-export`](actions/poetry/README.md), [`poetry-install`](actions/poetry/README.md) | hooks to enforce poetry configuration | +| [`yarn-check`](actions/yarn-check/README.md) | check whether Yarn installation is up to date | ### Supported Tools diff --git a/actions/commitlint/README.md b/actions/commitlint/README.md index 1d2111e51..b4f8e2ad4 100644 --- a/actions/commitlint/README.md +++ b/actions/commitlint/README.md @@ -4,7 +4,7 @@ https://github.com/conventional-changelog/commitlint ## Simple configuration -1. `echo "module.exports = {extends: ['@commitlint/config-conventional']}" > commitlint.config.js` +1. `echo "export default {extends: ['@commitlint/config-conventional']}" > commitlint.config.mjs` 2. `trunk actions enable commitlint` This will install the basic config and run commitlint on every `commit-msg` hook. @@ -14,7 +14,7 @@ This will install the basic config and run commitlint on every `commit-msg` hook In order to use different commitlint configuration or specify a specific commitlint version, you must: -1. Modify your `commitlint.config.js` accordingly +1. Modify your `commitlint.config.mjs` accordingly 2. Override the `packages_file` field for the action and specify a package.json For example: @@ -30,10 +30,10 @@ actions: packages_file: ${workspace}/.trunk/commitlint/package.json ``` -`commitlint.config.js`: +`commitlint.config.mjs`: ```js -module.exports = { +export default { extends: ["@commitlint/config-angular", "@commitlint/config-conventional"], }; ``` diff --git a/actions/commitlint/commitlint.test.ts b/actions/commitlint/commitlint.test.ts index fe8402105..f9dd17fb1 100644 --- a/actions/commitlint/commitlint.test.ts +++ b/actions/commitlint/commitlint.test.ts @@ -4,8 +4,8 @@ import { TrunkActionDriver } from "tests/driver"; const preCheck = (driver: TrunkActionDriver) => { driver.writeFile( - "commitlint.config.js", - "module.exports = {extends: ['@commitlint/config-conventional']}", + "commitlint.config.mjs", + "export default {extends: ['@commitlint/config-conventional']}", ); }; diff --git a/actions/commitlint/package.json b/actions/commitlint/package.json index dedb725d5..972a41131 100644 --- a/actions/commitlint/package.json +++ b/actions/commitlint/package.json @@ -1,6 +1,6 @@ { "dependencies": { - "@commitlint/cli": "^17.0", - "@commitlint/config-conventional": "^17.0" + "@commitlint/cli": "^19.0", + "@commitlint/config-conventional": "^19.0" } } diff --git a/actions/poetry/README.md b/actions/poetry/README.md new file mode 100644 index 000000000..29cd8168a --- /dev/null +++ b/actions/poetry/README.md @@ -0,0 +1,52 @@ +# Poetry + +## Recommended Usage + +The recommended way to run [Poetry](https://python-poetry.org/docs/) using Trunk is to use the +SYSTEM environment, rather than a hermetic setup. This is because Poetry provides its own +environment management that will often collide with Trunk's hermetic setup. Nevertheless, leveraging +Poetry and Trunk in parallel can be powerful. + +Trunk provides 4 different Actions for running Poetry validation, matching parity with +[Poetry pre-commit hooks](https://python-poetry.org/docs/pre-commit-hooks/). + +| action | description | +| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | +| `poetry-check` | Validate `pyproject.toml` when running `git commit` | +| `poetry-lock` | Update `poetry.lock` to match `pyproject.toml` when running `git commit`. To avoid updating packages, you can override `run` to include `--no-update` | +| `poetry-export` | Update `requirements.txt` to match `pyproject.toml` when running `git commit` | +| `poetry-install` | Install dependencies to make sure all locked packages are installed when running `git checkout` or `git merge` | + +You can enable any subset of these Actions using `trunk actions enable`. + +As written, all of these actions require that you have `poetry` in your `PATH` in order to run. + +## Hermetic Installation + +Trunk provides some mechanisms for a hermetic installation and execution of `poetry`. You can use +the Poetry [Tool](https://docs.trunk.io/check/advanced-setup/tools) to run `poetry` manually, and +you can override each of the action definitions to include the `packages_file` and `runtime`, like +so: + +```yaml +version: 0.1 +actions: + definitions: + - id: poetry-check + runtime: python + packages_file: ${cwd}/requirements.txt +``` + +These overrides will tell Trunk to use the hermetic install of `poetry` and use a sandboxed +execution for the Action. Note that this approach has some limitations, namely when creating +`poetry` shells or virtual environments. Currently full functionality is blocked by the inability to +unset runtime-inherited environments. Note that the `poetry` Tool suffers from the same problem. + +When using the hermetic installation, you will want to ensure that your `python` runtime is enabled +at the same version required by your Poetry configuration. See our +[docs](https://docs.trunk.io/check/advanced-setup/runtimes) for more information about specifying +runtime versions. + +## Notes + +Poetry requires Python 3.8 or higher to run. diff --git a/actions/poetry/plugin.yaml b/actions/poetry/plugin.yaml new file mode 100644 index 000000000..f088e7e29 --- /dev/null +++ b/actions/poetry/plugin.yaml @@ -0,0 +1,68 @@ +version: 0.1 +# NOTE: See README.md for usage guidelines. +actions: + definitions: + - id: poetry-check + display_name: poetry check + description: Run 'poetry check' to validate config + # runtime: python + # packages_file: ${cwd}/requirements.txt + run: poetry check + triggers: + - git_hooks: [pre-commit] + environment: + - name: VIRTUAL_ENV + value: ${env.VIRTUAL_ENV} + optional: true + + - id: poetry-lock + display_name: poetry lock + # You may wish to override this with 'poetry lock --no-update' + description: Run 'poetry lock' to update lock file to match pyproject.toml + run: poetry lock --no-update + # runtime: python + # packages_file: ${cwd}/requirements.txt + triggers: + - git_hooks: [pre-commit] + environment: + - name: VIRTUAL_ENV + value: ${env.VIRTUAL_ENV} + optional: true + + - id: poetry-export + display_name: poetry export + description: Run 'poetry export' to sync requirements.txt with lock file + run: poetry export -f requirements.txt -o requirements.txt + # packages_file: ${cwd}/requirements.txt + # runtime: python + triggers: + - git_hooks: [pre-commit] + environment: + - name: VIRTUAL_ENV + value: ${env.VIRTUAL_ENV} + optional: true + + - id: poetry-install + display_name: poetry install + description: Run 'poetry install' to ensure all locked packages are installed + run: poetry install + # packages_file: ${cwd}/requirements.txt + # runtime: python + triggers: + - git_hooks: [post-checkout, post-merge] + environment: + - name: VIRTUAL_ENV + value: ${env.VIRTUAL_ENV} + optional: true + +tools: + definitions: + - name: poetry + runtime: python + package: poetry + extra_packages: [poetry-plugin-export] + known_good_version: 1.8.2 + health_checks: + - command: poetry --version + parse_regex: ${semver} + shims: [poetry] diff --git a/actions/poetry/poetry.test.ts b/actions/poetry/poetry.test.ts new file mode 100644 index 000000000..46a4001a9 --- /dev/null +++ b/actions/poetry/poetry.test.ts @@ -0,0 +1,103 @@ +import * as fs from "fs"; +import * as path from "path"; +import { actionRunTest, toolInstallTest } from "tests"; +import { TrunkActionDriver } from "tests/driver"; + +toolInstallTest({ + toolName: "poetry", + toolVersion: "1.8.2", +}); + +const preCheck = (authors: boolean) => (driver: TrunkActionDriver) => { + const trunkYamlPath = ".trunk/trunk.yaml"; + const currentContents = driver.readFile(trunkYamlPath); + const newContents = currentContents.concat(` + definitions: + - id: poetry-check + runtime: python + packages_file: \${cwd}/requirements.txt + - id: poetry-lock + runtime: python + packages_file: \${cwd}/requirements.txt + - id: poetry-export + runtime: python + packages_file: \${cwd}/requirements.txt`); + driver.writeFile(trunkYamlPath, newContents); + + const authorsSection = authors ? "authors = []" : ""; + driver.writeFile( + "pyproject.toml", + `[tool.poetry] +name = "poetry-test" +version = "0.1.0" +description = "" +${authorsSection} + +[tool.poetry.dependencies] +python = "^3.10" +pendulum = "^3.0.0" + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api" + `, + ); +}; + +const checkTestCallback = async (driver: TrunkActionDriver) => { + try { + await driver.gitDriver?.commit( + "Test commit", + [], + { "--allow-empty": null }, + (error, result) => { + expect(error?.message).toContain("The fields ['authors'] are required in package mode."); + expect(result).toBeUndefined(); + }, + ); + + // Commit step should throw + expect(1).toBe(2); + } catch (_err) { + // Intentionally empty + } +}; + +const fileExistsCallback = (filename: string) => async (driver: TrunkActionDriver) => { + try { + await driver.gitDriver?.commit( + "Test commit", + [], + { "--allow-empty": null }, + (_error, result) => { + expect(_error).toBeFalsy(); + expect(result).toBeTruthy(); + }, + ); + + expect(fs.existsSync(path.resolve(driver.getSandbox(), filename))).toBeTruthy(); + } catch (_err) { + // Intentionally empty + } +}; + +actionRunTest({ + actionName: "poetry-check", + syncGitHooks: true, + testCallback: checkTestCallback, + preCheck: preCheck(/*authors=*/ false), +}); + +actionRunTest({ + actionName: "poetry-lock", + syncGitHooks: true, + testCallback: fileExistsCallback("poetry.lock"), + preCheck: preCheck(/*authors=*/ true), +}); + +actionRunTest({ + actionName: "poetry-export", + syncGitHooks: true, + testCallback: fileExistsCallback("requirements.txt"), + preCheck: preCheck(/*authors=*/ true), +}); diff --git a/actions/poetry/requirements.txt b/actions/poetry/requirements.txt new file mode 100644 index 000000000..541d1dabd --- /dev/null +++ b/actions/poetry/requirements.txt @@ -0,0 +1,2 @@ +poetry==1.8.2 +poetry-plugin-export==1.7.1 diff --git a/linters/actionlint/plugin.yaml b/linters/actionlint/plugin.yaml index 4b2c0a170..54eae807a 100644 --- a/linters/actionlint/plugin.yaml +++ b/linters/actionlint/plugin.yaml @@ -29,6 +29,7 @@ lint: files: [github-workflow] # Custom parser/trigger type defined in the trunk cli. tools: [actionlint] + description: Verify your Github workflows commands: - name: lint output: actionlint diff --git a/linters/ansible-lint/plugin.yaml b/linters/ansible-lint/plugin.yaml index bcb557669..ca71524ac 100644 --- a/linters/ansible-lint/plugin.yaml +++ b/linters/ansible-lint/plugin.yaml @@ -14,6 +14,7 @@ lint: supported_platforms: [linux, macos] # No files as this linter must be triggered manually. files: [] + description: Improve ansible playbooks commands: - name: lint version: ">=6.1.0" diff --git a/linters/autopep8/plugin.yaml b/linters/autopep8/plugin.yaml index 97bcffcbd..2ea2c6e61 100644 --- a/linters/autopep8/plugin.yaml +++ b/linters/autopep8/plugin.yaml @@ -11,6 +11,7 @@ lint: definitions: - name: autopep8 files: [python] + description: A python formatter commands: - name: format output: rewrite diff --git a/linters/bandit/plugin.yaml b/linters/bandit/plugin.yaml index 16ec14d7b..81a660d66 100644 --- a/linters/bandit/plugin.yaml +++ b/linters/bandit/plugin.yaml @@ -13,6 +13,7 @@ lint: tools: [bandit] suggest_if: files_present direct_configs: [.bandit] + description: A security linter for Python commands: - name: lint # Custom parser type defined in the trunk cli to handle bandit's JSON output. diff --git a/linters/biome/plugin.yaml b/linters/biome/plugin.yaml index 776da91cf..5a7410168 100644 --- a/linters/biome/plugin.yaml +++ b/linters/biome/plugin.yaml @@ -15,6 +15,7 @@ lint: - typescript - javascript - json + description: A static analyzer for web projects commands: - name: lint output: regex diff --git a/linters/biome/test_data/biome_v1.6.0_basic_check.check.shot b/linters/biome/test_data/biome_v1.6.0_basic_check.check.shot index a8d850004..4c68082f4 100644 --- a/linters/biome/test_data/biome_v1.6.0_basic_check.check.shot +++ b/linters/biome/test_data/biome_v1.6.0_basic_check.check.shot @@ -1,5 +1,4 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -// trunk-upgrade-validation:RELEASE exports[`Testing linter biome test basic_check 1`] = ` { diff --git a/linters/biome/test_data/biome_v1.6.0_basic_fmt.fmt.shot b/linters/biome/test_data/biome_v1.6.0_basic_fmt.fmt.shot index 89fab5e9b..0961c8a09 100644 --- a/linters/biome/test_data/biome_v1.6.0_basic_fmt.fmt.shot +++ b/linters/biome/test_data/biome_v1.6.0_basic_fmt.fmt.shot @@ -1,5 +1,4 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -// trunk-upgrade-validation:RELEASE exports[`Testing formatter biome test basic_fmt 1`] = ` "const foobar = () => {}; diff --git a/linters/biome/test_data/biome_v1.6.0_basic_json.fmt.shot b/linters/biome/test_data/biome_v1.6.0_basic_json.fmt.shot index d2f69a3ac..3b5af7e15 100644 --- a/linters/biome/test_data/biome_v1.6.0_basic_json.fmt.shot +++ b/linters/biome/test_data/biome_v1.6.0_basic_json.fmt.shot @@ -1,5 +1,4 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -// trunk-upgrade-validation:RELEASE exports[`Testing formatter biome test basic_json 1`] = ` "{ "a": "foo", "b": 1, "a": true } diff --git a/linters/black/plugin.yaml b/linters/black/plugin.yaml index 698e4b163..329fb2db1 100644 --- a/linters/black/plugin.yaml +++ b/linters/black/plugin.yaml @@ -10,6 +10,7 @@ lint: definitions: - name: black files: [python, jupyter, python-interface] + description: Uncompromising python formatter commands: - name: format output: rewrite diff --git a/linters/brakeman/brakeman.test.ts b/linters/brakeman/brakeman.test.ts index 9912664ac..d3cef51a0 100644 --- a/linters/brakeman/brakeman.test.ts +++ b/linters/brakeman/brakeman.test.ts @@ -3,7 +3,7 @@ import { osTimeoutMultiplier, skipOS, TEST_DATA } from "tests/utils"; // Note that the ruby setup can sometimes take a while. // Ruby build is quite slow on Mac, so only run tests on linux for now -jest.setTimeout(600000 * osTimeoutMultiplier); // 300s or 900s +jest.setTimeout(600000 * osTimeoutMultiplier); customLinterCheckTest({ linterName: "brakeman", diff --git a/linters/brakeman/plugin.yaml b/linters/brakeman/plugin.yaml index 452fb1eb4..ec97780f8 100644 --- a/linters/brakeman/plugin.yaml +++ b/linters/brakeman/plugin.yaml @@ -10,6 +10,7 @@ lint: definitions: - name: brakeman files: [ruby] + description: A vulnerability scanner for Ruby commands: - name: lint # 5.0.0 introduced the sarif output format. diff --git a/linters/buf/plugin.yaml b/linters/buf/plugin.yaml index 492c2320d..813a3d97b 100644 --- a/linters/buf/plugin.yaml +++ b/linters/buf/plugin.yaml @@ -32,6 +32,7 @@ lint: files: [proto] download: buf suggest_if: never + description: Formatter for Protobuf commands: - name: format output: rewrite @@ -62,6 +63,7 @@ lint: - name: buf-lint files: [proto] download: buf + description: Accelerate Protobuf development with Buf commands: - name: lint output: buf @@ -90,6 +92,7 @@ lint: files: [proto] download: buf suggest_if: never + description: Check for breaking Protobuf API changes commands: - name: lint output: buf diff --git a/linters/buildifier/plugin.yaml b/linters/buildifier/plugin.yaml index 897faa943..ddfb2f793 100644 --- a/linters/buildifier/plugin.yaml +++ b/linters/buildifier/plugin.yaml @@ -43,6 +43,7 @@ lint: - name: buildifier files: [starlark, bazel-build, bazel-workspace] tools: [buildifier] + description: Formatter for Bazel files commands: - name: fix run: buildifier --lint=fix --warnings=all "${target}" diff --git a/linters/buildifier/test_data/buildifier_v7.1.0_basic_check.check.shot b/linters/buildifier/test_data/buildifier_v7.1.0_basic_check.check.shot new file mode 100644 index 000000000..45eab45ea --- /dev/null +++ b/linters/buildifier/test_data/buildifier_v7.1.0_basic_check.check.shot @@ -0,0 +1,135 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP +// trunk-upgrade-validation:RELEASE + +exports[`Testing linter buildifier test basic_check 1`] = ` +{ + "issues": [ + { + "code": "module-docstring", + "column": "1", + "file": "test_data/basic.bzl", + "issueClass": "ISSUE_CLASS_EXISTING", + "issueUrl": "https://github.com/bazelbuild/buildtools/blob/master/WARNINGS.md#module-docstring", + "level": "LEVEL_HIGH", + "line": "1", + "linter": "buildifier", + "message": "The file has no module docstring. +A module docstring is a string literal (not a comment) which should be the first statement of a file (it may follow comment lines).", + "targetType": "starlark", + }, + { + "code": "load", + "column": "26", + "file": "test_data/basic.bzl", + "issueClass": "ISSUE_CLASS_EXISTING", + "issueUrl": "https://github.com/bazelbuild/buildtools/blob/master/WARNINGS.md#load", + "level": "LEVEL_HIGH", + "line": "1", + "linter": "buildifier", + "message": "Loaded symbol "a" is unused. Please remove it. +To disable the warning, add '@unused' in a comment. +If you want to re-export a symbol, use the following pattern: + + load(..., _a = "a", ...) + a = _a", + "targetType": "starlark", + }, + { + "code": "load", + "column": "26", + "file": "test_data/basic.bzl", + "issueClass": "ISSUE_CLASS_EXISTING", + "issueUrl": "https://github.com/bazelbuild/buildtools/blob/master/WARNINGS.md#load", + "level": "LEVEL_HIGH", + "line": "2", + "linter": "buildifier", + "message": "Loaded symbol "b" is unused. Please remove it. +To disable the warning, add '@unused' in a comment. +If you want to re-export a symbol, use the following pattern: + + load(..., _b = "b", ...) + b = _b", + "targetType": "starlark", + }, + ], + "lintActions": [ + { + "command": "fix", + "fileGroupName": "bazel-build", + "linter": "buildifier", + "paths": [ + "test_data/add_tables.BUILD", + ], + "verb": "TRUNK_VERB_FMT", + }, + { + "command": "fix", + "fileGroupName": "starlark", + "linter": "buildifier", + "paths": [ + "test_data/basic.bzl", + ], + "verb": "TRUNK_VERB_FMT", + }, + { + "command": "warn", + "fileGroupName": "bazel-build", + "linter": "buildifier", + "paths": [ + "test_data/add_tables.BUILD", + ], + "verb": "TRUNK_VERB_CHECK", + }, + { + "command": "warn", + "fileGroupName": "starlark", + "linter": "buildifier", + "paths": [ + "test_data/basic.bzl", + ], + "verb": "TRUNK_VERB_CHECK", + }, + { + "command": "warn", + "fileGroupName": "bazel-build", + "linter": "buildifier", + "paths": [ + "test_data/add_tables.BUILD", + ], + "upstream": true, + "verb": "TRUNK_VERB_CHECK", + }, + { + "command": "warn", + "fileGroupName": "starlark", + "linter": "buildifier", + "paths": [ + "test_data/basic.bzl", + ], + "upstream": true, + "verb": "TRUNK_VERB_CHECK", + }, + ], + "taskFailures": [], + "unformattedFiles": [ + { + "column": "1", + "file": "test_data/add_tables.BUILD", + "issueClass": "ISSUE_CLASS_UNFORMATTED", + "level": "LEVEL_HIGH", + "line": "1", + "linter": "buildifier", + "message": "Incorrect formatting, autoformat by running 'trunk fmt'", + }, + { + "column": "1", + "file": "test_data/basic.bzl", + "issueClass": "ISSUE_CLASS_UNFORMATTED", + "level": "LEVEL_HIGH", + "line": "1", + "linter": "buildifier", + "message": "Incorrect formatting, autoformat by running 'trunk fmt'", + }, + ], +} +`; diff --git a/linters/buildifier/test_data/buildifier_v7.1.0_no_config.test_data.add_tables.BUILD.fmt.shot b/linters/buildifier/test_data/buildifier_v7.1.0_no_config.test_data.add_tables.BUILD.fmt.shot new file mode 100644 index 000000000..54e82961f --- /dev/null +++ b/linters/buildifier/test_data/buildifier_v7.1.0_no_config.test_data.add_tables.BUILD.fmt.shot @@ -0,0 +1,36 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP +// trunk-upgrade-validation:RELEASE + +exports[`Testing formatter buildifier test no_config 1`] = ` +"foo_macro( + fizz = [ + ":lib2", + ":lib1", + ], +) + +filegroup( + name = "files", + srcs = glob(["**"]), +) + +sh_library( + name = "lib1", + srcs = ["src1.sh"], +) + +sh_library( + name = "lib2", + srcs = ["src1.sh"], +) + +sh_binary( + name = "foo", + srcs = ["foo.sh"], + deps = [ + ":lib1", + ":lib2", + ], +) +" +`; diff --git a/linters/buildifier/test_data/buildifier_v7.1.0_no_config.test_data.basic.bzl.fmt.shot b/linters/buildifier/test_data/buildifier_v7.1.0_no_config.test_data.basic.bzl.fmt.shot new file mode 100644 index 000000000..0f9da3bb5 --- /dev/null +++ b/linters/buildifier/test_data/buildifier_v7.1.0_no_config.test_data.basic.bzl.fmt.shot @@ -0,0 +1,11 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP +// trunk-upgrade-validation:RELEASE + +exports[`Testing formatter buildifier test no_config 1`] = ` +"# Misformatted file +def eponymous_name(): + name = native.package_name() + + return name[name.rfind("/") + 1:] +" +`; diff --git a/linters/buildifier/test_data/buildifier_v7.1.0_with_config.test_data.add_tables.BUILD.fmt.shot b/linters/buildifier/test_data/buildifier_v7.1.0_with_config.test_data.add_tables.BUILD.fmt.shot new file mode 100644 index 000000000..e4ce11ada --- /dev/null +++ b/linters/buildifier/test_data/buildifier_v7.1.0_with_config.test_data.add_tables.BUILD.fmt.shot @@ -0,0 +1,36 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP +// trunk-upgrade-validation:RELEASE + +exports[`Testing formatter buildifier test with_config 1`] = ` +"foo_macro( + fizz = [ + ":lib1", + ":lib2", + ], +) + +filegroup( + name = "files", + srcs = glob(["**"]), +) + +sh_library( + name = "lib1", + srcs = ["src1.sh"], +) + +sh_library( + name = "lib2", + srcs = ["src1.sh"], +) + +sh_binary( + name = "foo", + srcs = ["foo.sh"], + deps = [ + ":lib1", + ":lib2", + ], +) +" +`; diff --git a/linters/cfnlint/plugin.yaml b/linters/cfnlint/plugin.yaml index 5def28df7..0d2a2d4f5 100644 --- a/linters/cfnlint/plugin.yaml +++ b/linters/cfnlint/plugin.yaml @@ -10,6 +10,7 @@ lint: definitions: - name: cfnlint files: [cloudformation] + description: Checks Cloudformation files commands: - name: lint # Custom parser type defined in the trunk cli to handle cfnlint's JSON output and triggers. diff --git a/linters/checkov/plugin.yaml b/linters/checkov/plugin.yaml index eadb751de..62c18cd7f 100644 --- a/linters/checkov/plugin.yaml +++ b/linters/checkov/plugin.yaml @@ -11,6 +11,7 @@ lint: - name: checkov files: [terraform, cloudformation, docker, yaml, json] tools: [checkov] + description: Finds security issues in IaC files commands: - name: lint # on Windows, we need to make sure 'checkov' resolves to 'checkov.cmd' diff --git a/linters/circleci/plugin.yaml b/linters/circleci/plugin.yaml index 3b568aa73..4743e450c 100644 --- a/linters/circleci/plugin.yaml +++ b/linters/circleci/plugin.yaml @@ -11,6 +11,7 @@ lint: tools: [circleci] known_good_version: 0.1.28811 suggest_if: never + description: Validates CircleCI configuration files commands: - name: validate platforms: [windows] diff --git a/linters/clang-format/plugin.yaml b/linters/clang-format/plugin.yaml index 52b213d56..518a4fa3d 100644 --- a/linters/clang-format/plugin.yaml +++ b/linters/clang-format/plugin.yaml @@ -33,7 +33,8 @@ lint: definitions: - name: clang-format supported_platforms: [linux, macos] - files: [c/c++, proto] + description: Formatter for C/C++ and Protobuf + files: [c/c++, cuda, proto] commands: - name: format output: rewrite diff --git a/linters/clang-format/test_data/clang_format_v16.0.3_cuda.fmt.shot b/linters/clang-format/test_data/clang_format_v16.0.3_cuda.fmt.shot new file mode 100644 index 000000000..76e6a8d69 --- /dev/null +++ b/linters/clang-format/test_data/clang_format_v16.0.3_cuda.fmt.shot @@ -0,0 +1,11 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Testing formatter clang-format test cuda 1`] = ` +"__global__ void cuda_hello() { printf("Hello World from GPU!\\n"); } + +int main() { + cuda_hello<<<1, 1>>>(); + return 0; +} +" +`; diff --git a/linters/clang-format/test_data/cuda.in.cu b/linters/clang-format/test_data/cuda.in.cu new file mode 100644 index 000000000..bf6a375af --- /dev/null +++ b/linters/clang-format/test_data/cuda.in.cu @@ -0,0 +1,8 @@ +__global__ void cuda_hello(){ + printf("Hello World from GPU!\n"); +} + +int main() { + cuda_hello<<<1,1>>>( ); + return 0 ; +} diff --git a/linters/clang-tidy/plugin.yaml b/linters/clang-tidy/plugin.yaml index ad968b68e..80ac4e5e1 100644 --- a/linters/clang-tidy/plugin.yaml +++ b/linters/clang-tidy/plugin.yaml @@ -34,6 +34,7 @@ lint: - name: clang-tidy supported_platforms: [linux, macos] files: [c/c++-source] + description: Static Analyzer for C/C++ commands: - name: lint output: llvm @@ -42,6 +43,7 @@ lint: cache_results: true run_from: ${compile_command} read_output_from: tmp_file + run_when: [cli, monitor, ci] # Do not run from lsp - clangd is more optimized for this use-case. max_concurrency: 4 # Clang-tidy can be very memory intensive, limit the default concurrency. tools: [clang-tidy] suggest_if: config_present diff --git a/linters/clippy/plugin.yaml b/linters/clippy/plugin.yaml index e1ee7469a..705fe9179 100644 --- a/linters/clippy/plugin.yaml +++ b/linters/clippy/plugin.yaml @@ -9,6 +9,7 @@ lint: - name: clippy files: [rust] download: rust + description: Catch common mistakes and improve your Rust code. commands: - name: lint # Custom parser type defined in the trunk cli to handle clippy's JSON output. diff --git a/linters/cmake-format/plugin.yaml b/linters/cmake-format/plugin.yaml index b7775bab8..0f420e744 100644 --- a/linters/cmake-format/plugin.yaml +++ b/linters/cmake-format/plugin.yaml @@ -10,6 +10,7 @@ lint: definitions: - name: cmake-format files: [cmake] + description: A formatter for cmake files commands: - name: fix formatter: true diff --git a/linters/codespell/plugin.yaml b/linters/codespell/plugin.yaml index 178e9e27c..6aca0b572 100644 --- a/linters/codespell/plugin.yaml +++ b/linters/codespell/plugin.yaml @@ -12,6 +12,7 @@ lint: files: [ALL] direct_configs: [.codespellrc] suggest_if: config_present + description: Check for common misspellings in your code affects_cache: - pyproject.toml - setup.cfg diff --git a/linters/cspell/plugin.yaml b/linters/cspell/plugin.yaml index e4e9737e0..7c39aef41 100644 --- a/linters/cspell/plugin.yaml +++ b/linters/cspell/plugin.yaml @@ -11,6 +11,7 @@ lint: - name: cspell files: [ALL] tools: [cspell] + description: Check for spelling mistakes in your code commands: - name: lint output: regex diff --git a/linters/cue-fmt/plugin.yaml b/linters/cue-fmt/plugin.yaml index 0d37ba982..bcb8b4933 100644 --- a/linters/cue-fmt/plugin.yaml +++ b/linters/cue-fmt/plugin.yaml @@ -10,6 +10,7 @@ lint: definitions: - name: cue-fmt files: [cue] + description: A formatter for cue files commands: - name: format output: rewrite diff --git a/linters/dart/plugin.yaml b/linters/dart/plugin.yaml index 638db74f0..425990988 100644 --- a/linters/dart/plugin.yaml +++ b/linters/dart/plugin.yaml @@ -30,6 +30,7 @@ lint: files: [dart] known_good_version: 3.2.6 suggest_if: never + description: Lints and formats dart code affects_cache: - analysis_options.yaml - pubspec.yaml diff --git a/linters/deno/plugin.yaml b/linters/deno/plugin.yaml index 045a242c1..e94447cba 100644 --- a/linters/deno/plugin.yaml +++ b/linters/deno/plugin.yaml @@ -3,6 +3,7 @@ lint: definitions: - name: deno files: [javascript, typescript, markdown, json] + description: A formatter for web framework code commands: - name: format output: rewrite diff --git a/linters/detekt/plugin.yaml b/linters/detekt/plugin.yaml index 1e135aa5c..a4d4dc911 100644 --- a/linters/detekt/plugin.yaml +++ b/linters/detekt/plugin.yaml @@ -11,6 +11,7 @@ lint: - name: detekt files: [kotlin] download: detekt + description: Static code analysis for Kotlin commands: - name: lint platforms: [windows] @@ -45,6 +46,7 @@ lint: - name: detekt-explicit files: [kotlin] download: detekt + description: Static code analysis for Kotlin commands: - name: lint platforms: [windows] @@ -75,6 +77,7 @@ lint: - name: detekt-gradle supported_platforms: [linux, macos] files: [kotlin] + description: Static code analysis for Kotlin commands: - name: lint # Custom parser/trigger type defined in the trunk cli. diff --git a/linters/djlint/plugin.yaml b/linters/djlint/plugin.yaml index 5d9552c6c..3de172114 100644 --- a/linters/djlint/plugin.yaml +++ b/linters/djlint/plugin.yaml @@ -11,6 +11,7 @@ lint: - name: djlint files: [html] tools: [djlint] + description: HTML template linter and formatter commands: - name: lint output: regex diff --git a/linters/dotenv-linter/plugin.yaml b/linters/dotenv-linter/plugin.yaml index 0fe0b9116..cf8d04dec 100644 --- a/linters/dotenv-linter/plugin.yaml +++ b/linters/dotenv-linter/plugin.yaml @@ -33,6 +33,7 @@ lint: - name: dotenv-linter files: [dotenv] tools: [dotenv-linter] + description: Lightning-fast linter for .env files commands: - name: format output: rewrite diff --git a/linters/dotnet-format/plugin.yaml b/linters/dotnet-format/plugin.yaml index 9d9adb72a..789e8a39e 100644 --- a/linters/dotnet-format/plugin.yaml +++ b/linters/dotnet-format/plugin.yaml @@ -9,6 +9,7 @@ lint: # https://download.visualstudio.microsoft.com/download/pr/0f17575a-a6b0-4365-9b79-64db70022d23/56e0da10678e4b2cad0cba0a83a561af/dotnet-sdk-7.0.400-win-x86.zip, # but we don't support that yet. known_good_version: 7.0.400 + description: A formatter for dotnet files commands: - name: format run: dotnet format --no-restore --include ${target} diff --git a/linters/dustilock/plugin.yaml b/linters/dustilock/plugin.yaml index 8531043b4..6592c0a6d 100644 --- a/linters/dustilock/plugin.yaml +++ b/linters/dustilock/plugin.yaml @@ -11,6 +11,7 @@ lint: - name: dustilock files: [dustilock] tools: [dustilock] + description: Finds security issues in dustilock files commands: - name: scan output: regex diff --git a/linters/eslint/README.md b/linters/eslint/README.md new file mode 100644 index 000000000..721c74fc0 --- /dev/null +++ b/linters/eslint/README.md @@ -0,0 +1,22 @@ +# eslint + +## Migration Guide + +Trunk does not yet support `eslint@9.x`, which includes substantial config format changes (see their +[migration guide](https://eslint.org/docs/latest/use/migrate-to-9.0.0#flat-config)). If you'd like +to opt-in to `eslint@9.x` with Trunk before we release official support, you can add the following +override to your `.trunk/trunk.yaml`: + +```yaml +version: 0.1 +--- +lint: + enabled: + - eslint@9.0.0 + definitions: + - name: eslint + direct_configs: + - eslint.config.js + - eslint.config.mjs + - eslint.config.cjs +``` diff --git a/linters/eslint/eslint.test.ts b/linters/eslint/eslint.test.ts index afd88f330..694f2ad4c 100644 --- a/linters/eslint/eslint.test.ts +++ b/linters/eslint/eslint.test.ts @@ -1,6 +1,7 @@ import { spawnSync } from "child_process"; import fs from "fs"; import path from "path"; +import semver from "semver"; import { customLinterCheckTest } from "tests"; import { TrunkLintDriver } from "tests/driver"; import { osTimeoutMultiplier, TEST_DATA } from "tests/utils"; @@ -54,6 +55,7 @@ const preCheck = (driver: TrunkLintDriver) => { cwd: driver.getSandbox(), timeout: INSTALL_TIMEOUT, windowsHide: true, + shell: true, }, ); driver.debug(install); @@ -68,12 +70,22 @@ const preCheck = (driver: TrunkLintDriver) => { } }; +const manualVersionReplacer = (version: string) => { + // NOTE(Tyler): Continue to test eslint pre-9.0.0 and gate until we have a long-term fix. + const parsedVersion = semver.parse(version); + if (parsedVersion && parsedVersion.major >= 9) { + return "8.57.0"; + } + return version; +}; + // This set of testing is incomplete with regard to failure modes and unicode autofixes with eslint, but it serves as a sampling // Use upstream=false in order to supply autofixes for committed files. customLinterCheckTest({ linterName: "eslint", args: `${TEST_DATA} -y --upstream=false`, preCheck, + manualVersionReplacer, pathsToSnapshot: [ path.join(TEST_DATA, "non_ascii.ts"), path.join(TEST_DATA, "eof_autofix.ts"), @@ -86,4 +98,5 @@ customLinterCheckTest({ testName: "bad_install", args: `${TEST_DATA} -y`, preCheck: moveConfig, + manualVersionReplacer, }); diff --git a/linters/eslint/plugin.yaml b/linters/eslint/plugin.yaml index 29e21bc3f..1562bcb3a 100644 --- a/linters/eslint/plugin.yaml +++ b/linters/eslint/plugin.yaml @@ -11,6 +11,7 @@ lint: - name: eslint files: [typescript, javascript] tools: [eslint] + description: Find and fix problems in your TS/JS code commands: - name: lint output: eslint diff --git a/linters/eslint/test_data/eslint_v8.10.0_bad_install.check.shot b/linters/eslint/test_data/eslint_v8.10.0_bad_install.check.shot index b45630c46..438aa0f6a 100644 --- a/linters/eslint/test_data/eslint_v8.10.0_bad_install.check.shot +++ b/linters/eslint/test_data/eslint_v8.10.0_bad_install.check.shot @@ -1,5 +1,4 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -// trunk-upgrade-validation:RELEASE exports[`Testing linter eslint test bad_install 1`] = ` { diff --git a/linters/flake8/plugin.yaml b/linters/flake8/plugin.yaml index bfcaffd4b..0a21e615f 100644 --- a/linters/flake8/plugin.yaml +++ b/linters/flake8/plugin.yaml @@ -10,6 +10,7 @@ lint: definitions: - name: flake8 files: [python] + description: Python style guide enforcement commands: - name: lint run: flake8 ${target} --output-file "${tmpfile}" --exit-zero diff --git a/linters/git-diff-check/plugin.yaml b/linters/git-diff-check/plugin.yaml index 64e325d9d..25d98a1be 100644 --- a/linters/git-diff-check/plugin.yaml +++ b/linters/git-diff-check/plugin.yaml @@ -3,6 +3,7 @@ lint: definitions: - name: git-diff-check files: [ALL] + description: Checks for git conflicts commands: - output: regex name: lint diff --git a/linters/gitleaks/plugin.yaml b/linters/gitleaks/plugin.yaml index 61bef5fa2..d8b2b0753 100644 --- a/linters/gitleaks/plugin.yaml +++ b/linters/gitleaks/plugin.yaml @@ -10,6 +10,7 @@ lint: definitions: - name: gitleaks files: [ALL] + description: Protect and discover secrets commands: - name: lint run: gitleaks detect --no-git --source=${target} --exit-code=101 -f sarif -r "${tmpfile}" diff --git a/linters/gofmt/plugin.yaml b/linters/gofmt/plugin.yaml index 59c1b15c6..573be13a1 100644 --- a/linters/gofmt/plugin.yaml +++ b/linters/gofmt/plugin.yaml @@ -3,6 +3,7 @@ lint: definitions: - name: gofmt files: [go] + description: A formatter for Go code commands: - name: format output: rewrite diff --git a/linters/gofumpt/plugin.yaml b/linters/gofumpt/plugin.yaml index b5be10e46..f013fa267 100644 --- a/linters/gofumpt/plugin.yaml +++ b/linters/gofumpt/plugin.yaml @@ -11,6 +11,7 @@ lint: - name: gofumpt tools: [gofumpt] files: [go] + description: An opinionated formatter for Go code commands: - name: format output: rewrite diff --git a/linters/goimports/plugin.yaml b/linters/goimports/plugin.yaml index 6fee30c74..8a39c5e02 100644 --- a/linters/goimports/plugin.yaml +++ b/linters/goimports/plugin.yaml @@ -10,6 +10,7 @@ lint: definitions: - name: goimports files: [go] + description: Removes unused imports from Go code commands: - name: format output: rewrite diff --git a/linters/gokart/plugin.yaml b/linters/gokart/plugin.yaml index 07ea8bc6b..59468e821 100644 --- a/linters/gokart/plugin.yaml +++ b/linters/gokart/plugin.yaml @@ -12,6 +12,7 @@ lint: files: [go] tools: [gokart] suggest_if: config_present + description: Checks for security issues in Go code. environment: - name: PATH list: ["${linter}"] diff --git a/linters/golangci-lint/plugin.yaml b/linters/golangci-lint/plugin.yaml index 8fd02ba83..a67f80d6c 100644 --- a/linters/golangci-lint/plugin.yaml +++ b/linters/golangci-lint/plugin.yaml @@ -13,6 +13,7 @@ lint: - name: golangci-lint files: [go] tools: [golangci-lint] + description: A powerful Go linter runner environment: - name: GOLANGCI_LINT_CACHE value: ${cachedir} diff --git a/linters/golangci-lint/test_data/golangci_lint_v1.57.0_all.check.shot b/linters/golangci-lint/test_data/golangci_lint_v1.57.0_all.check.shot new file mode 100644 index 000000000..897738f10 --- /dev/null +++ b/linters/golangci-lint/test_data/golangci_lint_v1.57.0_all.check.shot @@ -0,0 +1,92 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP +// trunk-upgrade-validation:RELEASE + +exports[`Testing linter golangci-lint test all 1`] = ` +{ + "issues": [ + { + "autofixOptions": [ + { + "replacements": [ + { + "filePath": "test_data/basic.go", + "length": "34", + "offset": "45", + "replacementText": "// this is the main function 🏃. +", + }, + ], + }, + ], + "code": "godot", + "column": "34", + "file": "test_data/basic.go", + "issueClass": "ISSUE_CLASS_EXISTING", + "issueUrl": "https://golangci-lint.run/usage/linters/", + "level": "LEVEL_HIGH", + "line": "6", + "linter": "golangci-lint", + "message": "Comment should end in a period", + "targetType": "go", + }, + { + "code": "errcheck", + "column": "12", + "file": "test_data/basic.go", + "issueClass": "ISSUE_CLASS_EXISTING", + "issueUrl": "https://golangci-lint.run/usage/linters/", + "level": "LEVEL_HIGH", + "line": "8", + "linter": "golangci-lint", + "message": "Error return value of \`time.Parse\` is not checked", + "targetType": "go", + }, + { + "code": "unused", + "column": "6", + "file": "test_data/unused_func.go", + "issueClass": "ISSUE_CLASS_EXISTING", + "issueUrl": "https://golangci-lint.run/usage/linters/", + "level": "LEVEL_HIGH", + "line": "5", + "linter": "golangci-lint", + "message": "func \`helper\` is unused", + "targetType": "go", + }, + { + "code": "typecheck", + "file": "test_data/wrapper/printer.go", + "issueClass": "ISSUE_CLASS_EXISTING", + "issueUrl": "https://golangci-lint.run/usage/linters/", + "level": "LEVEL_HIGH", + "line": "1", + "linter": "golangci-lint", + "message": ": # golangcilint_linter_test/wrapper +wrapper/printer.go:12:23: undefined: Wrapper2", + "targetType": "go", + }, + ], + "lintActions": [ + { + "command": "lint", + "fileGroupName": "go", + "linter": "golangci-lint", + "paths": [ + "test_data", + ], + "verb": "TRUNK_VERB_CHECK", + }, + { + "command": "lint", + "fileGroupName": "go", + "linter": "golangci-lint", + "paths": [ + "test_data/wrapper", + ], + "verb": "TRUNK_VERB_CHECK", + }, + ], + "taskFailures": [], + "unformattedFiles": [], +} +`; diff --git a/linters/golangci-lint/test_data/golangci_lint_v1.57.0_empty.check.shot b/linters/golangci-lint/test_data/golangci_lint_v1.57.0_empty.check.shot new file mode 100644 index 000000000..08f295adc --- /dev/null +++ b/linters/golangci-lint/test_data/golangci_lint_v1.57.0_empty.check.shot @@ -0,0 +1,55 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP +// trunk-upgrade-validation:RELEASE + +exports[`Testing linter golangci-lint test empty 1`] = ` +{ + "issues": [ + { + "code": "typecheck", + "column": "1", + "file": "test_data/empty.go", + "issueClass": "ISSUE_CLASS_NEW", + "issueUrl": "https://golangci-lint.run/usage/linters/", + "level": "LEVEL_HIGH", + "line": "1", + "linter": "golangci-lint", + "message": "expected 'package', found 'EOF'", + "targetType": "go", + }, + { + "code": "typecheck", + "file": "test_data/wrapper/printer.go", + "issueClass": "ISSUE_CLASS_EXISTING", + "issueUrl": "https://golangci-lint.run/usage/linters/", + "level": "LEVEL_HIGH", + "line": "1", + "linter": "golangci-lint", + "message": ": # golangcilint_linter_test/wrapper +wrapper/printer.go:12:23: undefined: Wrapper2", + "targetType": "go", + }, + ], + "lintActions": [ + { + "command": "lint", + "fileGroupName": "go", + "linter": "golangci-lint", + "paths": [ + "test_data", + ], + "verb": "TRUNK_VERB_CHECK", + }, + { + "command": "lint", + "fileGroupName": "go", + "linter": "golangci-lint", + "paths": [ + "test_data/wrapper", + ], + "verb": "TRUNK_VERB_CHECK", + }, + ], + "taskFailures": [], + "unformattedFiles": [], +} +`; diff --git a/linters/golangci-lint/test_data/golangci_lint_v1.57.0_unbuildable.check.shot b/linters/golangci-lint/test_data/golangci_lint_v1.57.0_unbuildable.check.shot new file mode 100644 index 000000000..5e14a0891 --- /dev/null +++ b/linters/golangci-lint/test_data/golangci_lint_v1.57.0_unbuildable.check.shot @@ -0,0 +1,31 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP +// trunk-upgrade-validation:RELEASE + +exports[`Testing linter golangci-lint test unbuildable 1`] = ` +{ + "issues": [ + { + "code": "error", + "file": ".", + "issueClass": "ISSUE_CLASS_NEW", + "level": "LEVEL_HIGH", + "linter": "golangci-lint", + "message": "typechecking error: build constraints exclude all Go files in /tmp/plugins_", + "targetType": "go", + }, + ], + "lintActions": [ + { + "command": "lint", + "fileGroupName": "go", + "linter": "golangci-lint", + "paths": [ + ".", + ], + "verb": "TRUNK_VERB_CHECK", + }, + ], + "taskFailures": [], + "unformattedFiles": [], +} +`; diff --git a/linters/golines/plugin.yaml b/linters/golines/plugin.yaml index 5070024da..1c087ce2d 100644 --- a/linters/golines/plugin.yaml +++ b/linters/golines/plugin.yaml @@ -11,6 +11,7 @@ lint: - name: golines files: [go] tools: [golines] + description: Enforces line limits in Go commands: - name: format output: rewrite diff --git a/linters/google-java-format/plugin.yaml b/linters/google-java-format/plugin.yaml index b9902fad4..ca27a5e26 100644 --- a/linters/google-java-format/plugin.yaml +++ b/linters/google-java-format/plugin.yaml @@ -9,6 +9,7 @@ lint: - name: google-java-format files: [java] download: google-java-format.jar + description: A formatter for Java files commands: - name: format platforms: [windows] diff --git a/linters/graphql-schema-linter/plugin.yaml b/linters/graphql-schema-linter/plugin.yaml index 624dc3f56..32fee08b8 100644 --- a/linters/graphql-schema-linter/plugin.yaml +++ b/linters/graphql-schema-linter/plugin.yaml @@ -14,6 +14,7 @@ lint: tools: [graphql-schema-linter] known_good_version: 3.0.1 files: [graphql-schema] + description: Validate GraphQL Schema definitions commands: - name: lint # on Windows, we need to make sure the binary resolves to the cmd form diff --git a/linters/hadolint/plugin.yaml b/linters/hadolint/plugin.yaml index b13fe7340..e462ac52e 100644 --- a/linters/hadolint/plugin.yaml +++ b/linters/hadolint/plugin.yaml @@ -31,6 +31,7 @@ lint: - name: hadolint files: [docker] tools: [hadolint] + description: Helps you build best practice Docker images commands: - name: lint # Custom parser type defined in the trunk cli to handle hadolint's JSON output. diff --git a/linters/haml-lint/haml_lint.test.ts b/linters/haml-lint/haml_lint.test.ts index 1864aabea..ccc83613a 100644 --- a/linters/haml-lint/haml_lint.test.ts +++ b/linters/haml-lint/haml_lint.test.ts @@ -3,7 +3,7 @@ import { osTimeoutMultiplier, skipOS, TEST_DATA } from "tests/utils"; // Note that the first-time ruby/rufo download can sometimes take a while. // Ruby build is quite slow on Mac, so only run tests on linux for now -jest.setTimeout(600000 * osTimeoutMultiplier); // 300s or 900s +jest.setTimeout(600000 * osTimeoutMultiplier); // Ruby build is quite slow on Mac, so only run tests on linux for now customLinterCheckTest({ diff --git a/linters/haml-lint/plugin.yaml b/linters/haml-lint/plugin.yaml index 213f94d2d..175ee9b7f 100644 --- a/linters/haml-lint/plugin.yaml +++ b/linters/haml-lint/plugin.yaml @@ -10,6 +10,7 @@ lint: definitions: - name: haml-lint files: [haml] + description: Keeps HAML files clean and readable commands: - name: lint # Custom parser type defined in the trunk cli to handle haml_lint's JSON output. diff --git a/linters/isort/plugin.yaml b/linters/isort/plugin.yaml index 26d8a9e1e..a630862ba 100644 --- a/linters/isort/plugin.yaml +++ b/linters/isort/plugin.yaml @@ -10,6 +10,7 @@ lint: definitions: - name: isort files: [python] + description: Sorts your Python imports commands: - name: format output: rewrite diff --git a/linters/iwyu/plugin.yaml b/linters/iwyu/plugin.yaml index ffa837a27..383de6554 100644 --- a/linters/iwyu/plugin.yaml +++ b/linters/iwyu/plugin.yaml @@ -30,6 +30,7 @@ lint: - name: include-what-you-use files: [c/c++-source] tools: [include-what-you-use] + description: Removes unused includes from C/C++ code. commands: - name: lint run_from: ${compile_command} diff --git a/linters/ktlint/plugin.yaml b/linters/ktlint/plugin.yaml index 0d4711dcd..371398932 100644 --- a/linters/ktlint/plugin.yaml +++ b/linters/ktlint/plugin.yaml @@ -12,6 +12,7 @@ lint: files: [kotlin] download: ktlint runtime: java + description: An anti-bikeshedding Kotlin linter and formatter commands: - name: format platforms: [windows] diff --git a/linters/kube-linter/kube_linter.test.ts b/linters/kube-linter/kube_linter.test.ts index f26e59447..37a1027d5 100644 --- a/linters/kube-linter/kube_linter.test.ts +++ b/linters/kube-linter/kube_linter.test.ts @@ -1,7 +1,7 @@ import { linterCheckTest } from "tests"; import { osTimeoutMultiplier } from "tests/utils"; -jest.setTimeout(900000 * osTimeoutMultiplier); // 300s or 900s +jest.setTimeout(900000 * osTimeoutMultiplier); // TODO(Tyler): We will eventually need to add a couple more test cases involving failure modes. linterCheckTest({ linterName: "kube-linter" }); diff --git a/linters/kube-linter/plugin.yaml b/linters/kube-linter/plugin.yaml index 1a6b3c81b..d040b35fc 100644 --- a/linters/kube-linter/plugin.yaml +++ b/linters/kube-linter/plugin.yaml @@ -10,6 +10,7 @@ lint: definitions: - name: kube-linter tools: [kube-linter] + description: A static analyzer for Kubernetes files: - yaml commands: diff --git a/linters/markdown-link-check/markdown-link-check.test.ts b/linters/markdown-link-check/markdown-link-check.test.ts index 0c3fc1777..716aba1ea 100644 --- a/linters/markdown-link-check/markdown-link-check.test.ts +++ b/linters/markdown-link-check/markdown-link-check.test.ts @@ -1,3 +1,11 @@ import { linterCheckTest } from "tests"; -linterCheckTest({ linterName: "markdown-link-check" }); +const manualVersionReplacer = (version: string) => { + if (version === "3.12.1") { + // As of 3/19, 3.12.1 cannot check for anchors, so we view it as a bad version. + return "3.11.2"; + } + return version; +}; + +linterCheckTest({ linterName: "markdown-link-check", manualVersionReplacer }); diff --git a/linters/markdown-link-check/plugin.yaml b/linters/markdown-link-check/plugin.yaml index 57507bd01..06263a2df 100644 --- a/linters/markdown-link-check/plugin.yaml +++ b/linters/markdown-link-check/plugin.yaml @@ -11,6 +11,7 @@ lint: - name: markdown-link-check files: [markdown] tools: [markdown-link-check] + description: Checks markdown files for broken links commands: - name: lint # Custom parser type defined in the trunk cli to handle markdownlint's JSON output. diff --git a/linters/markdown-table-prettify/plugin.yaml b/linters/markdown-table-prettify/plugin.yaml index 415ac73f8..a380b0a6b 100644 --- a/linters/markdown-table-prettify/plugin.yaml +++ b/linters/markdown-table-prettify/plugin.yaml @@ -9,6 +9,7 @@ tools: lint: definitions: - name: markdown-table-prettify + description: Prettify markdown tables files: [markdown] main_tool: markdown-table-prettify known_good_version: 3.6.0 diff --git a/linters/markdownlint/plugin.yaml b/linters/markdownlint/plugin.yaml index 4de8b135c..978bbdd0c 100644 --- a/linters/markdownlint/plugin.yaml +++ b/linters/markdownlint/plugin.yaml @@ -11,6 +11,7 @@ lint: - name: markdownlint files: [markdown] tools: [markdownlint] + description: A style checker and lint tool for markdown files commands: - name: lint # Custom parser type defined in the trunk cli to handle markdownlint's JSON output. diff --git a/linters/mypy/plugin.yaml b/linters/mypy/plugin.yaml index db319f832..e301908b2 100644 --- a/linters/mypy/plugin.yaml +++ b/linters/mypy/plugin.yaml @@ -9,6 +9,7 @@ tools: lint: definitions: - name: mypy + description: Static type checker for Python files: [python, python-interface] commands: - name: lint diff --git a/linters/mypy/test_data/mypy_v1.10.0_CUSTOM.check.shot b/linters/mypy/test_data/mypy_v1.10.0_CUSTOM.check.shot new file mode 100644 index 000000000..8e50c461f --- /dev/null +++ b/linters/mypy/test_data/mypy_v1.10.0_CUSTOM.check.shot @@ -0,0 +1,177 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Testing linter mypy test CUSTOM 1`] = ` +{ + "issues": [ + { + "code": "import-untyped", + "column": "1", + "file": "test_data/basic.py", + "issueClass": "ISSUE_CLASS_EXISTING", + "issueUrl": "https://mypy.readthedocs.io/en/stable/error_code_list.html", + "level": "LEVEL_HIGH", + "line": "1", + "linter": "mypy", + "message": "Library stubs not installed for "google.protobuf"", + "targetType": "python", + }, + { + "code": "import-untyped", + "column": "1", + "file": "test_data/basic.py", + "issueClass": "ISSUE_CLASS_EXISTING", + "issueUrl": "https://mypy.readthedocs.io/en/stable/error_code_list.html", + "level": "LEVEL_HIGH", + "line": "1", + "linter": "mypy", + "message": "Library stubs not installed for "google.protobuf.descriptor_pb2"", + "targetType": "python", + }, + { + "code": "note", + "column": "1", + "file": "test_data/basic.py", + "issueClass": "ISSUE_CLASS_EXISTING", + "issueUrl": "https://mypy.readthedocs.io/en/stable/error_code_list.html", + "level": "LEVEL_HIGH", + "line": "1", + "linter": "mypy", + "message": "Hint: "python3 -m pip install types-protobuf". (or run "mypy --install-types" to install all missing stub packages). See https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports", + "targetType": "python", + }, + { + "code": "arg-type", + "column": "10", + "file": "test_data/basic.py", + "issueClass": "ISSUE_CLASS_EXISTING", + "issueUrl": "https://mypy.readthedocs.io/en/stable/error_code_list.html", + "level": "LEVEL_HIGH", + "line": "13", + "linter": "mypy", + "message": "Argument 1 to "greeting" has incompatible type "int"; expected "str"", + "targetType": "python", + }, + { + "code": "arg-type", + "column": "10", + "file": "test_data/basic.py", + "issueClass": "ISSUE_CLASS_EXISTING", + "issueUrl": "https://mypy.readthedocs.io/en/stable/error_code_list.html", + "level": "LEVEL_HIGH", + "line": "14", + "linter": "mypy", + "message": "Argument 1 to "greeting" has incompatible type "bytes"; expected "str"", + "targetType": "python", + }, + { + "code": "func-returns-value", + "column": "5", + "file": "test_data/basic.py", + "issueClass": "ISSUE_CLASS_EXISTING", + "issueUrl": "https://mypy.readthedocs.io/en/stable/error_code_list.html", + "level": "LEVEL_HIGH", + "line": "15", + "linter": "mypy", + "message": ""printer" does not return a value (it only ever returns None)", + "targetType": "python", + }, + { + "code": "assignment", + "column": "10", + "file": "test_data/basic.py", + "issueClass": "ISSUE_CLASS_EXISTING", + "issueUrl": "https://mypy.readthedocs.io/en/stable/error_code_list.html", + "level": "LEVEL_HIGH", + "line": "16", + "linter": "mypy", + "message": "Incompatible types in assignment (expression has type "int", variable has type "str")", + "targetType": "python", + }, + { + "code": "attr-defined", + "column": "1", + "file": "test_data/basic.py", + "issueClass": "ISSUE_CLASS_EXISTING", + "issueUrl": "https://mypy.readthedocs.io/en/stable/error_code_list.html", + "level": "LEVEL_HIGH", + "line": "3", + "linter": "mypy", + "message": "Module "test_data" has no attribute "mypy_import2"", + "targetType": "python", + }, + { + "code": "return", + "column": "1", + "file": "test_data/source.py", + "issueClass": "ISSUE_CLASS_EXISTING", + "issueUrl": "https://mypy.readthedocs.io/en/stable/error_code_list.html", + "level": "LEVEL_HIGH", + "line": "8", + "linter": "mypy", + "message": "Missing return statement", + "targetType": "python", + }, + ], + "lintActions": [ + { + "command": "lint", + "fileGroupName": "python", + "linter": "mypy", + "paths": [ + "test_data/__init__.py", + ], + "verb": "TRUNK_VERB_CHECK", + }, + { + "command": "lint", + "fileGroupName": "python", + "linter": "mypy", + "paths": [ + "test_data/basic.py", + ], + "verb": "TRUNK_VERB_CHECK", + }, + { + "command": "lint", + "fileGroupName": "python", + "linter": "mypy", + "paths": [ + "test_data/source.py", + ], + "verb": "TRUNK_VERB_CHECK", + }, + { + "command": "lint", + "fileGroupName": "python", + "linter": "mypy", + "paths": [ + "test_data/__init__.py", + ], + "upstream": true, + "verb": "TRUNK_VERB_CHECK", + }, + { + "command": "lint", + "fileGroupName": "python", + "linter": "mypy", + "paths": [ + "test_data/basic.py", + ], + "upstream": true, + "verb": "TRUNK_VERB_CHECK", + }, + { + "command": "lint", + "fileGroupName": "python", + "linter": "mypy", + "paths": [ + "test_data/source.py", + ], + "upstream": true, + "verb": "TRUNK_VERB_CHECK", + }, + ], + "taskFailures": [], + "unformattedFiles": [], +} +`; diff --git a/linters/nancy/plugin.yaml b/linters/nancy/plugin.yaml index f212c2e74..0b16031a4 100644 --- a/linters/nancy/plugin.yaml +++ b/linters/nancy/plugin.yaml @@ -21,6 +21,7 @@ lint: files: [go-lockfile] download: nancy runtime: go + description: Checks for vulnerabilities in your Go dependencies commands: - output: sarif run: sh ${plugin}/linters/nancy/run.sh diff --git a/linters/nixpkgs-fmt/nixpkgs_fmt.test.ts b/linters/nixpkgs-fmt/nixpkgs_fmt.test.ts index fb68b786d..1ce6c05c1 100644 --- a/linters/nixpkgs-fmt/nixpkgs_fmt.test.ts +++ b/linters/nixpkgs-fmt/nixpkgs_fmt.test.ts @@ -1,7 +1,7 @@ import { linterFmtTest, TestCallback } from "tests"; import { osTimeoutMultiplier, skipOS } from "tests/utils"; -jest.setTimeout(600000 * osTimeoutMultiplier); // 300s or 900s +jest.setTimeout(600000 * osTimeoutMultiplier); // Earlier nixpkgs-fmt transitive dependencies are no longer // supported through older rust runtime installs. diff --git a/linters/nixpkgs-fmt/plugin.yaml b/linters/nixpkgs-fmt/plugin.yaml index 6749db7ae..b5536eadf 100644 --- a/linters/nixpkgs-fmt/plugin.yaml +++ b/linters/nixpkgs-fmt/plugin.yaml @@ -6,6 +6,7 @@ lint: package: nixpkgs-fmt runtime: rust files: [nix] + description: Formatter for Nix commands: - output: rewrite run: nixpkgs-fmt ${target} diff --git a/linters/opa/plugin.yaml b/linters/opa/plugin.yaml index 56677076d..50380473e 100644 --- a/linters/opa/plugin.yaml +++ b/linters/opa/plugin.yaml @@ -27,6 +27,7 @@ lint: files: [rego] main_tool: opa known_good_version: 0.62.1 + description: Formatter for OPA files suggest_if: never commands: # TODO(Tyler): Add support for opa check command. diff --git a/linters/osv-scanner/plugin.yaml b/linters/osv-scanner/plugin.yaml index 1a414a095..66847e8f6 100644 --- a/linters/osv-scanner/plugin.yaml +++ b/linters/osv-scanner/plugin.yaml @@ -42,6 +42,7 @@ lint: files: [lockfile] tools: [osv-scanner] known_good_version: 1.3.6 + description: Checks for known vulnerabilities in your dependencies commands: - name: scan output: sarif diff --git a/linters/oxipng/plugin.yaml b/linters/oxipng/plugin.yaml index 37fd0ac50..06d173bcd 100644 --- a/linters/oxipng/plugin.yaml +++ b/linters/oxipng/plugin.yaml @@ -23,6 +23,7 @@ lint: - name: oxipng files: [png] download: oxipng + description: Optimize PNG images commands: - name: fmt output: rewrite diff --git a/linters/perlcritic/plugin.yaml b/linters/perlcritic/plugin.yaml index 2599f92cf..ec478155e 100644 --- a/linters/perlcritic/plugin.yaml +++ b/linters/perlcritic/plugin.yaml @@ -3,6 +3,7 @@ lint: definitions: - name: perlcritic supported_platforms: [linux, macos] + description: Static analysis tool for Perl commands: - output: regex success_codes: diff --git a/linters/perltidy/plugin.yaml b/linters/perltidy/plugin.yaml index d5ddf7053..bdbd6f331 100644 --- a/linters/perltidy/plugin.yaml +++ b/linters/perltidy/plugin.yaml @@ -3,6 +3,7 @@ lint: definitions: - name: perltidy supported_platforms: [linux, macos] + description: Formatter for Perl commands: - output: rewrite success_codes: diff --git a/linters/phpstan/phpstan.test.ts b/linters/phpstan/phpstan.test.ts new file mode 100644 index 000000000..cd5626d05 --- /dev/null +++ b/linters/phpstan/phpstan.test.ts @@ -0,0 +1,4 @@ +import { linterCheckTest } from "tests"; +import { skipOS } from "tests/utils"; + +linterCheckTest({ linterName: "phpstan", skipTestIf: skipOS(["win32"]) }); diff --git a/linters/phpstan/phpstan_parser.py b/linters/phpstan/phpstan_parser.py new file mode 100755 index 000000000..32a7133e4 --- /dev/null +++ b/linters/phpstan/phpstan_parser.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python3 + +import json +import sys + + +def main(): + phpstan_json = json.loads(sys.stdin.read()) + + results = [] + for file_name in phpstan_json["files"]: + file_result = phpstan_json["files"][file_name] + for result in file_result["messages"]: + result = { + # We do not have a ruleId + "message": { + "text": result["message"], + }, + "ruleId": "phpstan", + "level": "error", + "locations": [ + { + "physicalLocation": { + "artifactLocation": {"uri": file_name}, + "region": { + "startLine": result["line"], + "startColumn": 0, # Output column is not available in phpstan + }, + } + }, + ], + } + results.append(result) + + sarif = { + "$schema": "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json", + "version": "2.1.0", + "runs": [{"results": results}], + } + + print(json.dumps(sarif, indent=2)) + + +if __name__ == "__main__": + main() diff --git a/linters/phpstan/plugin.yaml b/linters/phpstan/plugin.yaml new file mode 100644 index 000000000..e2f117e2a --- /dev/null +++ b/linters/phpstan/plugin.yaml @@ -0,0 +1,33 @@ +version: 0.1 +tools: + definitions: + - name: phpstan + runtime: php + package: phpstan/phpstan + known_good_version: 1.10.58 + shims: [phpstan] + environment: + - name: PATH + list: ["${tool}/vendor/bin"] +lint: + definitions: + - name: phpstan + main_tool: phpstan + known_good_version: 1.10.58 + description: PHP Static Analysis Tool + commands: + - run: phpstan analyze "${target}" --error-format=json --level=9 + output: sarif + success_codes: [0, 1] + files: [php] + batch: true + cache_results: true + read_output_from: stdout + parser: + runtime: python + run: python3 ${plugin}/linters/phpstan/phpstan_parser.py + + direct_configs: + - phpstan.neon + - phpstan.neon.dist + - phpstan.dist.neon diff --git a/linters/phpstan/test_data/basic.in.php b/linters/phpstan/test_data/basic.in.php new file mode 100644 index 000000000..749995fbe --- /dev/null +++ b/linters/phpstan/test_data/basic.in.php @@ -0,0 +1,9 @@ +format('j. n. Y'); + } +} diff --git a/linters/phpstan/test_data/phpstan_v1.10.58_basic.check.shot b/linters/phpstan/test_data/phpstan_v1.10.58_basic.check.shot new file mode 100644 index 000000000..abf9957a7 --- /dev/null +++ b/linters/phpstan/test_data/phpstan_v1.10.58_basic.check.shot @@ -0,0 +1,51 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Testing linter phpstan test basic 1`] = ` +{ + "issues": [ + { + "code": "phpstan", + "file": "test_data/basic.in.php", + "issueClass": "ISSUE_CLASS_EXISTING", + "level": "LEVEL_HIGH", + "line": "5", + "linter": "phpstan", + "message": "Parameter $date of method HelloWorld::sayHello() has invalid type DateTimeImutable.", + "targetType": "php", + }, + { + "code": "phpstan", + "file": "test_data/basic.in.php", + "issueClass": "ISSUE_CLASS_EXISTING", + "level": "LEVEL_HIGH", + "line": "7", + "linter": "phpstan", + "message": "Call to method format() on an unknown class DateTimeImutable.", + "targetType": "php", + }, + ], + "lintActions": [ + { + "command": "lint", + "fileGroupName": "php", + "linter": "phpstan", + "paths": [ + "test_data/basic.in.php", + ], + "verb": "TRUNK_VERB_CHECK", + }, + { + "command": "lint", + "fileGroupName": "php", + "linter": "phpstan", + "paths": [ + "test_data/basic.in.php", + ], + "upstream": true, + "verb": "TRUNK_VERB_CHECK", + }, + ], + "taskFailures": [], + "unformattedFiles": [], +} +`; diff --git a/linters/plugin.yaml b/linters/plugin.yaml index 5552fccc0..f5249f4a8 100644 --- a/linters/plugin.yaml +++ b/linters/plugin.yaml @@ -5,6 +5,14 @@ lint: leading_delimiter: "{-" trailing_delimiter: "-}" + - name: brace-slashes-block + leading_delimiter: "{/*" + trailing_delimiter: "*/}" + + - name: brace-slashes-block-spaced + leading_delimiter: "{ /*" + trailing_delimiter: "*/ }" + - name: dashes-block leading_delimiter: --[[ trailing_delimiter: --]] @@ -149,6 +157,13 @@ lint: comments: - slashes-block + - name: cuda + extensions: + - cu + comments: + - slashes-block + - slashes-inline + - name: cue extensions: - cue @@ -275,12 +290,22 @@ lint: extensions: - cjs - js - - jsx - mjs + inherit: + - javascript-xml comments: - slashes-block - slashes-inline + - name: javascript-xml + extensions: + - jsx + comments: + - slashes-block + - slashes-inline + - brace-slashes-block + - brace-slashes-block-spaced + - name: json extensions: - json @@ -412,6 +437,12 @@ lint: extensions: - png + - name: postcss + extensions: + # TODO(Tyler): Do we want to include css here as well? + - pcss + - postcss + - name: powershell extensions: - ps1 @@ -559,10 +590,20 @@ lint: extensions: - mts - ts + inherit: + - typescript-xml + comments: + - slashes-block + - slashes-inline + + - name: typescript-xml + extensions: - tsx comments: - slashes-block - slashes-inline + - brace-slashes-block + - brace-slashes-block-spaced - name: xib extensions: diff --git a/linters/pmd/plugin.yaml b/linters/pmd/plugin.yaml index 4884c145f..64ca2214b 100644 --- a/linters/pmd/plugin.yaml +++ b/linters/pmd/plugin.yaml @@ -2,49 +2,67 @@ version: 0.1 lint: downloads: - name: pmd + args: + semver: ${version}=>(pmd_releases\/)*(?P.*) downloads: + - url: https://github.com/pmd/pmd/releases/download/pmd_releases%2F${semver}/pmd-dist-${semver}-bin.zip + version: ">=7.0.0" + strip_components: 1 - url: https://github.com/pmd/pmd/releases/download/pmd_releases%2F${semver}/pmd-bin-${semver}.zip strip_components: 1 - args: - semver: ${version}=>(pmd_releases\/)*(?P.*) definitions: - name: pmd download: pmd + description: Static code analysis for Java and Apex commands: + - name: lint-apex + version: ">=7.0.0" + output: sarif + # Override this in your repo if you have custom rulesets + run: pmd check -R rulesets/apex/quickstart.xml -f sarif -d ${target} + success_codes: [0, 4] + read_output_from: stdout + files: [apex] - name: lint-apex platforms: [windows] output: sarif - # Override this in your repo if you have a custom rulesets + # Override this in your repo if you have custom rulesets run: pmd.bat -R rulesets/apex/quickstart.xml -f sarif -d ${target} success_codes: [0, 4] read_output_from: stdout - files: - - apex + files: [apex] - name: lint-apex + # 6.55.0 uses run.sh in place of pmd for non-Windows output: sarif - # Override this in your repo if you have a custom rulesets + # Override this in your repo if you have custom rulesets run: run.sh pmd -R rulesets/apex/quickstart.xml -f sarif -d ${target} success_codes: [0, 4] read_output_from: stdout - files: - - apex + files: [apex] + - name: lint-java + version: ">=7.0.0" + output: sarif + # Override this in your repo if you have custom rulesets + run: pmd check -R rulesets/java/quickstart.xml -f sarif -d ${target} + success_codes: [0, 4] + read_output_from: stdout + files: [java] - name: lint-java platforms: [windows] output: sarif - # Override this in your repo if you have a custom rulesets + # Override this in your repo if you have custom rulesets run: pmd.bat -R rulesets/java/quickstart.xml -f sarif -d ${target} success_codes: [0, 4] read_output_from: stdout - files: - - java + files: [java] - name: lint-java + # 6.55.0 uses run.sh in place of pmd output: sarif - # Override this in your repo if you have a custom rulesets + # Override this in your repo if you have custom rulesets run: run.sh pmd -R rulesets/java/quickstart.xml -f sarif -d ${target} success_codes: [0, 4] read_output_from: stdout - files: - - java + files: [java] runtime: java suggest_if: never known_good_version: 6.55.0 diff --git a/linters/pmd/pmd.test.ts b/linters/pmd/pmd.test.ts index 5ccf58c6a..7b56e8f1a 100644 --- a/linters/pmd/pmd.test.ts +++ b/linters/pmd/pmd.test.ts @@ -1,5 +1,15 @@ -import { linterCheckTest } from "tests"; +import semver from "semver"; +import { customLinterCheckTest } from "tests"; +import { TEST_DATA } from "tests/utils"; -linterCheckTest({ +const versionGreaterThanOrEqual = (a: string, b: string) => { + const normalizedA = a.replace("pmd_releases/", ""); + const normalizedB = b.replace("pmd_releases/", ""); + return semver.gte(normalizedA, normalizedB); +}; + +customLinterCheckTest({ linterName: "pmd", + args: TEST_DATA, + versionGreaterThanOrEqual, }); diff --git a/linters/pmd/test_data/pmd_v6.55.0_apex.check.shot b/linters/pmd/test_data/pmd_v6.55.0_CUSTOM.check.shot similarity index 54% rename from linters/pmd/test_data/pmd_v6.55.0_apex.check.shot rename to linters/pmd/test_data/pmd_v6.55.0_CUSTOM.check.shot index 33cad54e7..14056c099 100644 --- a/linters/pmd/test_data/pmd_v6.55.0_apex.check.shot +++ b/linters/pmd/test_data/pmd_v6.55.0_CUSTOM.check.shot @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Testing linter pmd test apex 1`] = ` +exports[`Testing linter pmd test CUSTOM 1`] = ` { "issues": [ { @@ -57,6 +57,42 @@ exports[`Testing linter pmd test apex 1`] = ` ], "targetType": "apex", }, + { + "code": "NoPackage", + "column": "1", + "file": "test_data/hello.in.java", + "issueClass": "ISSUE_CLASS_EXISTING", + "level": "LEVEL_HIGH", + "line": "3", + "linter": "pmd", + "message": "All classes, interfaces, enums and annotations must belong to a named package", + "ranges": [ + { + "filePath": "test_data/hello.in.java", + "length": "116", + "offset": "23", + }, + ], + "targetType": "java", + }, + { + "code": "UseUtilityClass", + "column": "18", + "file": "test_data/hello.in.java", + "issueClass": "ISSUE_CLASS_EXISTING", + "level": "LEVEL_HIGH", + "line": "3", + "linter": "pmd", + "message": "All methods are static. Consider using a utility class instead. Alternatively, you could add a private constructor or make the class abstract to silence this warning.", + "ranges": [ + { + "filePath": "test_data/hello.in.java", + "length": "99", + "offset": "40", + }, + ], + "targetType": "java", + }, ], "lintActions": [ { @@ -78,6 +114,25 @@ exports[`Testing linter pmd test apex 1`] = ` "upstream": true, "verb": "TRUNK_VERB_CHECK", }, + { + "command": "lint-java", + "fileGroupName": "java", + "linter": "pmd", + "paths": [ + "test_data/hello.in.java", + ], + "verb": "TRUNK_VERB_CHECK", + }, + { + "command": "lint-java", + "fileGroupName": "java", + "linter": "pmd", + "paths": [ + "test_data/hello.in.java", + ], + "upstream": true, + "verb": "TRUNK_VERB_CHECK", + }, ], "taskFailures": [], "unformattedFiles": [], diff --git a/linters/pmd/test_data/pmd_v6.55.0_hello.check.shot b/linters/pmd/test_data/pmd_v6.55.0_hello.check.shot deleted file mode 100644 index 49509de8a..000000000 --- a/linters/pmd/test_data/pmd_v6.55.0_hello.check.shot +++ /dev/null @@ -1,67 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Testing linter pmd test hello 1`] = ` -{ - "issues": [ - { - "code": "NoPackage", - "column": "1", - "file": "test_data/hello.in.java", - "issueClass": "ISSUE_CLASS_EXISTING", - "level": "LEVEL_HIGH", - "line": "3", - "linter": "pmd", - "message": "All classes, interfaces, enums and annotations must belong to a named package", - "ranges": [ - { - "filePath": "test_data/hello.in.java", - "length": "116", - "offset": "23", - }, - ], - "targetType": "java", - }, - { - "code": "UseUtilityClass", - "column": "18", - "file": "test_data/hello.in.java", - "issueClass": "ISSUE_CLASS_EXISTING", - "level": "LEVEL_HIGH", - "line": "3", - "linter": "pmd", - "message": "All methods are static. Consider using a utility class instead. Alternatively, you could add a private constructor or make the class abstract to silence this warning.", - "ranges": [ - { - "filePath": "test_data/hello.in.java", - "length": "99", - "offset": "40", - }, - ], - "targetType": "java", - }, - ], - "lintActions": [ - { - "command": "lint-java", - "fileGroupName": "java", - "linter": "pmd", - "paths": [ - "test_data/hello.in.java", - ], - "verb": "TRUNK_VERB_CHECK", - }, - { - "command": "lint-java", - "fileGroupName": "java", - "linter": "pmd", - "paths": [ - "test_data/hello.in.java", - ], - "upstream": true, - "verb": "TRUNK_VERB_CHECK", - }, - ], - "taskFailures": [], - "unformattedFiles": [], -} -`; diff --git a/linters/pmd/test_data/pmd_v7.0.0_CUSTOM.check.shot b/linters/pmd/test_data/pmd_v7.0.0_CUSTOM.check.shot new file mode 100644 index 000000000..bed649a29 --- /dev/null +++ b/linters/pmd/test_data/pmd_v7.0.0_CUSTOM.check.shot @@ -0,0 +1,140 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Testing linter pmd test CUSTOM 1`] = ` +{ + "issues": [ + { + "code": "ApexDoc", + "column": "8", + "file": "test_data/apex.in.cls", + "issueClass": "ISSUE_CLASS_EXISTING", + "level": "LEVEL_HIGH", + "line": "1", + "linter": "pmd", + "message": "Missing ApexDoc comment", + "ranges": [ + { + "filePath": "test_data/apex.in.cls", + "length": "69", + "offset": "7", + }, + ], + "targetType": "apex", + }, + { + "code": "AvoidGlobalModifier", + "column": "8", + "file": "test_data/apex.in.cls", + "issueClass": "ISSUE_CLASS_EXISTING", + "level": "LEVEL_HIGH", + "line": "1", + "linter": "pmd", + "message": "Avoid using global modifier", + "ranges": [ + { + "filePath": "test_data/apex.in.cls", + "length": "69", + "offset": "7", + }, + ], + "targetType": "apex", + }, + { + "code": "ApexDoc", + "column": "8", + "file": "test_data/apex.in.cls", + "issueClass": "ISSUE_CLASS_EXISTING", + "level": "LEVEL_HIGH", + "line": "2", + "linter": "pmd", + "message": "Missing ApexDoc comment", + "ranges": [ + { + "filePath": "test_data/apex.in.cls", + "length": "41", + "offset": "33", + }, + ], + "targetType": "apex", + }, + { + "code": "NoPackage", + "column": "1", + "file": "test_data/hello.in.java", + "issueClass": "ISSUE_CLASS_EXISTING", + "level": "LEVEL_HIGH", + "line": "3", + "linter": "pmd", + "message": "All classes, interfaces, enums and annotations must belong to a named package", + "ranges": [ + { + "filePath": "test_data/hello.in.java", + "length": "5", + "offset": "23", + }, + ], + "targetType": "java", + }, + { + "code": "UseUtilityClass", + "column": "1", + "file": "test_data/hello.in.java", + "issueClass": "ISSUE_CLASS_EXISTING", + "level": "LEVEL_HIGH", + "line": "3", + "linter": "pmd", + "message": "This utility class has a non-private constructor", + "ranges": [ + { + "filePath": "test_data/hello.in.java", + "length": "5", + "offset": "23", + }, + ], + "targetType": "java", + }, + ], + "lintActions": [ + { + "command": "lint-apex", + "fileGroupName": "apex", + "linter": "pmd", + "paths": [ + "test_data/apex.in.cls", + ], + "verb": "TRUNK_VERB_CHECK", + }, + { + "command": "lint-apex", + "fileGroupName": "apex", + "linter": "pmd", + "paths": [ + "test_data/apex.in.cls", + ], + "upstream": true, + "verb": "TRUNK_VERB_CHECK", + }, + { + "command": "lint-java", + "fileGroupName": "java", + "linter": "pmd", + "paths": [ + "test_data/hello.in.java", + ], + "verb": "TRUNK_VERB_CHECK", + }, + { + "command": "lint-java", + "fileGroupName": "java", + "linter": "pmd", + "paths": [ + "test_data/hello.in.java", + ], + "upstream": true, + "verb": "TRUNK_VERB_CHECK", + }, + ], + "taskFailures": [], + "unformattedFiles": [], +} +`; diff --git a/linters/pragma-once/plugin.yaml b/linters/pragma-once/plugin.yaml index 249af1a37..b4e65c0c5 100644 --- a/linters/pragma-once/plugin.yaml +++ b/linters/pragma-once/plugin.yaml @@ -4,6 +4,7 @@ lint: # Inserts "#pragma once" if it wasn't there - name: pragma-once files: [c-header, c++-header] + description: Enforces "#pragma once" in header files commands: - name: format platforms: [windows] diff --git a/linters/pre-commit-hooks/plugin.yaml b/linters/pre-commit-hooks/plugin.yaml index 1dcc86fd7..49b60027c 100644 --- a/linters/pre-commit-hooks/plugin.yaml +++ b/linters/pre-commit-hooks/plugin.yaml @@ -5,6 +5,7 @@ lint: known_good_version: 4.4.0 runtime: python package: pre-commit-hooks + description: A collection of pre-commit tools for Python suggest_if: never environment: - name: PATH diff --git a/linters/prettier/plugin.yaml b/linters/prettier/plugin.yaml index f0507aede..f01f16da8 100644 --- a/linters/prettier/plugin.yaml +++ b/linters/prettier/plugin.yaml @@ -13,6 +13,7 @@ lint: - typescript - yaml - css + - postcss - sass - html - markdown @@ -20,6 +21,7 @@ lint: - javascript - graphql - prettier_supported_configs + description: A universal formatter commands: - name: format output: sarif diff --git a/linters/prisma/plugin.yaml b/linters/prisma/plugin.yaml index 1aceb385f..1b1ee5a48 100644 --- a/linters/prisma/plugin.yaml +++ b/linters/prisma/plugin.yaml @@ -6,6 +6,7 @@ lint: files: [prisma] known_good_version: 4.16.1 suggest_if: never + description: A Prisma formatter commands: - name: format platforms: [windows] diff --git a/linters/psscriptanalyzer/plugin.yaml b/linters/psscriptanalyzer/plugin.yaml index 3b47d1091..712730a33 100644 --- a/linters/psscriptanalyzer/plugin.yaml +++ b/linters/psscriptanalyzer/plugin.yaml @@ -30,6 +30,7 @@ lint: files: [powershell] main_tool: psscriptanalyzer tools: [converttosarif, pwsh] + description: Linter for PowerShell scripts commands: - name: Invoke-ScriptAnalyzer run: pwsh -f ${cwd}/lint.ps1 -FilePath ${target} -OutputPath ${tmpfile} diff --git a/linters/pylint/plugin.yaml b/linters/pylint/plugin.yaml index fa6163105..def3cfe4b 100644 --- a/linters/pylint/plugin.yaml +++ b/linters/pylint/plugin.yaml @@ -10,6 +10,7 @@ lint: definitions: - name: pylint files: [python] + description: Static code analysis for Python commands: - name: lint # Custom parser type defined in the trunk cli to handle pylint's JSON output. diff --git a/linters/pyright/plugin.yaml b/linters/pyright/plugin.yaml index c317b4fba..9939a4d07 100644 --- a/linters/pyright/plugin.yaml +++ b/linters/pyright/plugin.yaml @@ -11,6 +11,7 @@ lint: - name: pyright files: [python] suggest_if: config_present + description: Static type checker for Python commands: - name: lint output: sarif diff --git a/linters/pyright/test_data/pyright_v1.1.348_basic.check.shot b/linters/pyright/test_data/pyright_v1.1.348_basic.check.shot index 578bd08c6..add5d7bf5 100644 --- a/linters/pyright/test_data/pyright_v1.1.348_basic.check.shot +++ b/linters/pyright/test_data/pyright_v1.1.348_basic.check.shot @@ -1,5 +1,4 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -// trunk-upgrade-validation:RELEASE exports[`Testing linter pyright test basic 1`] = ` { diff --git a/linters/pyright/test_data/pyright_v1.1.359_basic.check.shot b/linters/pyright/test_data/pyright_v1.1.359_basic.check.shot new file mode 100644 index 000000000..ca818b2ac --- /dev/null +++ b/linters/pyright/test_data/pyright_v1.1.359_basic.check.shot @@ -0,0 +1,226 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP +// trunk-upgrade-validation:RELEASE + +exports[`Testing linter pyright test basic 1`] = ` +{ + "issues": [ + { + "code": "reportAttributeAccessIssue", + "column": "57", + "file": "test_data/basic.in.py", + "issueClass": "ISSUE_CLASS_EXISTING", + "issueUrl": "https://github.com/microsoft/pyright/blob/main/docs/configuration.md#reportAttributeAccessIssue", + "level": "LEVEL_HIGH", + "line": "1", + "linter": "pyright", + "message": ""Enum" is unknown import symbol", + "ranges": [ + { + "filePath": "test_data/basic.in.py", + "length": "4", + "offset": "56", + }, + ], + "targetType": "python", + }, + { + "column": "13", + "file": "test_data/basic.in.py", + "issueClass": "ISSUE_CLASS_EXISTING", + "issueUrl": "https://github.com/microsoft/pyright/blob/main/docs/configuration.md#", + "level": "LEVEL_LOW", + "line": "15", + "linter": "pyright", + "message": "Type of "a.x" is "int | str"", + "ranges": [ + { + "filePath": "test_data/basic.in.py", + "length": "3", + "offset": "384", + }, + ], + "targetType": "python", + }, + { + "code": "reportAttributeAccessIssue", + "column": "3", + "file": "test_data/basic.in.py", + "issueClass": "ISSUE_CLASS_EXISTING", + "issueUrl": "https://github.com/microsoft/pyright/blob/main/docs/configuration.md#reportAttributeAccessIssue", + "level": "LEVEL_HIGH", + "line": "18", + "linter": "pyright", + "message": "Cannot assign to attribute "x" for class "A" +  Expression of type "float" cannot be assigned to attribute "x" of class "A" +    Type "float" is incompatible with type "int | str" +      "float" is incompatible with "int" +      "float" is incompatible with "str"", + "ranges": [ + { + "filePath": "test_data/basic.in.py", + "length": "1", + "offset": "462", + }, + ], + "targetType": "python", + }, + { + "code": "reportUndefinedVariable", + "column": "8", + "file": "test_data/basic.in.py", + "issueClass": "ISSUE_CLASS_EXISTING", + "issueUrl": "https://github.com/microsoft/pyright/blob/main/docs/configuration.md#reportUndefinedVariable", + "level": "LEVEL_HIGH", + "line": "24", + "linter": "pyright", + "message": ""ClassVar" is not defined", + "ranges": [ + { + "filePath": "test_data/basic.in.py", + "length": "8", + "offset": "602", + }, + ], + "targetType": "python", + }, + { + "code": "reportAttributeAccessIssue", + "column": "9", + "file": "test_data/basic.in.py", + "issueClass": "ISSUE_CLASS_EXISTING", + "issueUrl": "https://github.com/microsoft/pyright/blob/main/docs/configuration.md#reportAttributeAccessIssue", + "level": "LEVEL_HIGH", + "line": "31", + "linter": "pyright", + "message": "Cannot access attribute "z" for class "type[A]" +  Attribute "z" is unknown", + "ranges": [ + { + "filePath": "test_data/basic.in.py", + "length": "1", + "offset": "742", + }, + ], + "targetType": "python", + }, + { + "code": "reportReturnType", + "column": "29", + "file": "test_data/basic.in.py", + "issueClass": "ISSUE_CLASS_EXISTING", + "issueUrl": "https://github.com/microsoft/pyright/blob/main/docs/configuration.md#reportReturnType", + "level": "LEVEL_HIGH", + "line": "39", + "linter": "pyright", + "message": "Function with declared return type "bool" must return value on all code paths +  "None" is incompatible with "bool"", + "ranges": [ + { + "filePath": "test_data/basic.in.py", + "length": "4", + "offset": "864", + }, + ], + "targetType": "python", + }, + { + "code": "reportReturnType", + "column": "12", + "file": "test_data/basic.in.py", + "issueClass": "ISSUE_CLASS_EXISTING", + "issueUrl": "https://github.com/microsoft/pyright/blob/main/docs/configuration.md#reportReturnType", + "level": "LEVEL_HIGH", + "line": "5", + "linter": "pyright", + "message": "Expression of type "int" is incompatible with return type "str" +  "int" is incompatible with "str"", + "ranges": [ + { + "filePath": "test_data/basic.in.py", + "length": "1", + "offset": "105", + }, + ], + "targetType": "python", + }, + { + "column": "25", + "file": "test_data/basic.in.py", + "issueClass": "ISSUE_CLASS_EXISTING", + "issueUrl": "https://github.com/microsoft/pyright/blob/main/docs/configuration.md#", + "level": "LEVEL_LOW", + "line": "51", + "linter": "pyright", + "message": "Type of "val" is "int"", + "ranges": [ + { + "filePath": "test_data/basic.in.py", + "length": "3", + "offset": "1128", + }, + ], + "targetType": "python", + }, + { + "column": "39", + "file": "test_data/basic.in.py", + "issueClass": "ISSUE_CLASS_EXISTING", + "issueUrl": "https://github.com/microsoft/pyright/blob/main/docs/configuration.md#", + "level": "LEVEL_LOW", + "line": "54", + "linter": "pyright", + "message": "Type of "val" is "int"", + "ranges": [ + { + "filePath": "test_data/basic.in.py", + "length": "3", + "offset": "1244", + }, + ], + "targetType": "python", + }, + { + "code": "reportRedeclaration", + "column": "7", + "file": "test_data/basic.in.py", + "issueClass": "ISSUE_CLASS_EXISTING", + "issueUrl": "https://github.com/microsoft/pyright/blob/main/docs/configuration.md#reportRedeclaration", + "level": "LEVEL_HIGH", + "line": "7", + "linter": "pyright", + "message": "Class declaration "A" is obscured by a declaration of the same name", + "ranges": [ + { + "filePath": "test_data/basic.in.py", + "length": "1", + "offset": "183", + }, + ], + "targetType": "python", + }, + ], + "lintActions": [ + { + "command": "lint", + "fileGroupName": "python", + "linter": "pyright", + "paths": [ + "test_data/basic.in.py", + ], + "verb": "TRUNK_VERB_CHECK", + }, + { + "command": "lint", + "fileGroupName": "python", + "linter": "pyright", + "paths": [ + "test_data/basic.in.py", + ], + "upstream": true, + "verb": "TRUNK_VERB_CHECK", + }, + ], + "taskFailures": [], + "unformattedFiles": [], +} +`; diff --git a/linters/regal/plugin.yaml b/linters/regal/plugin.yaml index 767f9c10d..ff0dfc4f1 100644 --- a/linters/regal/plugin.yaml +++ b/linters/regal/plugin.yaml @@ -27,6 +27,7 @@ lint: main_tool: regal known_good_version: 0.18.0 suggest_if: config_present + description: Linter for Rego files direct_configs: - .regal/config.yaml commands: diff --git a/linters/regal/test_data/regal_v0.21.0_basic.check.shot b/linters/regal/test_data/regal_v0.21.0_basic.check.shot new file mode 100644 index 000000000..1eeb83fbf --- /dev/null +++ b/linters/regal/test_data/regal_v0.21.0_basic.check.shot @@ -0,0 +1,75 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Testing linter regal test basic 1`] = ` +{ + "issues": [ + { + "code": "opa-fmt", + "column": "1", + "file": "test_data/basic.in.rego", + "issueClass": "ISSUE_CLASS_EXISTING", + "level": "LEVEL_HIGH", + "line": "1", + "linter": "regal", + "message": "File should be formatted with \`opa fmt\`", + "targetType": "rego", + }, + { + "code": "prefer-snake-case", + "column": "1", + "file": "test_data/basic.in.rego", + "issueClass": "ISSUE_CLASS_EXISTING", + "level": "LEVEL_HIGH", + "line": "12", + "linter": "regal", + "message": "Prefer snake_case for names", + "targetType": "rego", + }, + { + "code": "non-raw-regex-pattern", + "column": "27", + "file": "test_data/basic.in.rego", + "issueClass": "ISSUE_CLASS_EXISTING", + "level": "LEVEL_HIGH", + "line": "12", + "linter": "regal", + "message": "Use raw strings for regex patterns", + "targetType": "rego", + }, + { + "code": "use-assignment-operator", + "column": "15", + "file": "test_data/basic.in.rego", + "issueClass": "ISSUE_CLASS_EXISTING", + "level": "LEVEL_HIGH", + "line": "5", + "linter": "regal", + "message": "Prefer := over = for assignment", + "targetType": "rego", + }, + ], + "lintActions": [ + { + "command": "lint", + "fileGroupName": "rego", + "linter": "regal", + "paths": [ + "test_data/basic.in.rego", + ], + "verb": "TRUNK_VERB_CHECK", + }, + { + "command": "lint", + "fileGroupName": "rego", + "linter": "regal", + "paths": [ + "test_data/basic.in.rego", + ], + "upstream": true, + "verb": "TRUNK_VERB_CHECK", + }, + ], + "taskFailures": [], + "unformattedFiles": [], +} +`; diff --git a/linters/remark-lint/plugin.yaml b/linters/remark-lint/plugin.yaml index 250cbd66e..3f91593e4 100644 --- a/linters/remark-lint/plugin.yaml +++ b/linters/remark-lint/plugin.yaml @@ -4,6 +4,7 @@ lint: - name: remark-lint supported_platforms: [linux, macos] files: [markdown] + description: A markdown linter and formatter package: remark-cli extra_packages: - remark-preset-lint-consistent diff --git a/linters/remark-lint/test_data/remark_lint_v11.0.0_basic.check.shot b/linters/remark-lint/test_data/remark_lint_v11.0.0_basic.check.shot index 61d64ba93..77a9f4921 100644 --- a/linters/remark-lint/test_data/remark_lint_v11.0.0_basic.check.shot +++ b/linters/remark-lint/test_data/remark_lint_v11.0.0_basic.check.shot @@ -5,13 +5,24 @@ exports[`Testing linter remark-lint test basic 1`] = ` "issues": [ { "code": "list-item-indent", - "column": "4", + "column": "1", + "file": "test_data/basic.in.md", + "issueClass": "ISSUE_CLASS_EXISTING", + "level": "LEVEL_HIGH", + "line": "1", + "linter": "remark-lint", + "message": "Unexpected \`2\` spaces between list item marker and content, expected \`1\` space, remove \`1\` space", + "targetType": "markdown", + }, + { + "code": "list-item-indent", + "column": "1", "file": "test_data/basic.in.md", "issueClass": "ISSUE_CLASS_EXISTING", "level": "LEVEL_HIGH", "line": "1", "linter": "remark-lint", - "message": "Incorrect list-item indent: add 1 space", + "message": "Unexpected \`3\` spaces between list item marker and content, expected \`1\` space, remove \`2\` spaces", "targetType": "markdown", }, ], diff --git a/linters/remark-lint/test_data/remark_lint_v12.0.0_basic.check.shot b/linters/remark-lint/test_data/remark_lint_v12.0.0_basic.check.shot index 61d64ba93..ecff80f23 100644 --- a/linters/remark-lint/test_data/remark_lint_v12.0.0_basic.check.shot +++ b/linters/remark-lint/test_data/remark_lint_v12.0.0_basic.check.shot @@ -11,7 +11,18 @@ exports[`Testing linter remark-lint test basic 1`] = ` "level": "LEVEL_HIGH", "line": "1", "linter": "remark-lint", - "message": "Incorrect list-item indent: add 1 space", + "message": "Unexpected \`2\` spaces between list item marker and content, expected \`1\` space, remove \`1\` space", + "targetType": "markdown", + }, + { + "code": "list-item-indent", + "column": "5", + "file": "test_data/basic.in.md", + "issueClass": "ISSUE_CLASS_EXISTING", + "level": "LEVEL_HIGH", + "line": "4", + "linter": "remark-lint", + "message": "Unexpected \`3\` spaces between list item marker and content, expected \`1\` space, remove \`2\` spaces", "targetType": "markdown", }, ], diff --git a/linters/renovate/plugin.yaml b/linters/renovate/plugin.yaml index d61bbcefb..f3b7d5b62 100644 --- a/linters/renovate/plugin.yaml +++ b/linters/renovate/plugin.yaml @@ -11,6 +11,7 @@ lint: - name: renovate files: [renovate-config] tools: [renovate] + description: Validates Renovate configuration files commands: - name: validate platforms: [windows] diff --git a/linters/renovate/renovate.test.ts b/linters/renovate/renovate.test.ts index 5ec5f1d94..d64ff51df 100644 --- a/linters/renovate/renovate.test.ts +++ b/linters/renovate/renovate.test.ts @@ -1,7 +1,7 @@ import { customLinterCheckTest } from "tests"; import { osTimeoutMultiplier, TEST_DATA } from "tests/utils"; -jest.setTimeout(600000 * osTimeoutMultiplier); // 300s or 900s +jest.setTimeout(600000 * osTimeoutMultiplier); customLinterCheckTest({ linterName: "renovate", diff --git a/linters/rome/plugin.yaml b/linters/rome/plugin.yaml index 6b7b6baa3..46ece471b 100644 --- a/linters/rome/plugin.yaml +++ b/linters/rome/plugin.yaml @@ -10,6 +10,7 @@ lint: definitions: # No longer maintained. Succeeded by the biome linter+formatter - name: rome + description: A static analyzer for web projects files: - typescript - javascript diff --git a/linters/rubocop/plugin.yaml b/linters/rubocop/plugin.yaml index 430a444af..5c449bbd1 100644 --- a/linters/rubocop/plugin.yaml +++ b/linters/rubocop/plugin.yaml @@ -2,6 +2,7 @@ version: 0.1 lint: definitions: - name: rubocop + description: A Ruby static code analyzer and formatter files: [ruby, gemspec] direct_configs: [.rubocop.yml] suggest_if: config_present diff --git a/linters/rubocop/rubocop.test.ts b/linters/rubocop/rubocop.test.ts index 5a417b719..861f59784 100644 --- a/linters/rubocop/rubocop.test.ts +++ b/linters/rubocop/rubocop.test.ts @@ -5,7 +5,7 @@ import { osTimeoutMultiplier, skipOS, TEST_DATA } from "tests/utils"; // Note that the first-time ruby/rufo download can sometimes take a while. // Ruby build is quite slow on Mac, so only run tests on linux for now -jest.setTimeout(600000 * osTimeoutMultiplier); // 300s or 900s +jest.setTimeout(600000 * osTimeoutMultiplier); const preCheck = (driver: TrunkLintDriver) => { if (process.platform == "win32") { diff --git a/linters/ruff/plugin.yaml b/linters/ruff/plugin.yaml index e74775f4b..ad2d5b9ad 100644 --- a/linters/ruff/plugin.yaml +++ b/linters/ruff/plugin.yaml @@ -9,7 +9,8 @@ tools: lint: definitions: - name: ruff - files: [python] + files: [python, python-interface] + description: A Python linter and formatter commands: - name: lint # As of ruff v0.1.0, --format is replaced with --output-format diff --git a/linters/ruff/ruff.test.ts b/linters/ruff/ruff.test.ts index bd322b90f..253490de7 100644 --- a/linters/ruff/ruff.test.ts +++ b/linters/ruff/ruff.test.ts @@ -2,7 +2,7 @@ import { linterCheckTest, linterFmtTest } from "tests"; import { TrunkLintDriver } from "tests/driver"; import { skipOS } from "tests/utils"; -linterCheckTest({ linterName: "ruff", namedTestPrefixes: ["basic"] }); +linterCheckTest({ linterName: "ruff", namedTestPrefixes: ["basic", "interface"] }); // ruff-nbqa still runs correctly on Windows, but the diagnostics are slightly different from the assertions. linterCheckTest({ diff --git a/linters/ruff/test_data/interface.in.pyi b/linters/ruff/test_data/interface.in.pyi new file mode 100644 index 000000000..ac27d5d56 --- /dev/null +++ b/linters/ruff/test_data/interface.in.pyi @@ -0,0 +1,51 @@ +# Based on test file input from astral-sh/ruff +import json + +from typing import Any, Sequence + +class MissingCommand(TypeError): ... +class AnoherClass: ... + +def a(): ... + +@overload +def a(arg: int): ... + +@overload +def a(arg: int, name: str): ... + + +def grouped1(): ... +def grouped2(): ... +def grouped3( ): ... + + +class BackendProxy: + backend_module: str + backend_object: str | None + backend: Any + + def grouped1(): ... + def grouped2(): ... + def grouped3( ): ... + @decorated + + def with_blank_line(): ... + + + def ungrouped(): ... +a = "test" + +def function_def(): + pass +b = "test" + + +def outer(): + def inner(): + pass + def inner2(): + pass + +class Foo: ... +class Bar: ... diff --git a/linters/ruff/test_data/ruff_v0.0.250_interface.check.shot b/linters/ruff/test_data/ruff_v0.0.250_interface.check.shot new file mode 100644 index 000000000..2df3cf57b --- /dev/null +++ b/linters/ruff/test_data/ruff_v0.0.250_interface.check.shot @@ -0,0 +1,208 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Testing linter ruff test interface 1`] = ` +{ + "issues": [ + { + "code": "F821", + "column": "2", + "file": "test_data/interface.in.pyi", + "issueClass": "ISSUE_CLASS_EXISTING", + "issueUrl": "https://docs.astral.sh/ruff/rules/#F821", + "level": "LEVEL_HIGH", + "line": "11", + "linter": "ruff", + "message": "Undefined name \`overload\`", + "ranges": [ + { + "filePath": "test_data/interface.in.pyi", + "length": "8", + "offset": "170", + }, + ], + "targetType": "python-interface", + }, + { + "code": "F811", + "column": "5", + "file": "test_data/interface.in.pyi", + "issueClass": "ISSUE_CLASS_EXISTING", + "issueUrl": "https://docs.astral.sh/ruff/rules/#F811", + "level": "LEVEL_HIGH", + "line": "12", + "linter": "ruff", + "message": "Redefinition of unused \`a\` from line 9", + "ranges": [ + { + "filePath": "test_data/interface.in.pyi", + "length": "1", + "offset": "183", + }, + ], + "targetType": "python-interface", + }, + { + "code": "F821", + "column": "2", + "file": "test_data/interface.in.pyi", + "issueClass": "ISSUE_CLASS_EXISTING", + "issueUrl": "https://docs.astral.sh/ruff/rules/#F821", + "level": "LEVEL_HIGH", + "line": "14", + "linter": "ruff", + "message": "Undefined name \`overload\`", + "ranges": [ + { + "filePath": "test_data/interface.in.pyi", + "length": "8", + "offset": "202", + }, + ], + "targetType": "python-interface", + }, + { + "code": "F811", + "column": "5", + "file": "test_data/interface.in.pyi", + "issueClass": "ISSUE_CLASS_EXISTING", + "issueUrl": "https://docs.astral.sh/ruff/rules/#F811", + "level": "LEVEL_HIGH", + "line": "15", + "linter": "ruff", + "message": "Redefinition of unused \`a\` from line 12", + "ranges": [ + { + "filePath": "test_data/interface.in.pyi", + "length": "1", + "offset": "215", + }, + ], + "targetType": "python-interface", + }, + { + "autofixOptions": [ + { + "message": "Remove unused import: \`json\`", + "replacements": [ + { + "filePath": "test_data/interface.in.pyi", + "length": "12", + "offset": "47", + }, + ], + }, + ], + "code": "F401", + "column": "8", + "file": "test_data/interface.in.pyi", + "issueClass": "ISSUE_CLASS_EXISTING", + "issueUrl": "https://docs.astral.sh/ruff/rules/#F401", + "level": "LEVEL_HIGH", + "line": "2", + "linter": "ruff", + "message": "\`json\` imported but unused", + "ranges": [ + { + "filePath": "test_data/interface.in.pyi", + "length": "4", + "offset": "54", + }, + ], + "targetType": "python-interface", + }, + { + "code": "F821", + "column": "6", + "file": "test_data/interface.in.pyi", + "issueClass": "ISSUE_CLASS_EXISTING", + "issueUrl": "https://docs.astral.sh/ruff/rules/#F821", + "level": "LEVEL_HIGH", + "line": "31", + "linter": "ruff", + "message": "Undefined name \`decorated\`", + "ranges": [ + { + "filePath": "test_data/interface.in.pyi", + "length": "9", + "offset": "479", + }, + ], + "targetType": "python-interface", + }, + { + "code": "F811", + "column": "1", + "file": "test_data/interface.in.pyi", + "issueClass": "ISSUE_CLASS_EXISTING", + "issueUrl": "https://docs.astral.sh/ruff/rules/#F811", + "level": "LEVEL_HIGH", + "line": "37", + "linter": "ruff", + "message": "Redefinition of unused \`a\` from line 15", + "ranges": [ + { + "filePath": "test_data/interface.in.pyi", + "length": "1", + "offset": "548", + }, + ], + "targetType": "python-interface", + }, + { + "autofixOptions": [ + { + "message": "Remove unused import: \`typing.Sequence\`", + "replacements": [ + { + "filePath": "test_data/interface.in.pyi", + "length": "32", + "offset": "60", + "replacementText": "from typing import Any", + }, + ], + }, + ], + "code": "F401", + "column": "25", + "file": "test_data/interface.in.pyi", + "issueClass": "ISSUE_CLASS_EXISTING", + "issueUrl": "https://docs.astral.sh/ruff/rules/#F401", + "level": "LEVEL_HIGH", + "line": "4", + "linter": "ruff", + "message": "\`typing.Sequence\` imported but unused", + "ranges": [ + { + "filePath": "test_data/interface.in.pyi", + "length": "8", + "offset": "84", + }, + ], + "targetType": "python-interface", + }, + ], + "lintActions": [ + { + "command": "lint", + "fileGroupName": "python-interface", + "linter": "ruff", + "paths": [ + "test_data/interface.in.pyi", + ], + "verb": "TRUNK_VERB_CHECK", + }, + { + "command": "lint", + "fileGroupName": "python-interface", + "linter": "ruff", + "paths": [ + "test_data/interface.in.pyi", + ], + "upstream": true, + "verb": "TRUNK_VERB_CHECK", + }, + ], + "taskFailures": [], + "unformattedFiles": [], +} +`; diff --git a/linters/rufo/plugin.yaml b/linters/rufo/plugin.yaml index 9fb8a3875..053810ab4 100644 --- a/linters/rufo/plugin.yaml +++ b/linters/rufo/plugin.yaml @@ -10,6 +10,7 @@ lint: definitions: - name: rufo files: [ruby] + description: A Ruby formatter commands: - name: format output: rewrite diff --git a/linters/rufo/rufo.test.ts b/linters/rufo/rufo.test.ts index ab5e1e8fb..dc5b57c94 100644 --- a/linters/rufo/rufo.test.ts +++ b/linters/rufo/rufo.test.ts @@ -4,7 +4,7 @@ import { osTimeoutMultiplier, skipOS, TEST_DATA } from "tests/utils"; // Note that the first-time ruby/rufo download can sometimes take a while. // Ruby build is quite slow on Mac, so only run tests on linux for now -jest.setTimeout(600000 * osTimeoutMultiplier); // 300s or 900s +jest.setTimeout(600000 * osTimeoutMultiplier); // Rufo succeeds on empty files customLinterCheckTest({ diff --git a/linters/rustfmt/plugin.yaml b/linters/rustfmt/plugin.yaml index b3408ebde..dca9105b1 100644 --- a/linters/rustfmt/plugin.yaml +++ b/linters/rustfmt/plugin.yaml @@ -4,6 +4,7 @@ lint: - name: rustfmt files: [rust] download: rust + description: A Rust formatter commands: - name: format output: rewrite diff --git a/linters/scalafmt/plugin.yaml b/linters/scalafmt/plugin.yaml index 2f4c47a0e..a1ce10dcb 100644 --- a/linters/scalafmt/plugin.yaml +++ b/linters/scalafmt/plugin.yaml @@ -28,6 +28,7 @@ lint: tools: [scalafmt] direct_configs: [.scalafmt.conf] suggest_if: config_present + description: A Scala formatter commands: - name: format output: rewrite diff --git a/linters/semgrep/plugin.yaml b/linters/semgrep/plugin.yaml index cd752a03d..9a0af399a 100644 --- a/linters/semgrep/plugin.yaml +++ b/linters/semgrep/plugin.yaml @@ -9,6 +9,7 @@ tools: lint: definitions: - name: semgrep + description: Find bugs and enforce code standards supported_platforms: [linux, macos] files: [ALL] tools: [semgrep] diff --git a/linters/shellcheck/plugin.yaml b/linters/shellcheck/plugin.yaml index fea586b63..712e96ccf 100644 --- a/linters/shellcheck/plugin.yaml +++ b/linters/shellcheck/plugin.yaml @@ -31,6 +31,7 @@ lint: - name: shellcheck files: [shell] tools: [shellcheck] + description: Finds bugs in your shell scripts commands: - name: lint # Custom parser type defined in the trunk cli to handle rubocop's JSON output. diff --git a/linters/shfmt/plugin.yaml b/linters/shfmt/plugin.yaml index f0004aba8..efbb30e64 100644 --- a/linters/shfmt/plugin.yaml +++ b/linters/shfmt/plugin.yaml @@ -11,6 +11,7 @@ lint: definitions: - name: shfmt files: [shell] + description: A shell formatter commands: - name: format output: shfmt diff --git a/linters/sourcery/plugin.yaml b/linters/sourcery/plugin.yaml index cd0646c2e..9f83d313f 100644 --- a/linters/sourcery/plugin.yaml +++ b/linters/sourcery/plugin.yaml @@ -3,6 +3,7 @@ lint: definitions: - name: sourcery files: [python] + description: Static analyzer for Python commands: - name: lint platforms: [linux, macos] diff --git a/linters/sql-formatter/plugin.yaml b/linters/sql-formatter/plugin.yaml index ec5de1e85..0c7424b09 100644 --- a/linters/sql-formatter/plugin.yaml +++ b/linters/sql-formatter/plugin.yaml @@ -10,6 +10,7 @@ lint: definitions: - name: sql-formatter files: [sql] + description: A SQL formatter commands: - output: rewrite # sql-formatter does not autodetect dialect, so this may not be sufficient for all setups diff --git a/linters/sqlfluff/plugin.yaml b/linters/sqlfluff/plugin.yaml index f4a7a12d3..139725a2c 100644 --- a/linters/sqlfluff/plugin.yaml +++ b/linters/sqlfluff/plugin.yaml @@ -11,6 +11,7 @@ lint: - name: sqlfluff files: [sql, sql-j2, dml, ddl] tools: [sqlfluff] + description: A dialect-flexible and configurable SQL linter known_good_version: 1.4.5 direct_configs: - .sqlfluff diff --git a/linters/sqlfmt/plugin.yaml b/linters/sqlfmt/plugin.yaml index a3cffcaac..8a62627e0 100644 --- a/linters/sqlfmt/plugin.yaml +++ b/linters/sqlfmt/plugin.yaml @@ -11,6 +11,7 @@ lint: - name: sqlfmt files: [sql, sql-j2] tools: [sqlfmt] + description: A SQL formatter known_good_version: 0.16.0 # trunk-ignore(yamllint/quoted-strings): see https://github.com/adrienverge/yamllint/issues/516 extra_packages: ["shandy-sqlfmt[jinjafmt]"] diff --git a/linters/standardrb/plugin.yaml b/linters/standardrb/plugin.yaml index e6ba71d25..d1efd3723 100644 --- a/linters/standardrb/plugin.yaml +++ b/linters/standardrb/plugin.yaml @@ -10,6 +10,7 @@ lint: definitions: - name: standardrb files: [ruby, gemspec] + description: Ruby's bikeshed-proof linter and formatter commands: - name: lint # Custom parser type defined in the trunk cli to handle rubocop's JSON output. diff --git a/linters/standardrb/standardrb.test.ts b/linters/standardrb/standardrb.test.ts index 6d6abc5e4..bf5069d1f 100644 --- a/linters/standardrb/standardrb.test.ts +++ b/linters/standardrb/standardrb.test.ts @@ -4,7 +4,7 @@ import { osTimeoutMultiplier, skipOS } from "tests/utils"; // Note that the first-time ruby/rufo download can sometimes take a while. // Ruby build is quite slow on Mac, so only run tests on linux for now -jest.setTimeout(600000 * osTimeoutMultiplier); // 300s or 900s +jest.setTimeout(600000 * osTimeoutMultiplier); const preCheck = (driver: TrunkLintDriver) => { if (process.platform == "win32") { diff --git a/linters/stringslint/plugin.yaml b/linters/stringslint/plugin.yaml index 2bcdb5fd2..b4f5d7123 100644 --- a/linters/stringslint/plugin.yaml +++ b/linters/stringslint/plugin.yaml @@ -23,6 +23,7 @@ lint: - xib - storyboard tools: [stringslint] + description: Ensures localized strings are complete and never unused commands: - name: lint output: regex diff --git a/linters/stylelint/plugin.yaml b/linters/stylelint/plugin.yaml index a1c18ab6e..d33e7640d 100644 --- a/linters/stylelint/plugin.yaml +++ b/linters/stylelint/plugin.yaml @@ -11,6 +11,7 @@ lint: - name: stylelint files: [css, sass] tools: [stylelint] + description: Over 100 built-in rules for modern CSS commands: - name: lint version: ">=16.0.0" diff --git a/linters/stylua/plugin.yaml b/linters/stylua/plugin.yaml index 5089789eb..9e84c4cae 100644 --- a/linters/stylua/plugin.yaml +++ b/linters/stylua/plugin.yaml @@ -22,6 +22,7 @@ lint: - name: stylua files: [lua] tools: [stylua] + description: An opinionated Lua formatter commands: - name: format output: rewrite diff --git a/linters/svgo/plugin.yaml b/linters/svgo/plugin.yaml index 7f9f2aa8f..e735fd124 100644 --- a/linters/svgo/plugin.yaml +++ b/linters/svgo/plugin.yaml @@ -11,6 +11,7 @@ lint: # while svgo could be a formatter, it is optimizing, not formatting, so it's more intuitive to run on `trunk check` - name: svgo files: [svg] + description: Optimize SVG files commands: - name: fmt output: rewrite diff --git a/linters/swiftformat/plugin.yaml b/linters/swiftformat/plugin.yaml index 0277ae183..0b42f6429 100644 --- a/linters/swiftformat/plugin.yaml +++ b/linters/swiftformat/plugin.yaml @@ -17,6 +17,7 @@ lint: - name: swiftformat files: [swift] tools: [swiftformat] + description: Formatter for Swift commands: - name: format output: rewrite diff --git a/linters/swiftlint/plugin.yaml b/linters/swiftlint/plugin.yaml index a5b462798..4191c696f 100644 --- a/linters/swiftlint/plugin.yaml +++ b/linters/swiftlint/plugin.yaml @@ -15,6 +15,7 @@ tools: lint: definitions: - name: swiftlint + description: Enforces Swift style and conventions files: - swift tools: [swiftlint] diff --git a/linters/taplo/plugin.yaml b/linters/taplo/plugin.yaml index 389fa5b86..06742af7a 100644 --- a/linters/taplo/plugin.yaml +++ b/linters/taplo/plugin.yaml @@ -79,6 +79,7 @@ lint: - name: taplo files: [toml] tools: [taplo] + description: Validate and format TOML files commands: - name: lint # Custom parser type defined in the trunk cli to handle taplo's output. diff --git a/linters/terraform/plugin.yaml b/linters/terraform/plugin.yaml index 20bbf4add..adf728c2d 100644 --- a/linters/terraform/plugin.yaml +++ b/linters/terraform/plugin.yaml @@ -4,6 +4,7 @@ lint: - name: terraform files: [terraform] tools: [terraform] + description: Validate and format terraform files commands: - name: validate # Custom parser type defined in the trunk cli to handle terraform's JSON output. diff --git a/linters/terragrunt/plugin.yaml b/linters/terragrunt/plugin.yaml index ff7c032c0..6aab17a1f 100644 --- a/linters/terragrunt/plugin.yaml +++ b/linters/terragrunt/plugin.yaml @@ -24,6 +24,7 @@ lint: definitions: - name: terragrunt tools: [terragrunt] + description: Maintain HCL files in a canonical format known_good_version: 0.45.8 files: [hcl] suggest_if: never diff --git a/linters/terrascan/plugin.yaml b/linters/terrascan/plugin.yaml index b11b9db38..30c4c8b98 100644 --- a/linters/terrascan/plugin.yaml +++ b/linters/terrascan/plugin.yaml @@ -22,7 +22,9 @@ lint: - name: terrascan tools: [terrascan] known_good_version: 1.18.1 - suggest_if: files_present + description: A static code analyzer for IaC + # terrascan does not support some modern terraform syntax. Don't auto-recommend. + suggest_if: never commands: - name: lint output: sarif diff --git a/linters/tflint/plugin.yaml b/linters/tflint/plugin.yaml index e6a163d20..b2c91731e 100644 --- a/linters/tflint/plugin.yaml +++ b/linters/tflint/plugin.yaml @@ -25,6 +25,7 @@ lint: definitions: - name: tflint files: [terraform] + description: A pluggable Terraform linter commands: - name: lint output: sarif diff --git a/linters/tfsec/plugin.yaml b/linters/tfsec/plugin.yaml index 4c764ed9e..cd4287bd9 100644 --- a/linters/tfsec/plugin.yaml +++ b/linters/tfsec/plugin.yaml @@ -29,6 +29,7 @@ lint: tools: [tfsec] known_good_version: 1.28.1 suggest_if: never + description: Security scanner for your Terraform code commands: - name: lint output: sarif diff --git a/linters/tofu/plugin.yaml b/linters/tofu/plugin.yaml new file mode 100644 index 000000000..ef2cc66c2 --- /dev/null +++ b/linters/tofu/plugin.yaml @@ -0,0 +1,40 @@ +version: 0.1 +lint: + definitions: + - name: tofu + files: [terraform] + tools: [tofu] + description: A Terraform validator and formatter + commands: + - name: validate + # Custom parser type defined in the trunk cli to handle tofu's JSON output. + output: terraform_validate + target: ${parent} + run: tofu validate -json + run_from: ${target_directory} + success_codes: [0, 1] + enabled: false + - name: fmt + output: rewrite + formatter: true + run: tofu fmt -no-color - + stdin: true + success_codes: [0] + cache_results: true + suggest_if: never + environment: + - name: PATH + list: ["${linter}"] + - name: GITHUB_APP_ID + value: ${env.GITHUB_APP_ID} + optional: true + - name: GITHUB_APP_INSTALLATION_ID + value: ${env.GITHUB_APP_INSTALLATION_ID} + optional: true + - name: GITHUB_APP_PEM_FILE + value: ${env.GITHUB_APP_PEM_FILE} + optional: true + known_good_version: 1.6.2 + version_command: + parse_regex: ${semver} + run: tofu --version diff --git a/linters/tofu/test_data/tofu_v1.6.2_variables.check.shot b/linters/tofu/test_data/tofu_v1.6.2_variables.check.shot new file mode 100644 index 000000000..bc325d35a --- /dev/null +++ b/linters/tofu/test_data/tofu_v1.6.2_variables.check.shot @@ -0,0 +1,60 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Testing linter tofu test variables 1`] = ` +{ + "issues": [ + { + "code": "Invalid quoted type constraints", + "file": "test_data/variables.in.tf", + "issueClass": "ISSUE_CLASS_EXISTING", + "level": "LEVEL_HIGH", + "line": "2", + "linter": "tofu", + "message": "OpenTofu 0.11 and earlier required type constraints to be given in quotes, but that form is now deprecated and will be removed in a future version of OpenTofu. Remove the quotes around "map" and write map(string) instead to explicitly indicate that the map elements are strings.", + "targetType": "terraform", + }, + ], + "lintActions": [ + { + "command": "fmt", + "fileGroupName": "terraform", + "linter": "tofu", + "paths": [ + "test_data/variables.in.tf", + ], + "verb": "TRUNK_VERB_FMT", + }, + { + "command": "validate", + "fileGroupName": "terraform", + "linter": "tofu", + "paths": [ + "test_data", + ], + "verb": "TRUNK_VERB_CHECK", + }, + { + "command": "validate", + "fileGroupName": "terraform", + "linter": "tofu", + "paths": [ + "test_data", + ], + "upstream": true, + "verb": "TRUNK_VERB_CHECK", + }, + ], + "taskFailures": [], + "unformattedFiles": [ + { + "column": "1", + "file": "test_data/variables.in.tf", + "issueClass": "ISSUE_CLASS_UNFORMATTED", + "level": "LEVEL_HIGH", + "line": "1", + "linter": "tofu", + "message": "Incorrect formatting, autoformat by running 'trunk fmt'", + }, + ], +} +`; diff --git a/linters/tofu/test_data/tofu_v1.6.2_variables.fmt.shot b/linters/tofu/test_data/tofu_v1.6.2_variables.fmt.shot new file mode 100644 index 000000000..7ead6f5f8 --- /dev/null +++ b/linters/tofu/test_data/tofu_v1.6.2_variables.fmt.shot @@ -0,0 +1,13 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Testing formatter tofu test variables 1`] = ` +"variable "ssl_certificates" { + type = map(string) + default = { + lorem-elb-us-west-3 = "lorem" + ipsum-elb-us-east-1 = "ipsum" + dolor-elb-us-east-2 = "dolor" + } +} +" +`; diff --git a/linters/tofu/test_data/variables.in.tf b/linters/tofu/test_data/variables.in.tf new file mode 100644 index 000000000..3743a3fef --- /dev/null +++ b/linters/tofu/test_data/variables.in.tf @@ -0,0 +1,8 @@ + variable "ssl_certificates" { + type = "map" + default = { + lorem-elb-us-west-3 = "lorem" + ipsum-elb-us-east-1 = "ipsum" + dolor-elb-us-east-2 = "dolor" + } +} diff --git a/linters/tofu/tofu.test.ts b/linters/tofu/tofu.test.ts new file mode 100644 index 000000000..616f4a3b5 --- /dev/null +++ b/linters/tofu/tofu.test.ts @@ -0,0 +1,18 @@ +import { linterCheckTest, linterFmtTest } from "tests"; +import { TrunkLintDriver } from "tests/driver"; + +// Due to tofu's validate subcommand being disabled by default, we need to manually enable it in our test's trunk.yaml. +const preCheck = (driver: TrunkLintDriver) => { + const trunkYamlPath = ".trunk/trunk.yaml"; + const currentContents = driver.readFile(trunkYamlPath); + const sqlfluffRegex = /- tofu@(.+)\n/; + const newContents = currentContents.replace( + sqlfluffRegex, + "- tofu@$1:\n commands: [validate, fmt]\n", + ); + driver.writeFile(trunkYamlPath, newContents); +}; + +linterCheckTest({ linterName: "tofu", preCheck }); + +linterFmtTest({ linterName: "tofu" }); diff --git a/linters/trivy/plugin.yaml b/linters/trivy/plugin.yaml index 9af9f4278..05cb25422 100644 --- a/linters/trivy/plugin.yaml +++ b/linters/trivy/plugin.yaml @@ -28,6 +28,7 @@ lint: - name: trivy tools: [trivy] suggest_if: files_present + description: A comprehensive and versatile security scanner known_good_version: 0.44.1 commands: - name: fs-vuln diff --git a/linters/trufflehog/plugin.yaml b/linters/trufflehog/plugin.yaml index 4ff554d74..b3952118e 100644 --- a/linters/trufflehog/plugin.yaml +++ b/linters/trufflehog/plugin.yaml @@ -21,6 +21,7 @@ lint: - name: trufflehog files: [ALL] tools: [trufflehog] + description: Validated and versatile secrets scanner known_good_version: 3.59.0 known_bad_versions: [3.41.0, 3.45.0, 3.60.1, 3.60.2] commands: @@ -31,7 +32,10 @@ lint: success_codes: [0, 183] is_security: true batch: true + cache_results: true cache_ttl: 1h + # trufflehog 3.71.1 stopped linting symlinks + sandbox_type: copy_targets parser: runtime: python run: python3 ${plugin}/linters/trufflehog/trufflehog_to_sarif.py diff --git a/linters/trufflehog/test_data/trufflehog_git_v3.68.0_CUSTOM.check.shot b/linters/trufflehog/test_data/trufflehog_git_v3.68.0_CUSTOM.check.shot index 9f4c1ce9c..270fba015 100644 --- a/linters/trufflehog/test_data/trufflehog_git_v3.68.0_CUSTOM.check.shot +++ b/linters/trufflehog/test_data/trufflehog_git_v3.68.0_CUSTOM.check.shot @@ -1,5 +1,4 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -// trunk-upgrade-validation:RELEASE exports[`Testing linter trufflehog-git test CUSTOM 1`] = ` { diff --git a/linters/trufflehog/test_data/trufflehog_git_v3.69.0_CUSTOM.check.shot b/linters/trufflehog/test_data/trufflehog_git_v3.69.0_CUSTOM.check.shot index ef6b700b9..58b9a36af 100644 --- a/linters/trufflehog/test_data/trufflehog_git_v3.69.0_CUSTOM.check.shot +++ b/linters/trufflehog/test_data/trufflehog_git_v3.69.0_CUSTOM.check.shot @@ -1,5 +1,4 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -// trunk-upgrade-validation:RELEASE exports[`Testing linter trufflehog-git test CUSTOM 1`] = ` { diff --git a/linters/trufflehog/test_data/trufflehog_v3.68.0_buff_size.check.shot b/linters/trufflehog/test_data/trufflehog_v3.68.0_buff_size.check.shot index da6cc9615..1bda3a01c 100644 --- a/linters/trufflehog/test_data/trufflehog_v3.68.0_buff_size.check.shot +++ b/linters/trufflehog/test_data/trufflehog_v3.68.0_buff_size.check.shot @@ -1,5 +1,4 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -// trunk-upgrade-validation:RELEASE exports[`Testing linter trufflehog test buff_size 1`] = ` { diff --git a/linters/trufflehog/test_data/trufflehog_v3.68.0_secrets.check.shot b/linters/trufflehog/test_data/trufflehog_v3.68.0_secrets.check.shot index 843140cbf..5c737ae40 100644 --- a/linters/trufflehog/test_data/trufflehog_v3.68.0_secrets.check.shot +++ b/linters/trufflehog/test_data/trufflehog_v3.68.0_secrets.check.shot @@ -1,5 +1,4 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -// trunk-upgrade-validation:RELEASE exports[`Testing linter trufflehog test secrets 1`] = ` { diff --git a/linters/trufflehog/test_data/trufflehog_v3.68.0_wrong_line_number.check.shot b/linters/trufflehog/test_data/trufflehog_v3.68.0_wrong_line_number.check.shot index 97b99d614..fa6ebab37 100644 --- a/linters/trufflehog/test_data/trufflehog_v3.68.0_wrong_line_number.check.shot +++ b/linters/trufflehog/test_data/trufflehog_v3.68.0_wrong_line_number.check.shot @@ -1,5 +1,4 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -// trunk-upgrade-validation:RELEASE exports[`Testing linter trufflehog test wrong_line_number 1`] = ` { diff --git a/linters/trufflehog/test_data/trufflehog_v3.69.0_buff_size.check.shot b/linters/trufflehog/test_data/trufflehog_v3.69.0_buff_size.check.shot index da6cc9615..1bda3a01c 100644 --- a/linters/trufflehog/test_data/trufflehog_v3.69.0_buff_size.check.shot +++ b/linters/trufflehog/test_data/trufflehog_v3.69.0_buff_size.check.shot @@ -1,5 +1,4 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -// trunk-upgrade-validation:RELEASE exports[`Testing linter trufflehog test buff_size 1`] = ` { diff --git a/linters/trufflehog/test_data/trufflehog_v3.69.0_secrets.check.shot b/linters/trufflehog/test_data/trufflehog_v3.69.0_secrets.check.shot index 76fde58b1..589c7bb56 100644 --- a/linters/trufflehog/test_data/trufflehog_v3.69.0_secrets.check.shot +++ b/linters/trufflehog/test_data/trufflehog_v3.69.0_secrets.check.shot @@ -1,5 +1,4 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -// trunk-upgrade-validation:RELEASE exports[`Testing linter trufflehog test secrets 1`] = ` { diff --git a/linters/trufflehog/test_data/trufflehog_v3.69.0_wrong_line_number.check.shot b/linters/trufflehog/test_data/trufflehog_v3.69.0_wrong_line_number.check.shot index 97b99d614..fa6ebab37 100644 --- a/linters/trufflehog/test_data/trufflehog_v3.69.0_wrong_line_number.check.shot +++ b/linters/trufflehog/test_data/trufflehog_v3.69.0_wrong_line_number.check.shot @@ -1,5 +1,4 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -// trunk-upgrade-validation:RELEASE exports[`Testing linter trufflehog test wrong_line_number 1`] = ` { diff --git a/linters/trufflehog/trufflehog.test.ts b/linters/trufflehog/trufflehog.test.ts index 35cc3a065..a7639e655 100644 --- a/linters/trufflehog/trufflehog.test.ts +++ b/linters/trufflehog/trufflehog.test.ts @@ -13,6 +13,8 @@ const preCheck = async (driver: TrunkLintDriver) => { await driver.gitDriver.add("secrets.in.py").add("secrets2.in.py").commit("Add secrets"); driver.deleteFile("secrets.in.py"); await driver.gitDriver.add("secrets.in.py").commit("Remove secrets"); + } else { + driver.debug("Error: failed to initialize git driver"); } }; diff --git a/linters/trunk-toolbox/plugin.yaml b/linters/trunk-toolbox/plugin.yaml index b5ca64718..5be873d4a 100644 --- a/linters/trunk-toolbox/plugin.yaml +++ b/linters/trunk-toolbox/plugin.yaml @@ -23,6 +23,7 @@ lint: - name: trunk-toolbox main_tool: trunk-toolbox files: [ALL] + description: Collection of universal linting tools commands: - name: lint run: trunk-toolbox --upstream=${upstream-ref} --results=${tmpfile} ${target} diff --git a/linters/txtpbfmt/plugin.yaml b/linters/txtpbfmt/plugin.yaml index 2e065a221..a6eb25cbb 100644 --- a/linters/txtpbfmt/plugin.yaml +++ b/linters/txtpbfmt/plugin.yaml @@ -11,6 +11,7 @@ lint: - name: txtpbfmt files: [textproto] tools: [txtpbfmt] + description: A formatter for textproto files commands: - name: format output: rewrite diff --git a/linters/yamllint/plugin.yaml b/linters/yamllint/plugin.yaml index 98a4a5a7e..449d067ff 100644 --- a/linters/yamllint/plugin.yaml +++ b/linters/yamllint/plugin.yaml @@ -10,6 +10,7 @@ lint: definitions: - name: yamllint files: [yaml] + description: Validate, Verify and Reformat your YAML documents commands: - output: regex parse_regex: diff --git a/linters/yapf/plugin.yaml b/linters/yapf/plugin.yaml index e51d016a2..d89891fd5 100644 --- a/linters/yapf/plugin.yaml +++ b/linters/yapf/plugin.yaml @@ -11,6 +11,7 @@ lint: definitions: - name: yapf files: [python] + description: A formatter for Python files commands: - name: format output: rewrite diff --git a/package-lock.json b/package-lock.json index d15824484..b3b3ca265 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,34 +11,34 @@ "@jest/console": "^29.4.1", "@jest/reporters": "^29.4.1", "@jest/test-result": "^29.4.1", - "@trunkio/launcher": "^1.3.0", + "@trunkio/launcher": "^1.3.1", "@types/caller": "^1.0.2", "@types/debug": "^4.1.12", "@types/jest": "^29.5.12", "@types/jest-specific-snapshot": "^0.5.9", - "@types/node": "^20.11.28", - "@typescript-eslint/eslint-plugin": "^7.2.0", - "@typescript-eslint/parser": "^7.2.0", + "@types/node": "^20.12.7", + "@typescript-eslint/eslint-plugin": "^7.7.0", + "@typescript-eslint/parser": "^7.7.0", "caller": "^1.1.0", "debug": "^4.3.4", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", "eslint-import-resolver-typescript": "^3.5.2", "eslint-plugin-import": "^2.29.1", - "eslint-plugin-jest": "^27.9.0", + "eslint-plugin-jest": "^28.2.0", "eslint-plugin-node": "^11.1.0", "eslint-plugin-prefer-arrow-functions": "^3.3.2", "eslint-plugin-prettier": "^5.1.3", - "eslint-plugin-simple-import-sort": "^12.0.0", + "eslint-plugin-simple-import-sort": "^12.1.0", "fast-sort": "^3.2.0", "jest": "^29.3.1", "jest-specific-snapshot": "^8.0.0", "semver": "^7.6.0", - "simple-git": "^3.23.0", + "simple-git": "^3.24.0", "ts-jest": "^29.1.2", "ts-node": "^10.9.2", "tsconfig-paths": "^4.1.2", - "typescript": "^5.4.2", + "typescript": "^5.4.5", "yaml": "^2.4.1" }, "engines": { @@ -695,9 +695,9 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.6.2.tgz", - "integrity": "sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw==", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", "dev": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" @@ -1304,9 +1304,9 @@ } }, "node_modules/@trunkio/launcher": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@trunkio/launcher/-/launcher-1.3.0.tgz", - "integrity": "sha512-CIehTfjiB905y9SuSMIRKkMv7qV+2jOALau7f1w0kjD14aHZIerT+eSeIzfrp2CTgRTTPAz2MZh+euNmh2Goxg==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@trunkio/launcher/-/launcher-1.3.1.tgz", + "integrity": "sha512-30gcw/pc+hmzXR8qHM0ND1kYgwnAjze3Xsnw3AUvxO9G4JzKF8u6FDy/6qbYKZxJ6Wr4SE0E0L7ZrAEA8Nia5Q==", "dev": true, "dependencies": { "semver": "^7.5.4", @@ -1472,18 +1472,18 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.11.28", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.28.tgz", - "integrity": "sha512-M/GPWVS2wLkSkNHVeLkrF2fD5Lx5UC4PxA0uZcKc6QqbIQUJyW1jVjueJYi1z8n0I5PxYrtpnPnWglE+y9A0KA==", + "version": "20.12.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz", + "integrity": "sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==", "dev": true, "dependencies": { "undici-types": "~5.26.4" } }, "node_modules/@types/semver": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.5.tgz", - "integrity": "sha512-+d+WYC1BxJ6yVOgUgzK8gWvp5qF8ssV5r4nsDcZWKRWcDQLQ619tvWAxJQYGgBrO1MnLJC7a5GtiYsAoQ47dJg==", + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", "dev": true }, "node_modules/@types/stack-utils": { @@ -1508,25 +1508,25 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.2.0.tgz", - "integrity": "sha512-mdekAHOqS9UjlmyF/LSs6AIEvfceV749GFxoBAjwAv0nkevfKHWQFDMcBZWUiIC5ft6ePWivXoS36aKQ0Cy3sw==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.7.0.tgz", + "integrity": "sha512-GJWR0YnfrKnsRoluVO3PRb9r5aMZriiMMM/RHj5nnTrBy1/wIgk76XCtCKcnXGjpZQJQRFtGV9/0JJ6n30uwpQ==", "dev": true, "dependencies": { - "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "7.2.0", - "@typescript-eslint/type-utils": "7.2.0", - "@typescript-eslint/utils": "7.2.0", - "@typescript-eslint/visitor-keys": "7.2.0", + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "7.7.0", + "@typescript-eslint/type-utils": "7.7.0", + "@typescript-eslint/utils": "7.7.0", + "@typescript-eslint/visitor-keys": "7.7.0", "debug": "^4.3.4", "graphemer": "^1.4.0", - "ignore": "^5.2.4", + "ignore": "^5.3.1", "natural-compare": "^1.4.0", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -1543,16 +1543,16 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.2.0.tgz", - "integrity": "sha512-Qh976RbQM/fYtjx9hs4XkayYujB/aPwglw2choHmf3zBjB4qOywWSdt9+KLRdHubGcoSwBnXUH2sR3hkyaERRg==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.7.0.tgz", + "integrity": "sha512-/8INDn0YLInbe9Wt7dK4cXLDYp0fNHP5xKLHvZl3mOT5X17rK/YShXaiNmorl+/U4VKCVIjJnx4Ri5b0y+HClw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.2.0", - "@typescript-eslint/visitor-keys": "7.2.0" + "@typescript-eslint/types": "7.7.0", + "@typescript-eslint/visitor-keys": "7.7.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -1560,12 +1560,12 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.2.0.tgz", - "integrity": "sha512-XFtUHPI/abFhm4cbCDc5Ykc8npOKBSJePY3a3s+lwumt7XWJuzP5cZcfZ610MIPHjQjNsOLlYK8ASPaNG8UiyA==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.7.0.tgz", + "integrity": "sha512-G01YPZ1Bd2hn+KPpIbrAhEWOn5lQBrjxkzHkWvP6NucMXFtfXoevK82hzQdpfuQYuhkvFDeQYbzXCjR1z9Z03w==", "dev": true, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -1573,22 +1573,22 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.2.0.tgz", - "integrity": "sha512-cyxS5WQQCoBwSakpMrvMXuMDEbhOo9bNHHrNcEWis6XHx6KF518tkF1wBvKIn/tpq5ZpUYK7Bdklu8qY0MsFIA==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.7.0.tgz", + "integrity": "sha512-8p71HQPE6CbxIBy2kWHqM1KGrC07pk6RJn40n0DSc6bMOBBREZxSDJ+BmRzc8B5OdaMh1ty3mkuWRg4sCFiDQQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.2.0", - "@typescript-eslint/visitor-keys": "7.2.0", + "@typescript-eslint/types": "7.7.0", + "@typescript-eslint/visitor-keys": "7.7.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -1601,21 +1601,21 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.2.0.tgz", - "integrity": "sha512-YfHpnMAGb1Eekpm3XRK8hcMwGLGsnT6L+7b2XyRv6ouDuJU1tZir1GS2i0+VXRatMwSI1/UfcyPe53ADkU+IuA==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.7.0.tgz", + "integrity": "sha512-LKGAXMPQs8U/zMRFXDZOzmMKgFv3COlxUQ+2NMPhbqgVm6R1w+nU1i4836Pmxu9jZAuIeyySNrN/6Rc657ggig==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "7.2.0", - "@typescript-eslint/types": "7.2.0", - "@typescript-eslint/typescript-estree": "7.2.0", - "semver": "^7.5.4" + "@types/json-schema": "^7.0.15", + "@types/semver": "^7.5.8", + "@typescript-eslint/scope-manager": "7.7.0", + "@typescript-eslint/types": "7.7.0", + "@typescript-eslint/typescript-estree": "7.7.0", + "semver": "^7.6.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -1626,16 +1626,16 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.2.0.tgz", - "integrity": "sha512-c6EIQRHhcpl6+tO8EMR+kjkkV+ugUNXOmeASA1rlzkd8EPIriavpWoiEz1HR/VLhbVIdhqnV6E7JZm00cBDx2A==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.7.0.tgz", + "integrity": "sha512-h0WHOj8MhdhY8YWkzIF30R379y0NqyOHExI9N9KCzvmu05EgG4FumeYa3ccfKUSphyWkWQE1ybVrgz/Pbam6YA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.2.0", - "eslint-visitor-keys": "^3.4.1" + "@typescript-eslint/types": "7.7.0", + "eslint-visitor-keys": "^3.4.3" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -1652,9 +1652,9 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -1667,19 +1667,19 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.2.0.tgz", - "integrity": "sha512-5FKsVcHTk6TafQKQbuIVkXq58Fnbkd2wDL4LB7AURN7RUOu1utVP+G8+6u3ZhEroW3DF6hyo3ZEXxgKgp4KeCg==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.7.0.tgz", + "integrity": "sha512-fNcDm3wSwVM8QYL4HKVBggdIPAy9Q41vcvC/GtDobw3c4ndVT3K6cqudUmjHPw8EAp4ufax0o58/xvWaP2FmTg==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "7.2.0", - "@typescript-eslint/types": "7.2.0", - "@typescript-eslint/typescript-estree": "7.2.0", - "@typescript-eslint/visitor-keys": "7.2.0", + "@typescript-eslint/scope-manager": "7.7.0", + "@typescript-eslint/types": "7.7.0", + "@typescript-eslint/typescript-estree": "7.7.0", + "@typescript-eslint/visitor-keys": "7.7.0", "debug": "^4.3.4" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -1695,16 +1695,16 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.2.0.tgz", - "integrity": "sha512-Qh976RbQM/fYtjx9hs4XkayYujB/aPwglw2choHmf3zBjB4qOywWSdt9+KLRdHubGcoSwBnXUH2sR3hkyaERRg==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.7.0.tgz", + "integrity": "sha512-/8INDn0YLInbe9Wt7dK4cXLDYp0fNHP5xKLHvZl3mOT5X17rK/YShXaiNmorl+/U4VKCVIjJnx4Ri5b0y+HClw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.2.0", - "@typescript-eslint/visitor-keys": "7.2.0" + "@typescript-eslint/types": "7.7.0", + "@typescript-eslint/visitor-keys": "7.7.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -1712,12 +1712,12 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.2.0.tgz", - "integrity": "sha512-XFtUHPI/abFhm4cbCDc5Ykc8npOKBSJePY3a3s+lwumt7XWJuzP5cZcfZ610MIPHjQjNsOLlYK8ASPaNG8UiyA==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.7.0.tgz", + "integrity": "sha512-G01YPZ1Bd2hn+KPpIbrAhEWOn5lQBrjxkzHkWvP6NucMXFtfXoevK82hzQdpfuQYuhkvFDeQYbzXCjR1z9Z03w==", "dev": true, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -1725,22 +1725,22 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.2.0.tgz", - "integrity": "sha512-cyxS5WQQCoBwSakpMrvMXuMDEbhOo9bNHHrNcEWis6XHx6KF518tkF1wBvKIn/tpq5ZpUYK7Bdklu8qY0MsFIA==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.7.0.tgz", + "integrity": "sha512-8p71HQPE6CbxIBy2kWHqM1KGrC07pk6RJn40n0DSc6bMOBBREZxSDJ+BmRzc8B5OdaMh1ty3mkuWRg4sCFiDQQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.2.0", - "@typescript-eslint/visitor-keys": "7.2.0", + "@typescript-eslint/types": "7.7.0", + "@typescript-eslint/visitor-keys": "7.7.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -1753,16 +1753,16 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.2.0.tgz", - "integrity": "sha512-c6EIQRHhcpl6+tO8EMR+kjkkV+ugUNXOmeASA1rlzkd8EPIriavpWoiEz1HR/VLhbVIdhqnV6E7JZm00cBDx2A==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.7.0.tgz", + "integrity": "sha512-h0WHOj8MhdhY8YWkzIF30R379y0NqyOHExI9N9KCzvmu05EgG4FumeYa3ccfKUSphyWkWQE1ybVrgz/Pbam6YA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.2.0", - "eslint-visitor-keys": "^3.4.1" + "@typescript-eslint/types": "7.7.0", + "eslint-visitor-keys": "^3.4.3" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -1779,9 +1779,9 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -1794,16 +1794,16 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", - "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", + "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0" + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", @@ -1811,18 +1811,18 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.2.0.tgz", - "integrity": "sha512-xHi51adBHo9O9330J8GQYQwrKBqbIPJGZZVQTHHmy200hvkLZFWJIFtAG/7IYTWUyun6DE6w5InDReePJYJlJA==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.7.0.tgz", + "integrity": "sha512-bOp3ejoRYrhAlnT/bozNQi3nio9tIgv3U5C0mVDdZC7cpcQEDZXvq8inrHYghLVwuNABRqrMW5tzAv88Vy77Sg==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "7.2.0", - "@typescript-eslint/utils": "7.2.0", + "@typescript-eslint/typescript-estree": "7.7.0", + "@typescript-eslint/utils": "7.7.0", "debug": "^4.3.4", - "ts-api-utils": "^1.0.1" + "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -1838,16 +1838,16 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/scope-manager": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.2.0.tgz", - "integrity": "sha512-Qh976RbQM/fYtjx9hs4XkayYujB/aPwglw2choHmf3zBjB4qOywWSdt9+KLRdHubGcoSwBnXUH2sR3hkyaERRg==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.7.0.tgz", + "integrity": "sha512-/8INDn0YLInbe9Wt7dK4cXLDYp0fNHP5xKLHvZl3mOT5X17rK/YShXaiNmorl+/U4VKCVIjJnx4Ri5b0y+HClw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.2.0", - "@typescript-eslint/visitor-keys": "7.2.0" + "@typescript-eslint/types": "7.7.0", + "@typescript-eslint/visitor-keys": "7.7.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -1855,12 +1855,12 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.2.0.tgz", - "integrity": "sha512-XFtUHPI/abFhm4cbCDc5Ykc8npOKBSJePY3a3s+lwumt7XWJuzP5cZcfZ610MIPHjQjNsOLlYK8ASPaNG8UiyA==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.7.0.tgz", + "integrity": "sha512-G01YPZ1Bd2hn+KPpIbrAhEWOn5lQBrjxkzHkWvP6NucMXFtfXoevK82hzQdpfuQYuhkvFDeQYbzXCjR1z9Z03w==", "dev": true, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -1868,22 +1868,22 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.2.0.tgz", - "integrity": "sha512-cyxS5WQQCoBwSakpMrvMXuMDEbhOo9bNHHrNcEWis6XHx6KF518tkF1wBvKIn/tpq5ZpUYK7Bdklu8qY0MsFIA==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.7.0.tgz", + "integrity": "sha512-8p71HQPE6CbxIBy2kWHqM1KGrC07pk6RJn40n0DSc6bMOBBREZxSDJ+BmRzc8B5OdaMh1ty3mkuWRg4sCFiDQQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.2.0", - "@typescript-eslint/visitor-keys": "7.2.0", + "@typescript-eslint/types": "7.7.0", + "@typescript-eslint/visitor-keys": "7.7.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -1896,21 +1896,21 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/utils": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.2.0.tgz", - "integrity": "sha512-YfHpnMAGb1Eekpm3XRK8hcMwGLGsnT6L+7b2XyRv6ouDuJU1tZir1GS2i0+VXRatMwSI1/UfcyPe53ADkU+IuA==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.7.0.tgz", + "integrity": "sha512-LKGAXMPQs8U/zMRFXDZOzmMKgFv3COlxUQ+2NMPhbqgVm6R1w+nU1i4836Pmxu9jZAuIeyySNrN/6Rc657ggig==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "7.2.0", - "@typescript-eslint/types": "7.2.0", - "@typescript-eslint/typescript-estree": "7.2.0", - "semver": "^7.5.4" + "@types/json-schema": "^7.0.15", + "@types/semver": "^7.5.8", + "@typescript-eslint/scope-manager": "7.7.0", + "@typescript-eslint/types": "7.7.0", + "@typescript-eslint/typescript-estree": "7.7.0", + "semver": "^7.6.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -1921,16 +1921,16 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.2.0.tgz", - "integrity": "sha512-c6EIQRHhcpl6+tO8EMR+kjkkV+ugUNXOmeASA1rlzkd8EPIriavpWoiEz1HR/VLhbVIdhqnV6E7JZm00cBDx2A==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.7.0.tgz", + "integrity": "sha512-h0WHOj8MhdhY8YWkzIF30R379y0NqyOHExI9N9KCzvmu05EgG4FumeYa3ccfKUSphyWkWQE1ybVrgz/Pbam6YA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.2.0", - "eslint-visitor-keys": "^3.4.1" + "@typescript-eslint/types": "7.7.0", + "eslint-visitor-keys": "^3.4.3" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -1947,9 +1947,9 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -1962,12 +1962,12 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", - "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", + "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", "dev": true, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", @@ -1975,21 +1975,22 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", - "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", + "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "minimatch": "9.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", @@ -2001,43 +2002,66 @@ } } }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@typescript-eslint/utils": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", - "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", + "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", "dev": true, "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", - "eslint-scope": "^5.1.1", - "semver": "^7.3.7" + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", + "semver": "^7.5.4" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + "eslint": "^7.0.0 || ^8.0.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", - "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", + "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.62.0", - "eslint-visitor-keys": "^3.3.0" + "@typescript-eslint/types": "6.21.0", + "eslint-visitor-keys": "^3.4.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", @@ -3183,19 +3207,19 @@ } }, "node_modules/eslint-plugin-jest": { - "version": "27.9.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-27.9.0.tgz", - "integrity": "sha512-QIT7FH7fNmd9n4se7FFKHbsLKGQiw885Ds6Y/sxKgCZ6natwCsXdgPOADnYVxN2QrRweF0FZWbJ6S7Rsn7llug==", + "version": "28.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-28.2.0.tgz", + "integrity": "sha512-yRDti/a+f+SMSmNTiT9/M/MzXGkitl8CfzUxnpoQcTyfq8gUrXMriVcWU36W1X6BZSUoyUCJrDAWWUA2N4hE5g==", "dev": true, "dependencies": { - "@typescript-eslint/utils": "^5.10.0" + "@typescript-eslint/utils": "^6.0.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^16.10.0 || ^18.12.0 || >=20.0.0" }, "peerDependencies": { - "@typescript-eslint/eslint-plugin": "^5.0.0 || ^6.0.0 || ^7.0.0", - "eslint": "^7.0.0 || ^8.0.0", + "@typescript-eslint/eslint-plugin": "^6.0.0 || ^7.0.0", + "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0", "jest": "*" }, "peerDependenciesMeta": { @@ -3319,27 +3343,14 @@ } }, "node_modules/eslint-plugin-simple-import-sort": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-12.0.0.tgz", - "integrity": "sha512-8o0dVEdAkYap0Cn5kNeklaKcT1nUsa3LITWEuFk3nJifOoD+5JQGoyDUW2W/iPWwBsNBJpyJS9y4je/BgxLcyQ==", + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-12.1.0.tgz", + "integrity": "sha512-Y2fqAfC11TcG/WP3TrI1Gi3p3nc8XJyEOJYHyEPEGI/UAgNx6akxxlX74p7SbAQdLcgASKhj8M0GKvH3vq/+ig==", "dev": true, "peerDependencies": { "eslint": ">=5.0.0" } }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, "node_modules/eslint-visitor-keys": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", @@ -3449,15 +3460,6 @@ "node": ">=4.0" } }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", @@ -4039,9 +4041,9 @@ } }, "node_modules/ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", "dev": true, "engines": { "node": ">= 4" @@ -6080,9 +6082,9 @@ "dev": true }, "node_modules/simple-git": { - "version": "3.23.0", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.23.0.tgz", - "integrity": "sha512-P9ggTW8vb/21CAL/AmnACAhqBDfnqSSZVpV7WuFtsFR9HLunf5IqQvk+OXAQTfkcZep8pKnt3DV3o7w3TegEkQ==", + "version": "3.24.0", + "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.24.0.tgz", + "integrity": "sha512-QqAKee9Twv+3k8IFOFfPB2hnk6as6Y6ACUpwCtQvRYBAes23Wv3SZlHVobAzqcE8gfsisCvPw3HGW3HYM+VYYw==", "dev": true, "dependencies": { "@kwsites/file-exists": "^1.1.1", @@ -6398,12 +6400,12 @@ } }, "node_modules/ts-api-utils": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz", - "integrity": "sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", "dev": true, "engines": { - "node": ">=16.13.0" + "node": ">=16" }, "peerDependencies": { "typescript": ">=4.2.0" @@ -6524,27 +6526,6 @@ "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", "dev": true }, - "node_modules/tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "dependencies": { - "tslib": "^1.8.1" - }, - "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" - } - }, - "node_modules/tsutils/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -6644,9 +6625,9 @@ } }, "node_modules/typescript": { - "version": "5.4.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz", - "integrity": "sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==", + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", + "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -7406,9 +7387,9 @@ } }, "@eslint-community/regexpp": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.6.2.tgz", - "integrity": "sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw==", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", "dev": true }, "@eslint/eslintrc": { @@ -7885,9 +7866,9 @@ } }, "@trunkio/launcher": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@trunkio/launcher/-/launcher-1.3.0.tgz", - "integrity": "sha512-CIehTfjiB905y9SuSMIRKkMv7qV+2jOALau7f1w0kjD14aHZIerT+eSeIzfrp2CTgRTTPAz2MZh+euNmh2Goxg==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@trunkio/launcher/-/launcher-1.3.1.tgz", + "integrity": "sha512-30gcw/pc+hmzXR8qHM0ND1kYgwnAjze3Xsnw3AUvxO9G4JzKF8u6FDy/6qbYKZxJ6Wr4SE0E0L7ZrAEA8Nia5Q==", "dev": true, "requires": { "semver": "^7.5.4", @@ -8046,18 +8027,18 @@ "dev": true }, "@types/node": { - "version": "20.11.28", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.28.tgz", - "integrity": "sha512-M/GPWVS2wLkSkNHVeLkrF2fD5Lx5UC4PxA0uZcKc6QqbIQUJyW1jVjueJYi1z8n0I5PxYrtpnPnWglE+y9A0KA==", + "version": "20.12.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz", + "integrity": "sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==", "dev": true, "requires": { "undici-types": "~5.26.4" } }, "@types/semver": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.5.tgz", - "integrity": "sha512-+d+WYC1BxJ6yVOgUgzK8gWvp5qF8ssV5r4nsDcZWKRWcDQLQ619tvWAxJQYGgBrO1MnLJC7a5GtiYsAoQ47dJg==", + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", "dev": true }, "@types/stack-utils": { @@ -8082,79 +8063,79 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.2.0.tgz", - "integrity": "sha512-mdekAHOqS9UjlmyF/LSs6AIEvfceV749GFxoBAjwAv0nkevfKHWQFDMcBZWUiIC5ft6ePWivXoS36aKQ0Cy3sw==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.7.0.tgz", + "integrity": "sha512-GJWR0YnfrKnsRoluVO3PRb9r5aMZriiMMM/RHj5nnTrBy1/wIgk76XCtCKcnXGjpZQJQRFtGV9/0JJ6n30uwpQ==", "dev": true, "requires": { - "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "7.2.0", - "@typescript-eslint/type-utils": "7.2.0", - "@typescript-eslint/utils": "7.2.0", - "@typescript-eslint/visitor-keys": "7.2.0", + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "7.7.0", + "@typescript-eslint/type-utils": "7.7.0", + "@typescript-eslint/utils": "7.7.0", + "@typescript-eslint/visitor-keys": "7.7.0", "debug": "^4.3.4", "graphemer": "^1.4.0", - "ignore": "^5.2.4", + "ignore": "^5.3.1", "natural-compare": "^1.4.0", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" }, "dependencies": { "@typescript-eslint/scope-manager": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.2.0.tgz", - "integrity": "sha512-Qh976RbQM/fYtjx9hs4XkayYujB/aPwglw2choHmf3zBjB4qOywWSdt9+KLRdHubGcoSwBnXUH2sR3hkyaERRg==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.7.0.tgz", + "integrity": "sha512-/8INDn0YLInbe9Wt7dK4cXLDYp0fNHP5xKLHvZl3mOT5X17rK/YShXaiNmorl+/U4VKCVIjJnx4Ri5b0y+HClw==", "dev": true, "requires": { - "@typescript-eslint/types": "7.2.0", - "@typescript-eslint/visitor-keys": "7.2.0" + "@typescript-eslint/types": "7.7.0", + "@typescript-eslint/visitor-keys": "7.7.0" } }, "@typescript-eslint/types": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.2.0.tgz", - "integrity": "sha512-XFtUHPI/abFhm4cbCDc5Ykc8npOKBSJePY3a3s+lwumt7XWJuzP5cZcfZ610MIPHjQjNsOLlYK8ASPaNG8UiyA==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.7.0.tgz", + "integrity": "sha512-G01YPZ1Bd2hn+KPpIbrAhEWOn5lQBrjxkzHkWvP6NucMXFtfXoevK82hzQdpfuQYuhkvFDeQYbzXCjR1z9Z03w==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.2.0.tgz", - "integrity": "sha512-cyxS5WQQCoBwSakpMrvMXuMDEbhOo9bNHHrNcEWis6XHx6KF518tkF1wBvKIn/tpq5ZpUYK7Bdklu8qY0MsFIA==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.7.0.tgz", + "integrity": "sha512-8p71HQPE6CbxIBy2kWHqM1KGrC07pk6RJn40n0DSc6bMOBBREZxSDJ+BmRzc8B5OdaMh1ty3mkuWRg4sCFiDQQ==", "dev": true, "requires": { - "@typescript-eslint/types": "7.2.0", - "@typescript-eslint/visitor-keys": "7.2.0", + "@typescript-eslint/types": "7.7.0", + "@typescript-eslint/visitor-keys": "7.7.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" } }, "@typescript-eslint/utils": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.2.0.tgz", - "integrity": "sha512-YfHpnMAGb1Eekpm3XRK8hcMwGLGsnT6L+7b2XyRv6ouDuJU1tZir1GS2i0+VXRatMwSI1/UfcyPe53ADkU+IuA==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.7.0.tgz", + "integrity": "sha512-LKGAXMPQs8U/zMRFXDZOzmMKgFv3COlxUQ+2NMPhbqgVm6R1w+nU1i4836Pmxu9jZAuIeyySNrN/6Rc657ggig==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "7.2.0", - "@typescript-eslint/types": "7.2.0", - "@typescript-eslint/typescript-estree": "7.2.0", - "semver": "^7.5.4" + "@types/json-schema": "^7.0.15", + "@types/semver": "^7.5.8", + "@typescript-eslint/scope-manager": "7.7.0", + "@typescript-eslint/types": "7.7.0", + "@typescript-eslint/typescript-estree": "7.7.0", + "semver": "^7.6.0" } }, "@typescript-eslint/visitor-keys": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.2.0.tgz", - "integrity": "sha512-c6EIQRHhcpl6+tO8EMR+kjkkV+ugUNXOmeASA1rlzkd8EPIriavpWoiEz1HR/VLhbVIdhqnV6E7JZm00cBDx2A==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.7.0.tgz", + "integrity": "sha512-h0WHOj8MhdhY8YWkzIF30R379y0NqyOHExI9N9KCzvmu05EgG4FumeYa3ccfKUSphyWkWQE1ybVrgz/Pbam6YA==", "dev": true, "requires": { - "@typescript-eslint/types": "7.2.0", - "eslint-visitor-keys": "^3.4.1" + "@typescript-eslint/types": "7.7.0", + "eslint-visitor-keys": "^3.4.3" } }, "brace-expansion": { @@ -8167,9 +8148,9 @@ } }, "minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", "dev": true, "requires": { "brace-expansion": "^2.0.1" @@ -8178,58 +8159,58 @@ } }, "@typescript-eslint/parser": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.2.0.tgz", - "integrity": "sha512-5FKsVcHTk6TafQKQbuIVkXq58Fnbkd2wDL4LB7AURN7RUOu1utVP+G8+6u3ZhEroW3DF6hyo3ZEXxgKgp4KeCg==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.7.0.tgz", + "integrity": "sha512-fNcDm3wSwVM8QYL4HKVBggdIPAy9Q41vcvC/GtDobw3c4ndVT3K6cqudUmjHPw8EAp4ufax0o58/xvWaP2FmTg==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "7.2.0", - "@typescript-eslint/types": "7.2.0", - "@typescript-eslint/typescript-estree": "7.2.0", - "@typescript-eslint/visitor-keys": "7.2.0", + "@typescript-eslint/scope-manager": "7.7.0", + "@typescript-eslint/types": "7.7.0", + "@typescript-eslint/typescript-estree": "7.7.0", + "@typescript-eslint/visitor-keys": "7.7.0", "debug": "^4.3.4" }, "dependencies": { "@typescript-eslint/scope-manager": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.2.0.tgz", - "integrity": "sha512-Qh976RbQM/fYtjx9hs4XkayYujB/aPwglw2choHmf3zBjB4qOywWSdt9+KLRdHubGcoSwBnXUH2sR3hkyaERRg==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.7.0.tgz", + "integrity": "sha512-/8INDn0YLInbe9Wt7dK4cXLDYp0fNHP5xKLHvZl3mOT5X17rK/YShXaiNmorl+/U4VKCVIjJnx4Ri5b0y+HClw==", "dev": true, "requires": { - "@typescript-eslint/types": "7.2.0", - "@typescript-eslint/visitor-keys": "7.2.0" + "@typescript-eslint/types": "7.7.0", + "@typescript-eslint/visitor-keys": "7.7.0" } }, "@typescript-eslint/types": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.2.0.tgz", - "integrity": "sha512-XFtUHPI/abFhm4cbCDc5Ykc8npOKBSJePY3a3s+lwumt7XWJuzP5cZcfZ610MIPHjQjNsOLlYK8ASPaNG8UiyA==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.7.0.tgz", + "integrity": "sha512-G01YPZ1Bd2hn+KPpIbrAhEWOn5lQBrjxkzHkWvP6NucMXFtfXoevK82hzQdpfuQYuhkvFDeQYbzXCjR1z9Z03w==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.2.0.tgz", - "integrity": "sha512-cyxS5WQQCoBwSakpMrvMXuMDEbhOo9bNHHrNcEWis6XHx6KF518tkF1wBvKIn/tpq5ZpUYK7Bdklu8qY0MsFIA==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.7.0.tgz", + "integrity": "sha512-8p71HQPE6CbxIBy2kWHqM1KGrC07pk6RJn40n0DSc6bMOBBREZxSDJ+BmRzc8B5OdaMh1ty3mkuWRg4sCFiDQQ==", "dev": true, "requires": { - "@typescript-eslint/types": "7.2.0", - "@typescript-eslint/visitor-keys": "7.2.0", + "@typescript-eslint/types": "7.7.0", + "@typescript-eslint/visitor-keys": "7.7.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" } }, "@typescript-eslint/visitor-keys": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.2.0.tgz", - "integrity": "sha512-c6EIQRHhcpl6+tO8EMR+kjkkV+ugUNXOmeASA1rlzkd8EPIriavpWoiEz1HR/VLhbVIdhqnV6E7JZm00cBDx2A==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.7.0.tgz", + "integrity": "sha512-h0WHOj8MhdhY8YWkzIF30R379y0NqyOHExI9N9KCzvmu05EgG4FumeYa3ccfKUSphyWkWQE1ybVrgz/Pbam6YA==", "dev": true, "requires": { - "@typescript-eslint/types": "7.2.0", - "eslint-visitor-keys": "^3.4.1" + "@typescript-eslint/types": "7.7.0", + "eslint-visitor-keys": "^3.4.3" } }, "brace-expansion": { @@ -8242,9 +8223,9 @@ } }, "minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", "dev": true, "requires": { "brace-expansion": "^2.0.1" @@ -8253,82 +8234,82 @@ } }, "@typescript-eslint/scope-manager": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", - "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", + "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", "dev": true, "requires": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0" + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0" } }, "@typescript-eslint/type-utils": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.2.0.tgz", - "integrity": "sha512-xHi51adBHo9O9330J8GQYQwrKBqbIPJGZZVQTHHmy200hvkLZFWJIFtAG/7IYTWUyun6DE6w5InDReePJYJlJA==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.7.0.tgz", + "integrity": "sha512-bOp3ejoRYrhAlnT/bozNQi3nio9tIgv3U5C0mVDdZC7cpcQEDZXvq8inrHYghLVwuNABRqrMW5tzAv88Vy77Sg==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "7.2.0", - "@typescript-eslint/utils": "7.2.0", + "@typescript-eslint/typescript-estree": "7.7.0", + "@typescript-eslint/utils": "7.7.0", "debug": "^4.3.4", - "ts-api-utils": "^1.0.1" + "ts-api-utils": "^1.3.0" }, "dependencies": { "@typescript-eslint/scope-manager": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.2.0.tgz", - "integrity": "sha512-Qh976RbQM/fYtjx9hs4XkayYujB/aPwglw2choHmf3zBjB4qOywWSdt9+KLRdHubGcoSwBnXUH2sR3hkyaERRg==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.7.0.tgz", + "integrity": "sha512-/8INDn0YLInbe9Wt7dK4cXLDYp0fNHP5xKLHvZl3mOT5X17rK/YShXaiNmorl+/U4VKCVIjJnx4Ri5b0y+HClw==", "dev": true, "requires": { - "@typescript-eslint/types": "7.2.0", - "@typescript-eslint/visitor-keys": "7.2.0" + "@typescript-eslint/types": "7.7.0", + "@typescript-eslint/visitor-keys": "7.7.0" } }, "@typescript-eslint/types": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.2.0.tgz", - "integrity": "sha512-XFtUHPI/abFhm4cbCDc5Ykc8npOKBSJePY3a3s+lwumt7XWJuzP5cZcfZ610MIPHjQjNsOLlYK8ASPaNG8UiyA==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.7.0.tgz", + "integrity": "sha512-G01YPZ1Bd2hn+KPpIbrAhEWOn5lQBrjxkzHkWvP6NucMXFtfXoevK82hzQdpfuQYuhkvFDeQYbzXCjR1z9Z03w==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.2.0.tgz", - "integrity": "sha512-cyxS5WQQCoBwSakpMrvMXuMDEbhOo9bNHHrNcEWis6XHx6KF518tkF1wBvKIn/tpq5ZpUYK7Bdklu8qY0MsFIA==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.7.0.tgz", + "integrity": "sha512-8p71HQPE6CbxIBy2kWHqM1KGrC07pk6RJn40n0DSc6bMOBBREZxSDJ+BmRzc8B5OdaMh1ty3mkuWRg4sCFiDQQ==", "dev": true, "requires": { - "@typescript-eslint/types": "7.2.0", - "@typescript-eslint/visitor-keys": "7.2.0", + "@typescript-eslint/types": "7.7.0", + "@typescript-eslint/visitor-keys": "7.7.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" } }, "@typescript-eslint/utils": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.2.0.tgz", - "integrity": "sha512-YfHpnMAGb1Eekpm3XRK8hcMwGLGsnT6L+7b2XyRv6ouDuJU1tZir1GS2i0+VXRatMwSI1/UfcyPe53ADkU+IuA==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.7.0.tgz", + "integrity": "sha512-LKGAXMPQs8U/zMRFXDZOzmMKgFv3COlxUQ+2NMPhbqgVm6R1w+nU1i4836Pmxu9jZAuIeyySNrN/6Rc657ggig==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "7.2.0", - "@typescript-eslint/types": "7.2.0", - "@typescript-eslint/typescript-estree": "7.2.0", - "semver": "^7.5.4" + "@types/json-schema": "^7.0.15", + "@types/semver": "^7.5.8", + "@typescript-eslint/scope-manager": "7.7.0", + "@typescript-eslint/types": "7.7.0", + "@typescript-eslint/typescript-estree": "7.7.0", + "semver": "^7.6.0" } }, "@typescript-eslint/visitor-keys": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.2.0.tgz", - "integrity": "sha512-c6EIQRHhcpl6+tO8EMR+kjkkV+ugUNXOmeASA1rlzkd8EPIriavpWoiEz1HR/VLhbVIdhqnV6E7JZm00cBDx2A==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.7.0.tgz", + "integrity": "sha512-h0WHOj8MhdhY8YWkzIF30R379y0NqyOHExI9N9KCzvmu05EgG4FumeYa3ccfKUSphyWkWQE1ybVrgz/Pbam6YA==", "dev": true, "requires": { - "@typescript-eslint/types": "7.2.0", - "eslint-visitor-keys": "^3.4.1" + "@typescript-eslint/types": "7.7.0", + "eslint-visitor-keys": "^3.4.3" } }, "brace-expansion": { @@ -8341,9 +8322,9 @@ } }, "minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", "dev": true, "requires": { "brace-expansion": "^2.0.1" @@ -8352,50 +8333,70 @@ } }, "@typescript-eslint/types": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", - "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", + "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", - "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", + "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", "dev": true, "requires": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "minimatch": "9.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + } } }, "@typescript-eslint/utils": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", - "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", + "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", "dev": true, "requires": { - "@eslint-community/eslint-utils": "^4.2.0", - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", - "eslint-scope": "^5.1.1", - "semver": "^7.3.7" + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", + "semver": "^7.5.4" } }, "@typescript-eslint/visitor-keys": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", - "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", + "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", "dev": true, "requires": { - "@typescript-eslint/types": "5.62.0", - "eslint-visitor-keys": "^3.3.0" + "@typescript-eslint/types": "6.21.0", + "eslint-visitor-keys": "^3.4.1" } }, "@ungap/structured-clone": { @@ -9264,12 +9265,12 @@ } }, "eslint-plugin-jest": { - "version": "27.9.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-27.9.0.tgz", - "integrity": "sha512-QIT7FH7fNmd9n4se7FFKHbsLKGQiw885Ds6Y/sxKgCZ6natwCsXdgPOADnYVxN2QrRweF0FZWbJ6S7Rsn7llug==", + "version": "28.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-28.2.0.tgz", + "integrity": "sha512-yRDti/a+f+SMSmNTiT9/M/MzXGkitl8CfzUxnpoQcTyfq8gUrXMriVcWU36W1X6BZSUoyUCJrDAWWUA2N4hE5g==", "dev": true, "requires": { - "@typescript-eslint/utils": "^5.10.0" + "@typescript-eslint/utils": "^6.0.0" } }, "eslint-plugin-node": { @@ -9337,22 +9338,12 @@ } }, "eslint-plugin-simple-import-sort": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-12.0.0.tgz", - "integrity": "sha512-8o0dVEdAkYap0Cn5kNeklaKcT1nUsa3LITWEuFk3nJifOoD+5JQGoyDUW2W/iPWwBsNBJpyJS9y4je/BgxLcyQ==", + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-12.1.0.tgz", + "integrity": "sha512-Y2fqAfC11TcG/WP3TrI1Gi3p3nc8XJyEOJYHyEPEGI/UAgNx6akxxlX74p7SbAQdLcgASKhj8M0GKvH3vq/+ig==", "dev": true, "requires": {} }, - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, "eslint-visitor-keys": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", @@ -9410,12 +9401,6 @@ } } }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, "esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", @@ -9847,9 +9832,9 @@ "dev": true }, "ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", "dev": true }, "import-fresh": { @@ -11323,9 +11308,9 @@ "dev": true }, "simple-git": { - "version": "3.23.0", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.23.0.tgz", - "integrity": "sha512-P9ggTW8vb/21CAL/AmnACAhqBDfnqSSZVpV7WuFtsFR9HLunf5IqQvk+OXAQTfkcZep8pKnt3DV3o7w3TegEkQ==", + "version": "3.24.0", + "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.24.0.tgz", + "integrity": "sha512-QqAKee9Twv+3k8IFOFfPB2hnk6as6Y6ACUpwCtQvRYBAes23Wv3SZlHVobAzqcE8gfsisCvPw3HGW3HYM+VYYw==", "dev": true, "requires": { "@kwsites/file-exists": "^1.1.1", @@ -11565,9 +11550,9 @@ } }, "ts-api-utils": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz", - "integrity": "sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", "dev": true, "requires": {} }, @@ -11633,23 +11618,6 @@ "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", "dev": true }, - "tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - }, - "dependencies": { - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - } - } - }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -11719,9 +11687,9 @@ } }, "typescript": { - "version": "5.4.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz", - "integrity": "sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==", + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", + "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", "dev": true }, "unbox-primitive": { diff --git a/package.json b/package.json index 81b4da78c..a8729787a 100644 --- a/package.json +++ b/package.json @@ -9,34 +9,34 @@ "@jest/console": "^29.4.1", "@jest/reporters": "^29.4.1", "@jest/test-result": "^29.4.1", - "@trunkio/launcher": "^1.3.0", + "@trunkio/launcher": "^1.3.1", "@types/caller": "^1.0.2", "@types/debug": "^4.1.12", "@types/jest": "^29.5.12", "@types/jest-specific-snapshot": "^0.5.9", - "@types/node": "^20.11.28", - "@typescript-eslint/eslint-plugin": "^7.2.0", - "@typescript-eslint/parser": "^7.2.0", + "@types/node": "^20.12.7", + "@typescript-eslint/eslint-plugin": "^7.7.0", + "@typescript-eslint/parser": "^7.7.0", "caller": "^1.1.0", "debug": "^4.3.4", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", "eslint-import-resolver-typescript": "^3.5.2", "eslint-plugin-import": "^2.29.1", - "eslint-plugin-jest": "^27.9.0", + "eslint-plugin-jest": "^28.2.0", "eslint-plugin-node": "^11.1.0", "eslint-plugin-prefer-arrow-functions": "^3.3.2", "eslint-plugin-prettier": "^5.1.3", - "eslint-plugin-simple-import-sort": "^12.0.0", + "eslint-plugin-simple-import-sort": "^12.1.0", "fast-sort": "^3.2.0", "jest": "^29.3.1", "jest-specific-snapshot": "^8.0.0", "semver": "^7.6.0", - "simple-git": "^3.23.0", + "simple-git": "^3.24.0", "ts-jest": "^29.1.2", "ts-node": "^10.9.2", "tsconfig-paths": "^4.1.2", - "typescript": "^5.4.2", + "typescript": "^5.4.5", "yaml": "^2.4.1" }, "bundleDependencies": [ diff --git a/plugin.yaml b/plugin.yaml index 5a1be73eb..4b1358141 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -1,6 +1,6 @@ version: 0.1 # IfChange -required_trunk_version: ">=1.18.2-beta.7" +required_trunk_version: ">=1.21.1-beta.20" # ThenChange tests/repo_tests/config_check.test.ts environments: diff --git a/runtimes/php/plugin.yaml b/runtimes/php/plugin.yaml new file mode 100644 index 000000000..bd4db0d78 --- /dev/null +++ b/runtimes/php/plugin.yaml @@ -0,0 +1,29 @@ +version: 0.1 +downloads: # Needed for the php runtime to install packages + - name: composer + executable: true + version: 2.5.1 + downloads: + - version: 2.5.1 + gpg: CBB3D576F2A0946F + - name: phive + executable: true + version: 0.15.1 + downloads: + - url: https://github.com/phar-io/phive/releases/download/${version}/phive-${version}.phar +runtimes: + definitions: + - type: php + system_version: required + version: ">=8.0.0" + runtime_environment: + - name: HOME + value: ${env.HOME} + - name: PATH + list: ["${env.PATH}"] + linter_environment: + - name: PATH + list: ["${linter}/bin"] + version_commands: + - run: php --version + parse_regex: PHP ${short_semver} diff --git a/runtimes/ruby/plugin.yaml b/runtimes/ruby/plugin.yaml index 64b850c23..c2fb9526a 100644 --- a/runtimes/ruby/plugin.yaml +++ b/runtimes/ruby/plugin.yaml @@ -1,12 +1,12 @@ version: 0.1 downloads: - name: ruby-build - version: 20230330 + version: 20240319 downloads: - os: linux: linux macos: macos - url: https://github.com/rbenv/ruby-build/archive/refs/tags/v20230330.tar.gz + url: https://github.com/rbenv/ruby-build/archive/refs/tags/v20240319.tar.gz strip_components: 1 - name: ruby-install version: 3.1.4 diff --git a/tests/jest_setup.ts b/tests/jest_setup.ts index 2a7ec187f..caf1e4c41 100644 --- a/tests/jest_setup.ts +++ b/tests/jest_setup.ts @@ -2,7 +2,7 @@ import { FileIssue } from "tests/types"; import { osTimeoutMultiplier } from "tests/utils"; import { isDeepStrictEqual } from "util"; -jest.setTimeout(300000 * osTimeoutMultiplier); // 300s or 900s +jest.setTimeout(300000 * osTimeoutMultiplier); /** * Compares 2 file issues to determine exact equality. diff --git a/tests/repo_tests/config_check.test.ts b/tests/repo_tests/config_check.test.ts index 8c1adfcd1..bd364d848 100644 --- a/tests/repo_tests/config_check.test.ts +++ b/tests/repo_tests/config_check.test.ts @@ -10,7 +10,7 @@ import { osTimeoutMultiplier, REPO_ROOT } from "tests/utils"; // trunk-ignore-all(eslint/@typescript-eslint/no-unsafe-argument) // trunk-ignore-all(eslint/@typescript-eslint/no-unsafe-return) -jest.setTimeout(300000 * osTimeoutMultiplier); // 300s or 900s +jest.setTimeout(300000 * osTimeoutMultiplier); /** * This test runs 'trunk config print' from the root of the repository to verify a healthy config. @@ -25,7 +25,7 @@ describe("Global config health check", () => { setupTrunk: true, // NOTE: This version should be kept compatible in lockstep with the `required_trunk_version` in plugin.yaml // IfChange - trunkVersion: "1.18.2-beta.7", + trunkVersion: "1.21.1-beta.20", // ThenChange plugin.yaml }); @@ -165,7 +165,6 @@ describe("Global config health check", () => { "shfmt", "svgo", "taplo", - "terrascan", "tflint", "trivy", "trufflehog", diff --git a/tests/types/index.ts b/tests/types/index.ts index 2c3f8245e..5f0868dfb 100644 --- a/tests/types/index.ts +++ b/tests/types/index.ts @@ -88,6 +88,7 @@ export interface LintAction { parser: string; report: string; cacheHit?: boolean; + cacheExpiration?: string; upstream: boolean; fileGroupName: string; command: string; diff --git a/tests/utils/landing_state.ts b/tests/utils/landing_state.ts index 3b9a67f4f..a306170c8 100644 --- a/tests/utils/landing_state.ts +++ b/tests/utils/landing_state.ts @@ -26,6 +26,7 @@ const normalizePlatformPath = (originalPath: string | undefined) => { const extractLintActionFields = ({ actionDurationMs: _actionDurationMs, cacheHit: _cacheHit, + cacheExpiration: _cacheExpiration, paths: _paths, ...rest }: LintAction): LintAction => ({ diff --git a/tools/difft/difft.test.ts b/tools/difft/difft.test.ts new file mode 100644 index 000000000..40e310e56 --- /dev/null +++ b/tools/difft/difft.test.ts @@ -0,0 +1,6 @@ +import { toolInstallTest } from "tests"; + +toolInstallTest({ + toolName: "difft", + toolVersion: "0.56.1", +}); diff --git a/tools/difft/plugin.yaml b/tools/difft/plugin.yaml new file mode 100644 index 000000000..eb0eb016f --- /dev/null +++ b/tools/difft/plugin.yaml @@ -0,0 +1,22 @@ +version: 0.1 +downloads: + - name: difft + downloads: + - os: + linux: unknown-linux-gnu + macos: apple-darwin + cpu: + x86_64: x86_64 + arm_64: aarch64 + url: https://github.com/Wilfred/difftastic/releases/download/${version}/difft-${cpu}-${os}.tar.gz + - os: + windows: pc-windows-msvc + cpu: + x86_64: x86_64 + url: https://github.com/Wilfred/difftastic/releases/download/${version}/difft-${cpu}-${os}.zip +tools: + definitions: + - name: difft + download: difft + known_good_version: 0.56.1 + shims: [difft] diff --git a/tools/goreleaser/goreleaser.test.ts b/tools/goreleaser/goreleaser.test.ts new file mode 100644 index 000000000..9f798e884 --- /dev/null +++ b/tools/goreleaser/goreleaser.test.ts @@ -0,0 +1,10 @@ +import { toolInstallTest } from "tests"; +import { osTimeoutMultiplier } from "tests/utils"; + +// This install is quite slow on some Linux machines. +jest.setTimeout(600000 * osTimeoutMultiplier); + +toolInstallTest({ + toolName: "goreleaser", + toolVersion: "1.25.1", +}); diff --git a/tools/goreleaser/plugin.yaml b/tools/goreleaser/plugin.yaml new file mode 100644 index 000000000..1717ff9f1 --- /dev/null +++ b/tools/goreleaser/plugin.yaml @@ -0,0 +1,10 @@ +version: 0.1 +tools: + definitions: + - name: goreleaser + known_good_version: 1.25.1 + package: github.com/goreleaser/goreleaser + runtime: go + shims: + - name: goreleaser + target: goreleaser diff --git a/tools/gt/gt.test.ts b/tools/gt/gt.test.ts index 3b45f6c07..22a1912b8 100644 --- a/tools/gt/gt.test.ts +++ b/tools/gt/gt.test.ts @@ -1,20 +1,5 @@ import { makeToolTestConfig, toolTest } from "tests"; -import { skipCPUOS, skipOS } from "tests/utils"; - -toolTest({ - toolName: "gt", - toolVersion: "0.20.19", - testConfigs: [makeToolTestConfig({ command: ["gt", "--version"], expectedOut: "0.20.19" })], - skipTestIf: (version) => { - if (process.env.CI) { - console.log("Skipping gt test for CI until we have better parsing logic."); - return true; - } - - // Unsupported download - return skipCPUOS([{ os: "linux", cpu: "arm64" }])(version); - }, -}); +import { skipOS } from "tests/utils"; toolTest({ toolName: "gt", diff --git a/tools/gt/plugin.yaml b/tools/gt/plugin.yaml index a24042dab..5c1ae2fab 100644 --- a/tools/gt/plugin.yaml +++ b/tools/gt/plugin.yaml @@ -1,32 +1,11 @@ version: 0.1 -downloads: - - name: gt - executable: true - downloads: - - os: - linux: linux - cpu: - x86_64: x86_64 - url: https://github.com/withgraphite/graphite-cli/releases/download/v${version}/gt-${os} - - os: - macos: macos - url: https://github.com/withgraphite/graphite-cli/releases/download/v${version}/gt-${os} - - os: - windows: win - url: https://github.com/withgraphite/graphite-cli/releases/download/v${version}/gt-${os}.exe tools: definitions: - name: gt - version_constraint: ">=1.0.0" + # There used to be a download for older versions, but the assets are no longer available. known_good_version: 1.0.0 runtime: node package: "@withgraphite/graphite-cli" shims: - name: gt target: gt - - name: gt - known_good_version: 0.20.19 - download: gt - shims: - - name: gt - target: gt diff --git a/tools/kubectl/kubectl.test.ts b/tools/kubectl/kubectl.test.ts index 136a9de56..2bcd4cc3e 100644 --- a/tools/kubectl/kubectl.test.ts +++ b/tools/kubectl/kubectl.test.ts @@ -1,16 +1,17 @@ import { makeToolTestConfig, toolTest } from "tests"; -import { skipOS } from "tests/utils"; toolTest({ toolName: "kubectl", toolVersion: "1.25.16", testConfigs: [ makeToolTestConfig({ + // --short flag will be removed in future versions command: ["kubectl", "version", "--short"], expectedOut: "Client Version: v1.25.16", // This fails on no kubectl credentials. Why do you need that for a version check? Who knows... expectedExitCode: 1, }), ], - skipTestIf: skipOS(["win32"]), + // kubectl does not run on Windows. But kubectl is frequently flaky in CI because it spins up a kubectl daemon. + skipTestIf: () => true, }); diff --git a/tools/renovate/renovate.test.ts b/tools/renovate/renovate.test.ts index 1671964a8..f9b24e558 100644 --- a/tools/renovate/renovate.test.ts +++ b/tools/renovate/renovate.test.ts @@ -1,7 +1,7 @@ import { makeToolTestConfig, toolTest } from "tests"; import { osTimeoutMultiplier, skipOS } from "tests/utils"; -jest.setTimeout(600000 * osTimeoutMultiplier); // 300s or 900s +jest.setTimeout(600000 * osTimeoutMultiplier); toolTest({ toolName: "renovate", diff --git a/tools/tofu/plugin.yaml b/tools/tofu/plugin.yaml new file mode 100644 index 000000000..beb10b9d6 --- /dev/null +++ b/tools/tofu/plugin.yaml @@ -0,0 +1,19 @@ +version: 0.1 +downloads: + - name: tofu + version: 1.6.2 + downloads: + - os: + linux: linux + macos: darwin + windows: windows + cpu: + x86_64: amd64 + arm_64: arm64 + url: https://github.com/opentofu/opentofu/releases/download/v${version}/tofu_${version}_${os}_${cpu}.zip +tools: + definitions: + - name: tofu + download: tofu + shims: [tofu] + known_good_version: 1.6.2 diff --git a/tools/tofu/tofu.test.ts b/tools/tofu/tofu.test.ts new file mode 100644 index 000000000..bacd89cca --- /dev/null +++ b/tools/tofu/tofu.test.ts @@ -0,0 +1,11 @@ +import { makeToolTestConfig, toolTest } from "tests"; +toolTest({ + toolName: "tofu", + toolVersion: "1.6.2", + testConfigs: [ + makeToolTestConfig({ + command: ["tofu", "--version"], + expectedOut: "OpenTofu v1.6.2", + }), + ], +}); diff --git a/tools/yq/plugin.yaml b/tools/yq/plugin.yaml new file mode 100644 index 000000000..79c05943c --- /dev/null +++ b/tools/yq/plugin.yaml @@ -0,0 +1,23 @@ +version: 0.1 +downloads: + - name: yq + downloads: + - os: + linux: linux + macos: darwin + cpu: + x86_64: 386 + arm_64: arm64 + url: https://github.com/mikefarah/yq/releases/download/v${version}/yq_${os}_${cpu}.tar.gz + - os: + windows: windows + cpu: + x86_64: 386 + arm_64: arm64 + url: https://github.com/mikefarah/yq/releases/download/v${version}/yq_${os}_${cpu}.zip +tools: + definitions: + - name: yq + download: yq + known_good_version: 4.40.5 + shims: [yq] diff --git a/tools/yq/yq.test.ts b/tools/yq/yq.test.ts new file mode 100644 index 000000000..33c1d3c48 --- /dev/null +++ b/tools/yq/yq.test.ts @@ -0,0 +1,6 @@ +import { toolInstallTest } from "tests"; + +toolInstallTest({ + toolName: "yq", + toolVersion: "4.40.5", +});