diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index ae59099..7d28675 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -11,6 +11,9 @@ # name: "CodeQL" +# default token permissions: none +permissions: {} + on: push: branches: [ main ] @@ -24,6 +27,9 @@ jobs: analyze: name: Analyze runs-on: ubuntu-latest + permissions: + # required for all workflows + security-events: write strategy: fail-fast: false @@ -32,21 +38,21 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Install Go - uses: actions/setup-go@v5 + uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 with: go-version-file: go.mod # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v3 + uses: github/codeql-action/init@f09c1c0a94de965c15400f5634aa42fac8fb8f88 # v3.27.5 with: languages: ${{ matrix.language }} - name: Autobuild - uses: github/codeql-action/autobuild@v3 + uses: github/codeql-action/autobuild@f09c1c0a94de965c15400f5634aa42fac8fb8f88 # v3.27.5 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 + uses: github/codeql-action/autobuild@f09c1c0a94de965c15400f5634aa42fac8fb8f88 # v3.27.5 diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 138dd02..ca1d1a3 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -1,5 +1,8 @@ name: Lint (pre-commit) +# default token permissions: none +permissions: {} + on: pull_request: push: @@ -7,9 +10,9 @@ jobs: lint: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Install Go - uses: actions/setup-go@v5 + uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 with: go-version: v1.22.x cache: true diff --git a/.github/workflows/regression.yml b/.github/workflows/regression.yml index 19cebb1..03c8804 100644 --- a/.github/workflows/regression.yml +++ b/.github/workflows/regression.yml @@ -1,5 +1,8 @@ name: Regression Tests +# default token permissions: none +permissions: {} + on: push: branches: @@ -24,9 +27,9 @@ jobs: runs-on: ${{ matrix.os }} steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Install Go - uses: actions/setup-go@v5 + uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 with: go-version: ${{ matrix.go-version }} cache: true diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5861f6c..6c145ab 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,5 +1,8 @@ name: goreleaser +# default token permissions: none +permissions: {} + on: push: tags: @@ -8,34 +11,39 @@ on: jobs: goreleaser: runs-on: ubuntu-latest + permissions: + # publish archives for releases + contents: write + # publish packages (container images) + packages: write steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: fetch-depth: 0 - name: Set up QEMU - uses: docker/setup-qemu-action@v3 + uses: docker/setup-qemu-action@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf # v3.2.0 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@c47758b77c9736f4b2ef4073d4d51994fabfe349 # v3.7.1 - name: Set up Go - uses: actions/setup-go@v5 + uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 with: go-version: ^1.22 cache: true - name: Login to GitHub Container Registry - uses: docker/login-action@v3 + uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Run GoReleaser - uses: goreleaser/goreleaser-action@v5 + uses: goreleaser/goreleaser-action@9ed2f89a662bf1735a48bc8557fd212fa902bebf # v6.1.0 if: startsWith(github.ref, 'refs/tags/') with: version: latest diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 72ad80a..5afa1c4 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -32,12 +32,12 @@ jobs: steps: - name: "Checkout code" - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - name: "Run analysis" - uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1 + uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0 with: results_file: results.sarif results_format: sarif @@ -59,7 +59,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@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 with: name: SARIF file path: results.sarif @@ -67,6 +67,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@8a470fddafa5cbb6266ee11b37ef4d8aae19c571 # v3.24.6 + uses: github/codeql-action/upload-sarif@f09c1c0a94de965c15400f5634aa42fac8fb8f88 # v3.27.5 with: sarif_file: results.sarif diff --git a/Dockerfile b/Dockerfile index c86d5eb..9d13af8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ # Copyright 2022 OWASP Core Rule Set Project # SPDX-License-Identifier: Apache-2.0 -FROM alpine:3 +FROM alpine:3.20.3@sha256:1e42bbe2508154c9126d48c2b8a75420c3544343bf86fd041fb7527e017a4b4a RUN apk add --no-cache ca-certificates diff --git a/LICENSE b/LICENSE index e69de29..261eeb9 100644 --- a/LICENSE +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md index dd01a4c..9bd0741 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ # crs-toolchain -The CRS developer's utility belt. The documentation lives at [coreruleset.org](https://coreruleset.org/docs/development/crs_toolchain/). +[![Regression Tests](https://github.com/coreruleset/crs-toolchain/actions/workflows/regression.yml/badge.svg)](https://github.com/coreruleset/crs-toolchain/actions/workflows/regression.yml) +[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/coreruleset/crs-toolchain/badge)](https://securityscorecards.dev/viewer/?uri=github.com/coreruleset/crs-toolchain) + +The CRS developer's utility belt. The documentation lives at [coreruleset.org](https://coreruleset.org/docs/development/crs_toolchain/). \ No newline at end of file diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..817ff05 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,33 @@ +# Security Policy + +This document includes information about the vulnerability reporting, patch, +release, and disclosure processes, as well as general security posture. + +# Reporting Security Issues + +Vulnerabilities are reported privately via GitHub's +[Security Advisories](https://docs.github.com/en/code-security/security-advisories) +feature. Please use the following link to submit your vulnerability: +[Report a vulnerability](https://github.com/coreruleset/crs-toolchain/security/advisories/new) + +Please see +[Privately reporting a security vulnerability](https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing/privately-reporting-a-security-vulnerability#privately-reporting-a-security-vulnerability) +for more information on how to submit a vulnerability using GitHub's interface. + +Our vulnerability management team will respond within 3 working days of your +email. If the issue is confirmed as a vulnerability, we will open a +Security Advisory and acknowledge your contributions as part of it. This project +follows a 90 day disclosure timeline. + + +### When Should I Report a Vulnerability? + +- You think you discovered a potential security vulnerability in crs-toolchain +- You are unsure how a vulnerability affects crs-toolchain +- You think you discovered a vulnerability in another project that crs-toolchain depends on + - For projects with their own vulnerability reporting and disclosure process, please report it directly there + +### When Should I NOT Report a Vulnerability? + +- You need help applying security related updates +- Your issue is not security related diff --git a/chore/update_copyright.go b/chore/update_copyright.go index 3e1c30f..eb1ff50 100644 --- a/chore/update_copyright.go +++ b/chore/update_copyright.go @@ -12,8 +12,8 @@ import ( "github.com/rs/zerolog/log" - "github.com/coreruleset/crs-toolchain/context" - "github.com/coreruleset/crs-toolchain/regex" + "github.com/coreruleset/crs-toolchain/v2/context" + "github.com/coreruleset/crs-toolchain/v2/regex" ) var logger = log.With().Str("component", "update-copyright").Logger() diff --git a/cmd/chore_update_copyright.go b/cmd/chore_update_copyright.go index 9541019..7555bb2 100644 --- a/cmd/chore_update_copyright.go +++ b/cmd/chore_update_copyright.go @@ -10,8 +10,8 @@ import ( "github.com/Masterminds/semver/v3" "github.com/spf13/cobra" - "github.com/coreruleset/crs-toolchain/chore" - "github.com/coreruleset/crs-toolchain/context" + "github.com/coreruleset/crs-toolchain/v2/chore" + "github.com/coreruleset/crs-toolchain/v2/context" ) var choreUpdateCopyrightCmd = createChoreUpdateCopyrightCommand() diff --git a/cmd/chore_update_copyright_test.go b/cmd/chore_update_copyright_test.go index 5191abd..05c446e 100644 --- a/cmd/chore_update_copyright_test.go +++ b/cmd/chore_update_copyright_test.go @@ -50,7 +50,7 @@ func (s *choreUpdateCopyrightTestSuite) SetupTest() { s.FileExists(path.Join(s.rulesDir, "TEST-900.conf")) s.writeFile(path.Join(s.tempDir, "crs-setup.conf.example"), `# ------------------------------------------------------------------------ -# OWASP ModSecurity Core Rule Set ver.4.0.0-rc1 +# OWASP ModSecurity Core Rule Set ver.4.9.0-dev # Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved. # Copyright (c) 2021-2022 Core Rule Set project. All rights reserved. # @@ -116,6 +116,25 @@ func (s *choreUpdateCopyrightTestSuite) TestUpdateCopyright_ErrIfNoVersion() { s.Error(err, ErrUpdateCopyrightWithoutVersion) } +func (s *choreUpdateCopyrightTestSuite) TestUpdateCopyright_DevRelease() { + rootCmd.SetArgs([]string{"-d", s.tempDir, "chore", "update-copyright", "-v", "5.4.3-dev"}) + cmd, _ := rootCmd.ExecuteC() + + s.Equal("update-copyright", cmd.Name()) + + // get year from file contents + contents, err := os.ReadFile(path.Join(s.rulesDir, "TEST-900.conf")) + s.Require().NoError(err) + s.Contains(string(contents), "OWASP ModSecurity Core Rule Set ver.5.4.3-dev") + s.NotContains(string(contents), "OWASP ModSecurity Core Rule Set ver.5.4.3-dev-dev") + + // check that crs-setup.conf.example was also modified + contents, err = os.ReadFile(path.Join(s.tempDir, "crs-setup.conf.example")) + s.Require().NoError(err) + s.Contains(string(contents), "OWASP ModSecurity Core Rule Set ver.5.4.3-dev") + s.NotContains(string(contents), "OWASP ModSecurity Core Rule Set ver.5.4.3-dev-dev") +} + func (s *choreUpdateCopyrightTestSuite) writeFile(filename string, contents string) { err := os.WriteFile(filename, []byte(contents), fs.ModePerm) s.Require().NoError(err) diff --git a/cmd/regex.go b/cmd/regex.go index d7c1fb7..ee7501c 100644 --- a/cmd/regex.go +++ b/cmd/regex.go @@ -10,7 +10,7 @@ import ( "github.com/spf13/cobra" - "github.com/coreruleset/crs-toolchain/regex" + "github.com/coreruleset/crs-toolchain/v2/regex" ) // generateCmd represents the generate command diff --git a/cmd/regex_compare.go b/cmd/regex_compare.go index 133f480..3c87dab 100644 --- a/cmd/regex_compare.go +++ b/cmd/regex_compare.go @@ -18,9 +18,9 @@ import ( "github.com/spf13/cobra" - "github.com/coreruleset/crs-toolchain/context" - "github.com/coreruleset/crs-toolchain/regex" - "github.com/coreruleset/crs-toolchain/regex/processors" + "github.com/coreruleset/crs-toolchain/v2/context" + "github.com/coreruleset/crs-toolchain/v2/regex" + "github.com/coreruleset/crs-toolchain/v2/regex/processors" ) type ComparisonError struct { @@ -132,8 +132,8 @@ func performCompare(processAll bool, ctx *processors.Context) error { if err != nil && len(chainOffsetString) > 0 { return errors.New("failed to match chain offset. Value must not be larger than 255") } - rx := runAssemble(filePath, ctx) - err = processRegexForCompare(id, uint8(chainOffset), rx, ctx) + regex := runAssemble(filePath) + err = processRegexForCompare(id, uint8(chainOffset), regex, ctx) if err != nil && errors.Is(err, &ComparisonError{}) { failed = true return nil @@ -153,7 +153,7 @@ func performCompare(processAll bool, ctx *processors.Context) error { return &ComparisonError{} } } else { - regex := runAssemble(path.Join(ctx.RootContext().AssemblyDir(), ruleValues.fileName), ctx) + regex := runAssemble(path.Join(ctx.RootContext().AssemblyDir(), ruleValues.fileName)) return processRegexForCompare(ruleValues.id, ruleValues.chainOffset, regex, ctx) } return nil @@ -176,7 +176,7 @@ func processRegexForCompare(ruleId string, chainOffset uint8, regex string, ctxt logger.Debug().Msgf("Processing regex-assembly file %s", filePath) currentRegex := readCurrentRegex(filePath, ruleId, chainOffset) - return compareRegex(filePath, ruleId, chainOffset, regex, currentRegex) + return compareRegex(ruleId, regex, currentRegex) } func readCurrentRegex(filePath string, ruleId string, chainOffset uint8) string { @@ -219,7 +219,7 @@ func readCurrentRegex(filePath string, ruleId string, chainOffset uint8) string return found[0][2] } -func compareRegex(filePath string, ruleId string, chainOffset uint8, generatedRegex string, currentRegex string) error { +func compareRegex(ruleId string, generatedRegex string, currentRegex string) error { if currentRegex == generatedRegex { fmt.Println("Regex of", ruleId, "has not changed") return nil diff --git a/cmd/regex_format.go b/cmd/regex_format.go index d3f9c92..57cbb48 100644 --- a/cmd/regex_format.go +++ b/cmd/regex_format.go @@ -16,10 +16,10 @@ import ( "github.com/spf13/cobra" - "github.com/coreruleset/crs-toolchain/context" - "github.com/coreruleset/crs-toolchain/regex" - "github.com/coreruleset/crs-toolchain/regex/parser" - "github.com/coreruleset/crs-toolchain/regex/processors" + "github.com/coreruleset/crs-toolchain/v2/context" + "github.com/coreruleset/crs-toolchain/v2/regex" + "github.com/coreruleset/crs-toolchain/v2/regex/parser" + "github.com/coreruleset/crs-toolchain/v2/regex/processors" ) const ( diff --git a/cmd/regex_generate.go b/cmd/regex_generate.go index 3a8fa91..e460bc3 100644 --- a/cmd/regex_generate.go +++ b/cmd/regex_generate.go @@ -11,9 +11,9 @@ import ( "github.com/spf13/cobra" - "github.com/coreruleset/crs-toolchain/context" - "github.com/coreruleset/crs-toolchain/regex/operators" - "github.com/coreruleset/crs-toolchain/regex/processors" + "github.com/coreruleset/crs-toolchain/v2/context" + "github.com/coreruleset/crs-toolchain/v2/regex/operators" + "github.com/coreruleset/crs-toolchain/v2/regex/processors" ) // generateCmd represents the generate command diff --git a/cmd/regex_update.go b/cmd/regex_update.go index cad06cf..5a60a36 100644 --- a/cmd/regex_update.go +++ b/cmd/regex_update.go @@ -17,10 +17,10 @@ import ( "github.com/spf13/cobra" - "github.com/coreruleset/crs-toolchain/context" - "github.com/coreruleset/crs-toolchain/regex" - "github.com/coreruleset/crs-toolchain/regex/operators" - "github.com/coreruleset/crs-toolchain/regex/processors" + "github.com/coreruleset/crs-toolchain/v2/context" + "github.com/coreruleset/crs-toolchain/v2/regex" + "github.com/coreruleset/crs-toolchain/v2/regex/operators" + "github.com/coreruleset/crs-toolchain/v2/regex/processors" ) // updateCmd represents the update command @@ -129,8 +129,7 @@ func performUpdate(processAll bool, ctx *processors.Context) { } } -func runAssemble(filePath string, ctx *processors.Context) string { - // FIXME: duplicated in generate.go +func runAssemble(filePath string) string { rootContext := context.New(rootValues.workingDirectory.String(), rootValues.configurationFileName.String()) ctxt := processors.NewContext(rootContext) assembler := operators.NewAssembler(ctxt) @@ -158,7 +157,7 @@ func runAssemble(filePath string, ctx *processors.Context) string { func processRule(ruleId string, chainOffset uint8, dataFilePath string, ctxt *processors.Context) { logger.Info().Msgf("Processing %s, chain offset %d", ruleId, chainOffset) - regex := runAssemble(dataFilePath, ctxt) + regex := runAssemble(dataFilePath) rulePrefix := ruleId[:3] matches, err := filepath.Glob(fmt.Sprintf("%s/*-%s-*", ctxt.RootContext().RulesDir(), rulePrefix)) diff --git a/cmd/root_test.go b/cmd/root_test.go index 3d669eb..76a079d 100644 --- a/cmd/root_test.go +++ b/cmd/root_test.go @@ -12,7 +12,7 @@ import ( "github.com/rs/zerolog" "github.com/stretchr/testify/suite" - loggerConfig "github.com/coreruleset/crs-toolchain/logger" + loggerConfig "github.com/coreruleset/crs-toolchain/v2/logger" ) type rootTestSuite struct { diff --git a/cmd/self_update.go b/cmd/self_update.go index 691d1bf..b832509 100644 --- a/cmd/self_update.go +++ b/cmd/self_update.go @@ -6,7 +6,7 @@ package cmd import ( "github.com/spf13/cobra" - "github.com/coreruleset/crs-toolchain/internal/updater" + "github.com/coreruleset/crs-toolchain/v2/internal/updater" ) // selfUpdateCmd represents the self-update command diff --git a/cmd/self_update_test.go b/cmd/self_update_test.go index eafcade..b73630a 100644 --- a/cmd/self_update_test.go +++ b/cmd/self_update_test.go @@ -14,7 +14,7 @@ import ( "github.com/stretchr/testify/suite" - "github.com/coreruleset/crs-toolchain/internal/updater" + "github.com/coreruleset/crs-toolchain/v2/internal/updater" ) type selfUpdateTestSuite struct { diff --git a/cmd/util_renumber_tests.go b/cmd/util_renumber_tests.go index 999ada9..d17fa34 100644 --- a/cmd/util_renumber_tests.go +++ b/cmd/util_renumber_tests.go @@ -11,8 +11,8 @@ import ( "github.com/spf13/cobra" - "github.com/coreruleset/crs-toolchain/context" - "github.com/coreruleset/crs-toolchain/util" + "github.com/coreruleset/crs-toolchain/v2/context" + "github.com/coreruleset/crs-toolchain/v2/util" ) // renumberTestsCommand represents the update command diff --git a/cmd/util_renumber_tests_test.go b/cmd/util_renumber_tests_test.go index 2e90f7a..bea16ce 100644 --- a/cmd/util_renumber_tests_test.go +++ b/cmd/util_renumber_tests_test.go @@ -11,7 +11,7 @@ import ( "github.com/stretchr/testify/suite" - "github.com/coreruleset/crs-toolchain/util" + "github.com/coreruleset/crs-toolchain/v2/util" ) type renumberTestsTestSuite struct { @@ -77,26 +77,26 @@ func TestRunRenumberTestsTestSuite(t *testing.T) { } func (s *renumberTestsTestSuite) TestRenumberTests_WithYaml() { - s.writeTestFile("123456.yaml", "test_title: homer") + s.writeTestFile("123456.yaml", "test_id: homer") rootCmd.SetArgs([]string{"-d", s.tempDir, "util", "renumber-tests", "123456"}) _, err := rootCmd.ExecuteC() s.Require().NoError(err) actual := s.readTestFile("123456.yaml") - s.Equal("test_title: 123456-1\n", actual) + s.Equal("test_id: 1\n", actual) } func (s *renumberTestsTestSuite) TestRenumberTests_WithYml() { - s.writeTestFile("123456.yml", "test_title: homer") + s.writeTestFile("123456.yml", "test_id: homer") rootCmd.SetArgs([]string{"-d", s.tempDir, "util", "renumber-tests", "123456"}) _, err := rootCmd.ExecuteC() s.Require().NoError(err) actual := s.readTestFile("123456.yml") - s.Equal("test_title: 123456-1\n", actual) + s.Equal("test_id: 1\n", actual) } -func (s *renumberTestsTestSuite) TestRenumberTests_NormalRuleIdWith() { +func (s *renumberTestsTestSuite) TestRenumberTests_NormalRuleId() { s.writeTestFile("123456.yaml", "") rootCmd.SetArgs([]string{"-d", s.tempDir, "util", "renumber-tests", "123456"}) cmd, _ := rootCmd.ExecuteC() @@ -130,7 +130,7 @@ func (s *renumberTestsTestSuite) TestRenumberTests_Dash() { } func (s *renumberTestsTestSuite) TestRenumberTests_CheckOnly() { - contents := "test_title: homer" + contents := "test_id: homer" s.writeTestFile("123456.yaml", contents) rootCmd.SetArgs([]string{"-d", s.tempDir, "util", "renumber-tests", "-c", "123456"}) _, err := rootCmd.ExecuteC() @@ -144,6 +144,58 @@ func (s *renumberTestsTestSuite) TestRenumberTests_CheckOnly() { func (s *renumberTestsTestSuite) TestRenumberTests_GitHubOutput() { read := s.captureStdout() + contents := "test_id: homer" + s.writeTestFile("123456.yaml", contents) + rootCmd.SetArgs([]string{"-d", s.tempDir, "util", "renumber-tests", "-cao", "github"}) + _, err := rootCmd.ExecuteC() + + s.ErrorIs(err, &util.TestNumberingError{}) + + buffer := make([]byte, 1024) + _, err = read.Read(buffer) + s.Require().NoError(err) + + output := string(buffer) + s.Contains(output, "::warning::Test file not properly numbered") + s.Contains(output, "::error::") + s.Contains(output, "Please run `crs-toolchain util renumber-tests --all`") +} + +func (s *renumberTestsTestSuite) TestRenumberTests_Legacy_WithYaml() { + s.writeTestFile("123456.yaml", "test_title: homer") + rootCmd.SetArgs([]string{"-d", s.tempDir, "util", "renumber-tests", "123456"}) + _, err := rootCmd.ExecuteC() + s.Require().NoError(err) + + actual := s.readTestFile("123456.yaml") + s.Equal("test_title: 123456-1\n", actual) +} + +func (s *renumberTestsTestSuite) TestRenumberTests_Legacy_WithYml() { + s.writeTestFile("123456.yml", "test_title: homer") + rootCmd.SetArgs([]string{"-d", s.tempDir, "util", "renumber-tests", "123456"}) + _, err := rootCmd.ExecuteC() + s.Require().NoError(err) + + actual := s.readTestFile("123456.yml") + s.Equal("test_title: 123456-1\n", actual) +} + +func (s *renumberTestsTestSuite) TestRenumberTests_Legacy_CheckOnly() { + contents := "test_title: homer" + s.writeTestFile("123456.yaml", contents) + rootCmd.SetArgs([]string{"-d", s.tempDir, "util", "renumber-tests", "-c", "123456"}) + _, err := rootCmd.ExecuteC() + + s.EqualError(err, "Tests are not properly numbered") + + actual := s.readTestFile("123456.yaml") + s.Equal(contents, actual) +} + +func (s *renumberTestsTestSuite) TestRenumberTests_Legacy_GitHubOutput() { + read := s.captureStdout() + contents := "test_title: homer" s.writeTestFile("123456.yaml", contents) rootCmd.SetArgs([]string{"-d", s.tempDir, "util", "renumber-tests", "-cao", "github"}) diff --git a/cmd/version.go b/cmd/version.go index 52e8596..d058a78 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -9,7 +9,7 @@ import ( "github.com/spf13/cobra" - "github.com/coreruleset/crs-toolchain/internal/updater" + "github.com/coreruleset/crs-toolchain/v2/internal/updater" ) func init() { diff --git a/context/context.go b/context/context.go index 66ef6ea..b4d23c9 100644 --- a/context/context.go +++ b/context/context.go @@ -4,7 +4,7 @@ package context import ( - "github.com/coreruleset/crs-toolchain/configuration" + "github.com/coreruleset/crs-toolchain/v2/configuration" ) type Context struct { diff --git a/go.mod b/go.mod index 15817c4..1215191 100644 --- a/go.mod +++ b/go.mod @@ -1,50 +1,47 @@ -module github.com/coreruleset/crs-toolchain +module github.com/coreruleset/crs-toolchain/v2 go 1.22 require ( - dario.cat/mergo v1.0.0 + dario.cat/mergo v1.0.1 github.com/magefile/mage v1.15.0 - github.com/spf13/cobra v1.8.0 + github.com/spf13/cobra v1.8.1 ) require ( - github.com/Masterminds/semver/v3 v3.2.1 - github.com/creativeprojects/go-selfupdate v1.1.3 + github.com/Masterminds/semver/v3 v3.3.1 + github.com/creativeprojects/go-selfupdate v1.4.0 github.com/google/uuid v1.6.0 - github.com/itchyny/rassemble-go v0.1.0 + github.com/itchyny/rassemble-go v0.1.2 gopkg.in/yaml.v3 v3.0.1 ) require ( - code.gitea.io/sdk/gitea v0.17.1 // indirect + code.gitea.io/sdk/gitea v0.19.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/davidmz/go-pageant v1.0.2 // indirect github.com/go-fed/httpsig v1.1.0 // indirect - github.com/golang/protobuf v1.5.3 // indirect github.com/google/go-github/v30 v30.1.0 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect - github.com/hashicorp/go-retryablehttp v0.7.4 // indirect - github.com/hashicorp/go-version v1.6.0 // indirect + github.com/hashicorp/go-retryablehttp v0.7.7 // indirect + github.com/hashicorp/go-version v1.7.0 // indirect github.com/kr/pretty v0.2.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.19 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/ulikunitz/xz v0.5.11 // indirect - github.com/xanzy/go-gitlab v0.95.2 // indirect - golang.org/x/crypto v0.17.0 // indirect - golang.org/x/oauth2 v0.15.0 // indirect - golang.org/x/sys v0.15.0 // indirect - golang.org/x/time v0.3.0 // indirect - google.golang.org/appengine v1.6.8 // indirect - google.golang.org/protobuf v1.31.0 // indirect + github.com/ulikunitz/xz v0.5.12 // indirect + github.com/xanzy/go-gitlab v0.112.0 // indirect + golang.org/x/crypto v0.28.0 // indirect + golang.org/x/oauth2 v0.23.0 // indirect + golang.org/x/sys v0.26.0 // indirect + golang.org/x/time v0.7.0 // indirect gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect ) require ( github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/rs/zerolog v1.32.0 + github.com/rs/zerolog v1.33.0 github.com/spf13/pflag v1.0.5 // indirect - github.com/stretchr/testify v1.9.0 + github.com/stretchr/testify v1.10.0 ) diff --git a/go.sum b/go.sum index 199dd2f..77e1694 100644 --- a/go.sum +++ b/go.sum @@ -1,28 +1,34 @@ -code.gitea.io/sdk/gitea v0.17.1 h1:3jCPOG2ojbl8AcfaUCRYLT5MUcBMFwS0OSK2mA5Zok8= -code.gitea.io/sdk/gitea v0.17.1/go.mod h1:aCnBqhHpoEWA180gMbaCtdX9Pl6BWBAuuP2miadoTNM= +code.gitea.io/sdk/gitea v0.18.0 h1:+zZrwVmujIrgobt6wVBWCqITz6bn1aBjnCUHmpZrerI= +code.gitea.io/sdk/gitea v0.18.0/go.mod h1:IG9xZJoltDNeDSW0qiF2Vqx5orMWa7OhVWrjvrd5NpI= +code.gitea.io/sdk/gitea v0.19.0 h1:8I6s1s4RHgzxiPHhOQdgim1RWIRcr0LVMbHBjBFXq4Y= +code.gitea.io/sdk/gitea v0.19.0/go.mod h1:IG9xZJoltDNeDSW0qiF2Vqx5orMWa7OhVWrjvrd5NpI= dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= +dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= +github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0= +github.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= +github.com/Masterminds/semver/v3 v3.3.1 h1:QtNSWtVZ3nBfk8mAOu/B6v7FMJ+NHTIgUPi7rj+4nv4= +github.com/Masterminds/semver/v3 v3.3.1/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/creativeprojects/go-selfupdate v1.1.3 h1:p+Mx6rCZGBMrYWa5XhHCHYsS+w9v21fSfItuEUlxIGo= -github.com/creativeprojects/go-selfupdate v1.1.3/go.mod h1:sL4LPc1cei5kkQ8MG9EmhvUdLEcbfn7Z2nY+aYfAvrA= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/creativeprojects/go-selfupdate v1.3.0 h1:Hs+14cJ7Um7xbRpmkmrKEfkZGwec3vZLPWTVEFwYXBc= +github.com/creativeprojects/go-selfupdate v1.3.0/go.mod h1:uYJeumb6ECaI6bhc5dvH3Htjz1KoMArQjFt1P8m71Tc= +github.com/creativeprojects/go-selfupdate v1.4.0 h1:4ePPd2CPCNl/YoPXeVxpuBLDUZh8rMEKP5ac+1Y/r5c= +github.com/creativeprojects/go-selfupdate v1.4.0/go.mod h1:oPG7LmzEmS6OxfqEm620k5VKxP45xFZNKMkp4V5qqUY= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davidmz/go-pageant v1.0.2 h1:bPblRCh5jGU+Uptpz6LgMZGD5hJoOt7otgT454WvHn0= github.com/davidmz/go-pageant v1.0.2/go.mod h1:P2EDDnMqIwG5Rrp05dTRITj9z2zpGcD9efWSkTNKLIE= +github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/go-fed/httpsig v1.1.0 h1:9M+hb0jkEICD8/cAiNqEB66R87tTINszBRTjwjQzWcI= github.com/go-fed/httpsig v1.1.0/go.mod h1:RCMrTZvN1bJYtofsG4rd5NaO5obxQ5xBkdiS7xsT7bM= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-github/v30 v30.1.0 h1:VLDx+UolQICEOKu2m4uAoMti1SxuEBAl7RSEG16L+Oo= @@ -34,16 +40,16 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= -github.com/hashicorp/go-hclog v0.9.2 h1:CG6TE5H9/JXsFWJCfoIVpKFIkFe6ysEuHirp4DxCsHI= -github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= -github.com/hashicorp/go-retryablehttp v0.7.4 h1:ZQgVdpTdAL7WpMIwLzCfbalOcSUdkDZnpUv3/+BxzFA= -github.com/hashicorp/go-retryablehttp v0.7.4/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8= -github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= -github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= +github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU= +github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk= +github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= +github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/itchyny/rassemble-go v0.1.0 h1:PaH3f4XNlFx2SImEezdREmkW+/w2t3aLZS9xleHEPjY= -github.com/itchyny/rassemble-go v0.1.0/go.mod h1:3P4ZuUAYUp+hBvdkVPrL/IhiR0U5CLeCLaqREgGJB7c= +github.com/itchyny/rassemble-go v0.1.2 h1:4Jtms+JnlXJPbBfeXzdgXf/TJnFWilFzA6bXn+ZF6yM= +github.com/itchyny/rassemble-go v0.1.2/go.mod h1:VWc9FWUhn/1G2gGivJlq+K9toP2ylbKOwO46P/bPZFo= github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -54,94 +60,69 @@ github.com/magefile/mage v1.15.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXq github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= -github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0= -github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= +github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= -github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= +github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= +github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8= -github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= -github.com/xanzy/go-gitlab v0.95.2 h1:4p0IirHqEp5f0baK/aQqr4TR57IsD+8e4fuyAA1yi88= -github.com/xanzy/go-gitlab v0.95.2/go.mod h1:ETg8tcj4OhrB84UEgeE8dSuV/0h4BBL1uOV/qK0vlyI= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc= +github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= +github.com/xanzy/go-gitlab v0.106.0 h1:EDfD03K74cIlQo2EducfiupVrip+Oj02bq9ofw5F8sA= +github.com/xanzy/go-gitlab v0.106.0/go.mod h1:ETg8tcj4OhrB84UEgeE8dSuV/0h4BBL1uOV/qK0vlyI= +github.com/xanzy/go-gitlab v0.112.0 h1:6Z0cqEooCvBMfBIHw+CgO4AKGRV8na/9781xOb0+DKw= +github.com/xanzy/go-gitlab v0.112.0/go.mod h1:wKNKh3GkYDMOsGmnfuX+ITCmDuSDWFO0G+C4AygL9RY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= -golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= +golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= +golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= +golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.15.0 h1:s8pnnxNVzjWyrvYdFUQq5llS1PX2zhPXmccZv99h7uQ= -golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= +golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= +golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= -golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= +golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= -golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= +golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= +golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= -golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ= +golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= -google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/magefile.go b/magefile.go index 3d36a1c..d4d0561 100644 --- a/magefile.go +++ b/magefile.go @@ -17,18 +17,26 @@ import ( "github.com/magefile/mage/sh" ) -var addLicenseVersion = "v1.1.1" // https://github.com/google/addlicense +var addLicenseVersion = "v1.1.1" // https://github.com/google/addlicense/releases var golangCILintVer = "v1.56.2" // https://github.com/golangci/golangci-lint/releases -var gosImportsVer = "v0.3.8" // https://github.com/rinchsan/gosimports/releases/tag/v0.1.5 -var goGciVer = "v0.10.1" // https://github.com/daixiang0/gci/releases/tag/v0.8.2 +var gosImportsVer = "v0.3.8" // https://github.com/rinchsan/gosimports/releases +var goGciVer = "v0.13.0" // https://github.com/daixiang0/gci/releases/tag var errCommitFormatting = errors.New("files not formatted, please commit formatting changes") var errNoGitDir = errors.New("no .git directory found") // Format formats code in this repository. func Format() error { - if err := sh.RunV("go", "mod", "tidy"); err != nil { - return err + return FormatAndTidy(true) +} + +// Format formats code in this repository. +// Run `go mod tidy` if `tidy` is true. +func FormatAndTidy(tidy bool) error { + if tidy { + if err := sh.RunV("go", "mod", "tidy"); err != nil { + return err + } } // addlicense strangely logs skipped files to stderr despite not being erroneous, so use the long sh.Exec form to // discard stderr too. @@ -72,7 +80,7 @@ func Lint() error { sh.Run("git", "stash", "-k", "-u") // stash unstagged changes so they don't interfere with git diff below defer sh.Run("git", "stash", "pop") - mg.SerialDeps(Format) + mg.SerialDeps(mg.F(FormatAndTidy, false)) if sh.Run("git", "diff", "--exit-code") != nil { return errCommitFormatting diff --git a/main.go b/main.go index ddf61d9..9dfad4d 100644 --- a/main.go +++ b/main.go @@ -4,9 +4,9 @@ package main import ( - _ "github.com/coreruleset/crs-toolchain/logger" + _ "github.com/coreruleset/crs-toolchain/v2/logger" - "github.com/coreruleset/crs-toolchain/cmd" + "github.com/coreruleset/crs-toolchain/v2/cmd" ) // nolint: gochecknoglobals diff --git a/regex/definitions.go b/regex/definitions.go index 23e968f..b1609eb 100644 --- a/regex/definitions.go +++ b/regex/definitions.go @@ -70,6 +70,10 @@ var RuleIdFileNameRegex = regexp.MustCompile(`^(\d{6})(?:-chain(\d+))?(?:\.ra)?$ // The rule ID is captured in group 1, the optional extension in group 2. var RuleIdTestFileNameRegex = regexp.MustCompile(`^(\d{6})(?:\.ya?ml)?$`) +// TestIdRegex matches any test_id line in test YAML files (test_id: ). +// Everything up to the value of the test ID is captured in group 1, test ID in group 2. +var TestIdRegex = regexp.MustCompile(`(.*test_id:)\s+(.*$)`) + // TestTitleRegex matches any test_title line in test YAML files (test_title: ""). // Everything up to the value of the test title is captured in group 1, test title in group 2. var TestTitleRegex = regexp.MustCompile(`(.*test_title:)\s+(.*$)`) @@ -94,9 +98,9 @@ var CRSCopyrightYearRegex = regexp.MustCompile(`^(# Copyright \(c\) 2021-)(\d{4} // CRSYearSecRuleVerRegex matches the version in the SecRule part of the text, (e.g. ver:'OWASP_CRS/4.0.0') // setup example, and rule files. // The matched year will be captured in group 2. -var CRSYearSecRuleVerRegex = regexp.MustCompile(`(ver:'OWASP_CRS/)(\d+\.\d+\.\d+(-rc\d+)?)`) +var CRSYearSecRuleVerRegex = regexp.MustCompile(`(ver:'OWASP_CRS/)(\d+\.\d+\.\d+(-[a-z0-9-]+)?)`) // CRSVersionComponentSignatureRegex matches the version in the SecComponentSignature part of the text, (e.g. OWASP_CRS/4.0.0-rc1) // setup example, and rule files. // The matched year will be captured in group 2. -var CRSVersionComponentSignatureRegex = regexp.MustCompile(`^(SecComponentSignature "OWASP_CRS/)(\d+\.\d+\.\d+(-rc\d+)?)`) +var CRSVersionComponentSignatureRegex = regexp.MustCompile(`^(SecComponentSignature "OWASP_CRS/)(\d+\.\d+\.\d+(-[a-z0-9-]+)?)`) diff --git a/regex/operators/assembler.go b/regex/operators/assembler.go index 0003e7d..e9b5262 100644 --- a/regex/operators/assembler.go +++ b/regex/operators/assembler.go @@ -14,9 +14,9 @@ import ( "github.com/itchyny/rassemble-go" - "github.com/coreruleset/crs-toolchain/regex" - "github.com/coreruleset/crs-toolchain/regex/parser" - "github.com/coreruleset/crs-toolchain/regex/processors" + "github.com/coreruleset/crs-toolchain/v2/regex" + "github.com/coreruleset/crs-toolchain/v2/regex/parser" + "github.com/coreruleset/crs-toolchain/v2/regex/processors" ) // Create the processor stack @@ -26,11 +26,12 @@ var processor processors.IProcessor // NewAssembler creates a new Operator based on context. func NewAssembler(ctx *processors.Context) *Operator { return &Operator{ - name: "assemble", - details: make(map[string]string), - lines: []string{}, - ctx: ctx, - stats: NewStats(), + name: "assemble", + details: make(map[string]string), + lines: []string{}, + ctx: ctx, + stats: NewStats(), + groupReplacementStringBuilder: &strings.Builder{}, } } @@ -135,11 +136,13 @@ func (a *Operator) complete(assembleParser *parser.Parser) string { result = a.escapeDoublequotes(result) logger.Trace().Msgf("After escaping double quotes: %s\n", result) result = a.useHexBackslashes(result) - logger.Trace().Msgf("After replacing plain backslashes with hex escapse: %s\n", result) + logger.Trace().Msgf("After replacing plain backslashes with hex escapes: %s\n", result) result = a.includeVerticalTabInSpaceClass(result) logger.Trace().Msgf("After including vertical tabs: %s\n", result) result = a.dontUseFlagsForMetaCharacters(result) logger.Trace().Msgf("After removing meta character flags: %s\n", result) + result = a.removeOutermostNonCapturingGroup(result) + logger.Trace().Msgf("After removing outermost non-capturing group: %s\n", result) } if len(flagsPrefix) > 0 && len(result) > 0 { @@ -203,16 +206,23 @@ func (a *Operator) useHexBackslashes(input string) string { return strings.ReplaceAll(input, `\\`, `\x5c`) } -// In Perl, the vertical tab (`\v`, `\x0b`) is *not* part of `\s`, but it is -// in newer versions of PCRE (both 3 and 2). Go's `regexp/syntax` package +// In Perl, the vertical tab (`VT`, `\x0b`) is *not* part of `\s`, but it is +// in newer versions of PCRE (both 3 and 2) (`\v` in PCRE is actually +// a list of vertical characters, one of which is `VT`). +// Go's `regexp/syntax` package // uses Perl as the reference and, hence, generates `[\t-\n\f-\r ]` as the -// character class for `\s`, i.e., `\v` is missing. -// We simply replace the generated class with `[\s\v]` to fix this. -// Note that we could use `\s` for PCRE, but this will not work for re2 -// compatible engines. +// character class for `\s`, i.e., `VT` is missing. +// We simply replace the generated class with `[\s\0xb]` to fix this. +// Note that we could use simply use `\s` for PCRE, but this will not work +// for re2 compatible engines. +// Note also that we use the hex escape code for the vertical tab because in +// PCRE2 ranges in character classes are not allowed to start with escape codes +// that expand to multiple code points, which includes `\v`. In the original +// implementation of PCRE, `\v` was not illegal but led to the range token (`-`) +// to be interpreted as a literal. func (a *Operator) includeVerticalTabInSpaceClass(input string) string { - logger.Trace().Msg("Fixing up regex to include \\v in white space class matches") - return strings.ReplaceAll(input, `\t\n\f\r `, `\s\v`) + logger.Trace().Msg("Fixing up regex to include vertical tab (VT) in white space class matches") + return strings.ReplaceAll(input, `\t\n\f\r `, `\s\x0b`) } // rassemble-go doesn't provide an option to specify literals. @@ -235,7 +245,6 @@ func (a *Operator) includeVerticalTabInSpaceClass(input string) string { func (a *Operator) useHexEscapes(input string) string { var sb strings.Builder for _, char := range input { - // dec_value = ord(char) if char < 32 || char > 126 { sb.WriteString(`\x`) sb.WriteString(fmt.Sprintf("%x", char)) @@ -250,16 +259,16 @@ func (a *Operator) useHexEscapes(input string) string { // meta characters that could be ambiguous, such as `^`, `$`, `.`. // Remove both flags for the current context, e.g., `...(?m)...`, and flag groups // applied to subexpressions, e.g., `...(?m:...)...` -func (a *Operator) dontUseFlagsForMetaCharacters(input string) string { +func (o *Operator) dontUseFlagsForMetaCharacters(input string) string { result := input flagsStartRegexp := regexp.MustCompile(`\(\?[-misU]+\)`) - result = flagsStartRegexp.ReplaceAllString(result, "") + result = flagsStartRegexp.ReplaceAllLiteralString(result, "") flagGroupStartRegexp := regexp.MustCompile(`\(\?[-misU]+:`) for { location := flagGroupStartRegexp.FindStringIndex(result) if len(location) > 0 { - result = replaceFlagGroup(result, location) + result = o.removeGroup(result, location[0], location[1], false) } else { break } @@ -267,12 +276,52 @@ func (a *Operator) dontUseFlagsForMetaCharacters(input string) string { return result } -// Remove flag groups like `...(?-s:...)...` -func replaceFlagGroup(input string, location []int) string { +// Remove groups like `...(?-s:...)...`. +// If a group has an alternation on the same level as the group that +// should be replaced, the group needs to be retained in order to +// retain semantics, but the flags should still be removed. +// Ignore alternations if `ignoreAlternations` is true. This can be used +// to remove a top level group, in which case alternations with and without +// the group would be equivalent. +func (o *Operator) removeGroup(input string, groupStart int, bodyStart int, ignoreAlternations bool) string { + bodyEnd, hasAlternation := o.findGroupBodyEnd(input, bodyStart) + hasAlternation = hasAlternation && !ignoreAlternations + + o.groupReplacementStringBuilder.Reset() + o.groupReplacementStringBuilder.WriteString(input[:groupStart]) + if hasAlternation { + o.groupReplacementStringBuilder.WriteString("(?:") + } + o.groupReplacementStringBuilder.WriteString(input[bodyStart : bodyEnd+1]) + if hasAlternation { + o.groupReplacementStringBuilder.WriteString(")") + } + o.groupReplacementStringBuilder.WriteString(input[bodyEnd+2:]) + return o.groupReplacementStringBuilder.String() +} + +// Removes the topmost non-capturing group if it is redundant. +func (o *Operator) removeOutermostNonCapturingGroup(input string) string { + matcher := regexp.MustCompile(`^\(\?:.*\)$`) + if !matcher.MatchString(input) { + return input + } + + bodyEnd, _ := o.findGroupBodyEnd(input, 3) + if bodyEnd+1 < len(input)-1 { + return input + } + + return o.removeGroup(input, 0, 3, true) +} + +// Returns the index of the last token of the group whose body starts at +// `groupBodyStart`. Resturns `true`, as the second value, if the group +// has an alternation on the topmost level, `false` otherwise. +func (o *Operator) findGroupBodyEnd(input string, groupBodyStart int) (int, bool) { + hasAlternation := false parensCounter := 1 - groupStart := location[0] - bodyStart := location[1] - index := bodyStart + index := groupBodyStart for ; parensCounter > 0; index++ { char := input[index] switch char { @@ -284,9 +333,14 @@ func replaceFlagGroup(input string, location []int) string { if !isEscaped(input, index) { parensCounter-- } + case '|': + if parensCounter == 1 { + hasAlternation = true + } } } - return input[:groupStart] + input[bodyStart:index-1] + input[index:] + + return index - 2, hasAlternation } func isEscaped(input string, position int) bool { diff --git a/regex/operators/assembler_test.go b/regex/operators/assembler_test.go index aea66e4..c6d25b0 100644 --- a/regex/operators/assembler_test.go +++ b/regex/operators/assembler_test.go @@ -9,9 +9,9 @@ import ( "github.com/stretchr/testify/suite" - "github.com/coreruleset/crs-toolchain/configuration" - "github.com/coreruleset/crs-toolchain/context" - "github.com/coreruleset/crs-toolchain/regex/processors" + "github.com/coreruleset/crs-toolchain/v2/configuration" + "github.com/coreruleset/crs-toolchain/v2/context" + "github.com/coreruleset/crs-toolchain/v2/regex/processors" ) type assemblerTestSuite struct { @@ -361,7 +361,7 @@ func (s *specialCasesTestSuite) TestBackslashSReplacesPerlEquivalentCharacterCla assembler := NewAssembler(s.ctx) output, err := assembler.Run(contents) s.Require().NoError(err) - s.Equal(`[\s\v]`, output) + s.Equal(`[\s\x0b]`, output) } func (s *preprocessorsTestSuite) TestSequentialPreprocessors() { @@ -495,7 +495,7 @@ func (s *definitionsTestSuite) TestDefinition_RetainsEscapes() { output, err := assembler.Run(contents) s.Require().NoError(err) - s.Equal(`\n[\s\v]\b\v\t`, output) + s.Equal(`\n[\s\x0b]\b\v\t`, output) } @@ -1015,3 +1015,48 @@ func (s *assemblerTestSuite) TestAssemble_FlagGroupReplacementWithEscapedParenth s.Require().NoError(err) s.Equal(contents, output) } + +// regexp/syntax procudes flag groups we don't want. Make sure that +// Removal of those groups does not remove groups that are semantically +// relevant, which is the case when the flag group wraps an alternation. +func (s *assemblerTestSuite) TestAssemble_ReplaceFlagGroupsWithAlternations() { + contents := `(?-s:(?s:.)(?i:A|B .))` + expected := `.(?:A|B .)` + assembler := NewAssembler(s.ctx) + + output, err := assembler.Run(contents) + + s.Require().NoError(err) + s.Equal(expected, output) +} + +func (s *assemblerTestSuite) TestAssemble_RemoveOutermostNonMatchingGroup() { + contents := `(?:ab|cd)` + expected := `ab|cd` + assembler := NewAssembler(s.ctx) + + output, err := assembler.Run(contents) + + s.Require().NoError(err) + s.Equal(expected, output) +} +func (s *assemblerTestSuite) TestAssemble_RemoveOutermostNonMatchingGroup_WithExtraGroup() { + contents := `(?:(?:ab|cd))` + expected := `ab|cd` + assembler := NewAssembler(s.ctx) + + output, err := assembler.Run(contents) + + s.Require().NoError(err) + s.Equal(expected, output) +} + +func (s *assemblerTestSuite) TestAssemble_RemoveOutermostNonMatchingGroup_Dont() { + contents := `(?:ab|cd)e|fg` + assembler := NewAssembler(s.ctx) + + output, err := assembler.Run(contents) + + s.Require().NoError(err) + s.Equal(contents, output) +} diff --git a/regex/operators/operators.go b/regex/operators/operators.go index 1c2f955..5dc4731 100644 --- a/regex/operators/operators.go +++ b/regex/operators/operators.go @@ -6,20 +6,22 @@ package operators import ( "errors" "io" + "strings" "github.com/rs/zerolog/log" - "github.com/coreruleset/crs-toolchain/regex/processors" + "github.com/coreruleset/crs-toolchain/v2/regex/processors" ) var logger = log.With().Str("component", "operators").Logger() type Operator struct { - name string - details map[string]string - lines []string - stats *Stats - ctx *processors.Context + name string + details map[string]string + lines []string + stats *Stats + ctx *processors.Context + groupReplacementStringBuilder *strings.Builder } type ProcessorStack struct { diff --git a/regex/parser/definition_test.go b/regex/parser/definition_test.go index d33a47b..41d4b98 100644 --- a/regex/parser/definition_test.go +++ b/regex/parser/definition_test.go @@ -15,8 +15,8 @@ import ( "github.com/stretchr/testify/suite" - "github.com/coreruleset/crs-toolchain/context" - "github.com/coreruleset/crs-toolchain/regex/processors" + "github.com/coreruleset/crs-toolchain/v2/context" + "github.com/coreruleset/crs-toolchain/v2/regex/processors" ) type parserDefinitionTestSuite struct { diff --git a/regex/parser/include_except_test.go b/regex/parser/include_except_test.go index 2ab2598..b3b7db6 100644 --- a/regex/parser/include_except_test.go +++ b/regex/parser/include_except_test.go @@ -14,8 +14,8 @@ import ( "github.com/google/uuid" "github.com/stretchr/testify/suite" - "github.com/coreruleset/crs-toolchain/context" - "github.com/coreruleset/crs-toolchain/regex/processors" + "github.com/coreruleset/crs-toolchain/v2/context" + "github.com/coreruleset/crs-toolchain/v2/regex/processors" ) type parserIncludeExceptTestSuite struct { diff --git a/regex/parser/include_multiple_test.go b/regex/parser/include_multiple_test.go index cd3c7d1..23b8de6 100644 --- a/regex/parser/include_multiple_test.go +++ b/regex/parser/include_multiple_test.go @@ -15,8 +15,8 @@ import ( "github.com/stretchr/testify/suite" - "github.com/coreruleset/crs-toolchain/context" - "github.com/coreruleset/crs-toolchain/regex/processors" + "github.com/coreruleset/crs-toolchain/v2/context" + "github.com/coreruleset/crs-toolchain/v2/regex/processors" ) type parserMultiIncludeTestSuite struct { diff --git a/regex/parser/include_test.go b/regex/parser/include_test.go index 5c22270..91d4edb 100644 --- a/regex/parser/include_test.go +++ b/regex/parser/include_test.go @@ -15,8 +15,8 @@ import ( "github.com/stretchr/testify/suite" - "github.com/coreruleset/crs-toolchain/context" - "github.com/coreruleset/crs-toolchain/regex/processors" + "github.com/coreruleset/crs-toolchain/v2/context" + "github.com/coreruleset/crs-toolchain/v2/regex/processors" ) type parserIncludeTestSuite struct { diff --git a/regex/parser/include_with_definition_test.go b/regex/parser/include_with_definition_test.go index 83dab8d..2a4ccbc 100644 --- a/regex/parser/include_with_definition_test.go +++ b/regex/parser/include_with_definition_test.go @@ -13,8 +13,8 @@ import ( "github.com/rs/zerolog" "github.com/stretchr/testify/suite" - "github.com/coreruleset/crs-toolchain/context" - "github.com/coreruleset/crs-toolchain/regex/processors" + "github.com/coreruleset/crs-toolchain/v2/context" + "github.com/coreruleset/crs-toolchain/v2/regex/processors" ) type parserIncludeWithDefinitions struct { diff --git a/regex/parser/parser.go b/regex/parser/parser.go index 0d3663d..3d7b895 100644 --- a/regex/parser/parser.go +++ b/regex/parser/parser.go @@ -20,8 +20,8 @@ import ( "dario.cat/mergo" "github.com/rs/zerolog/log" - "github.com/coreruleset/crs-toolchain/regex" - "github.com/coreruleset/crs-toolchain/regex/processors" + "github.com/coreruleset/crs-toolchain/v2/regex" + "github.com/coreruleset/crs-toolchain/v2/regex/processors" ) var logger = log.With().Str("component", "parser").Logger() @@ -288,12 +288,12 @@ func parseFile(rootParser *Parser, filename string, definitions map[string]strin // Merge prefixes, and suffixes from include files into another parser. // All of these need to be treated as local to the source parser. -// We removed flag merging because of https://github.com/coreruleset/crs-toolchain/issues/72 +// We removed flag merging because of https://github.com/coreruleset/crs-toolchain/v2/issues/72 func mergePrefixesSuffixes(target *Parser, source *Parser, out *bytes.Buffer) (*bytes.Buffer, error) { logger.Trace().Msg("merging prefixes, suffixes from included file") // If the included file has flags, this is an error if len(source.Flags) > 0 { - return new(bytes.Buffer), errors.New("include files must not contain flags. See https://github.com/coreruleset/crs-toolchain/issues/71") + return new(bytes.Buffer), errors.New("include files must not contain flags. See https://github.com/coreruleset/crs-toolchain/v2/issues/71") } // IMPORTANT: don't write the assemble block at all if there are no flags, prefixes, or // suffixes. Enclosing the output in an assemble block can change the semantics, for example, diff --git a/regex/parser/parser_test.go b/regex/parser/parser_test.go index 2a60f0c..8b6d8ea 100644 --- a/regex/parser/parser_test.go +++ b/regex/parser/parser_test.go @@ -13,9 +13,9 @@ import ( "github.com/stretchr/testify/suite" - "github.com/coreruleset/crs-toolchain/context" - "github.com/coreruleset/crs-toolchain/regex" - "github.com/coreruleset/crs-toolchain/regex/processors" + "github.com/coreruleset/crs-toolchain/v2/context" + "github.com/coreruleset/crs-toolchain/v2/regex" + "github.com/coreruleset/crs-toolchain/v2/regex/processors" ) type parserTestSuite struct { diff --git a/regex/processors/assemble.go b/regex/processors/assemble.go index b484f5d..c3272c4 100644 --- a/regex/processors/assemble.go +++ b/regex/processors/assemble.go @@ -10,7 +10,7 @@ import ( "github.com/itchyny/rassemble-go" - "github.com/coreruleset/crs-toolchain/regex" + "github.com/coreruleset/crs-toolchain/v2/regex" ) const ( diff --git a/regex/processors/assemble_test.go b/regex/processors/assemble_test.go index eca3ffe..1fedc1d 100644 --- a/regex/processors/assemble_test.go +++ b/regex/processors/assemble_test.go @@ -9,7 +9,7 @@ import ( "github.com/stretchr/testify/suite" - "github.com/coreruleset/crs-toolchain/context" + "github.com/coreruleset/crs-toolchain/v2/context" ) type assembleTestSuite struct { diff --git a/regex/processors/cmdline_test.go b/regex/processors/cmdline_test.go index 3c82a4b..ce09f3b 100644 --- a/regex/processors/cmdline_test.go +++ b/regex/processors/cmdline_test.go @@ -9,8 +9,8 @@ import ( "github.com/stretchr/testify/suite" - "github.com/coreruleset/crs-toolchain/configuration" - "github.com/coreruleset/crs-toolchain/context" + "github.com/coreruleset/crs-toolchain/v2/configuration" + "github.com/coreruleset/crs-toolchain/v2/context" ) type cmdLineTestSuite struct { diff --git a/regex/processors/context.go b/regex/processors/context.go index f4f14cc..609c27c 100644 --- a/regex/processors/context.go +++ b/regex/processors/context.go @@ -7,7 +7,7 @@ import ( "fmt" "io" - "github.com/coreruleset/crs-toolchain/context" + "github.com/coreruleset/crs-toolchain/v2/context" ) type Context struct { diff --git a/regex/processors/processors_test.go b/regex/processors/processors_test.go index 5cc022a..4075914 100644 --- a/regex/processors/processors_test.go +++ b/regex/processors/processors_test.go @@ -9,7 +9,7 @@ import ( "github.com/stretchr/testify/suite" - "github.com/coreruleset/crs-toolchain/context" + "github.com/coreruleset/crs-toolchain/v2/context" ) type processorTestSuite struct { diff --git a/renovate.json b/renovate.json index 7025585..f05dc6b 100644 --- a/renovate.json +++ b/renovate.json @@ -1,29 +1,7 @@ { "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "extends": ["config:base"], - "packageRules": [ - { - "groupName": "all non-major dependencies", - "groupSlug": "all-minor-patch", - "matchPackagePatterns": [ - "*" - ], - "matchUpdateTypes": [ - "minor", - "patch" - ], - "matchSourceUrlPrefixes": ["https://github.com/"], - "prBodyDefinitions": { - "OpenSSF": "[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/{{sourceRepo}}/badge)](https://securityscorecards.dev/viewer/?uri=github.com/{{sourceRepo}})" - }, - "prBodyColumns": [ - "Package", - "Type", - "Update", - "Change", - "Pending", - "OpenSSF" - ] - } + "extends": [ + "local>coreruleset/renovate-config", + "schedule:weekly" ] } diff --git a/util/renumber_tests.go b/util/renumber_tests.go index 3f1db06..fb135a6 100644 --- a/util/renumber_tests.go +++ b/util/renumber_tests.go @@ -14,8 +14,8 @@ import ( "github.com/rs/zerolog/log" - "github.com/coreruleset/crs-toolchain/context" - "github.com/coreruleset/crs-toolchain/regex" + "github.com/coreruleset/crs-toolchain/v2/context" + "github.com/coreruleset/crs-toolchain/v2/regex" ) var logger = log.With().Str("component", "renumber-tests").Logger() @@ -111,11 +111,25 @@ func (t *TestRenumberer) processYaml(ruleId string, contents []byte) ([]byte, er output := new(bytes.Buffer) writer := bufio.NewWriter(output) index := 0 + idCount := 0 + titleCount := 0 for scanner.Scan() { line := scanner.Text() - matches := regex.TestTitleRegex.FindStringSubmatch(line) + matches := regex.TestIdRegex.FindStringSubmatch(line) if matches != nil { - index++ + idCount++ + if idCount > index { + index++ + } + line = fmt.Sprint(matches[1], " ", index) + } + // legacy support + matches = regex.TestTitleRegex.FindStringSubmatch(line) + if matches != nil { + titleCount++ + if titleCount > index { + index++ + } line = fmt.Sprint(matches[1], " ", ruleId, "-", index) } diff --git a/util/renumber_tests_test.go b/util/renumber_tests_test.go index 8a1bf74..750d7d2 100644 --- a/util/renumber_tests_test.go +++ b/util/renumber_tests_test.go @@ -20,7 +20,118 @@ func TestRunRenumberTestsTestSuite(t *testing.T) { suite.Run(t, new(renumberTestsTestSuite)) } -func (s *renumberTestsTestSuite) TestRenumberTests_SetTitle() { +func (s *renumberTestsTestSuite) TestRenumberTests_Setid() { + contents := `--- +meta: + enabled: true + name: 123456.yaml +tests: + - test_id: bapedibupi + desc: "test 1" + - test_id: "pine apple" + desc: "test 2" +` + expected := `--- +meta: + enabled: true + name: 123456.yaml +tests: + - test_id: 1 + desc: "test 1" + - test_id: 2 + desc: "test 2" +` + out, err := NewTestRenumberer().processYaml("123456", []byte(contents)) + s.Require().NoError(err) + + s.Equal(expected, string(out)) +} + +func (s *renumberTestsTestSuite) TestRenumberTests_RemoveSuperfluousNewLinesAtEof() { + contents := `--- +meta: + enabled: true + name: 123456.yaml +tests: + - test_id: bapedibupi + desc: "test 1" + - test_id: "pine apple" + desc: "test 2" + + +` + expected := `--- +meta: + enabled: true + name: 123456.yaml +tests: + - test_id: 1 + desc: "test 1" + - test_id: 2 + desc: "test 2" +` + out, err := NewTestRenumberer().processYaml("123456", []byte(contents)) + s.Require().NoError(err) + + s.Equal(expected, string(out)) +} + +func (s *renumberTestsTestSuite) TestRenumberTests_AddMissingNewLineAtEof() { + contents := `--- +meta: + enabled: true + name: 123456.yaml +tests: + - test_id: bapedibupi + desc: "test 1" + - test_id: "pine apple" + desc: "test 2"` + expected := `--- +meta: + enabled: true + name: 123456.yaml +tests: + - test_id: 1 + desc: "test 1" + - test_id: 2 + desc: "test 2" +` + out, err := NewTestRenumberer().processYaml("123456", []byte(contents)) + s.Require().NoError(err) + + s.Equal(expected, string(out)) +} + +func (s *renumberTestsTestSuite) TestRenumberTests_TrimSpaceOnTrailingLines() { + contents := `--- +meta: + enabled: true + name: 123456.yaml +tests: + - test_id: bapedibupi + desc: "test 1" + - test_id: "pine apple" + desc: "test 2" + + + ` + expected := `--- +meta: + enabled: true + name: 123456.yaml +tests: + - test_id: 1 + desc: "test 1" + - test_id: 2 + desc: "test 2" +` + out, err := NewTestRenumberer().processYaml("123456", []byte(contents)) + s.Require().NoError(err) + + s.Equal(expected, string(out)) +} + +func (s *renumberTestsTestSuite) TestRenumberTests_Legacy_SetTitle() { contents := `--- meta: enabled: true @@ -47,7 +158,7 @@ tests: s.Equal(expected, string(out)) } -func (s *renumberTestsTestSuite) TestRenumberTests_RemoveSuperfluousNewLinesAtEof() { +func (s *renumberTestsTestSuite) TestRenumberTests_Legacy_RemoveSuperfluousNewLinesAtEof() { contents := `--- meta: enabled: true @@ -76,7 +187,7 @@ tests: s.Equal(expected, string(out)) } -func (s *renumberTestsTestSuite) TestRenumberTests_AddMissingNewLineAtEof() { +func (s *renumberTestsTestSuite) TestRenumberTests_Legacy_AddMissingNewLineAtEof() { contents := `--- meta: enabled: true @@ -102,7 +213,7 @@ tests: s.Equal(expected, string(out)) } -func (s *renumberTestsTestSuite) TestRenumberTests_TrimSpaceOnTrailingLines() { +func (s *renumberTestsTestSuite) TestRenumberTests_Legacy_TrimSpaceOnTrailingLines() { contents := `--- meta: enabled: true @@ -130,3 +241,34 @@ tests: s.Equal(expected, string(out)) } + +func (s *renumberTestsTestSuite) TestRenumberTests_SupportLegacyAndNewFieldAtTheSameTime() { + contents := `--- +meta: + enabled: true + name: 123456.yaml +tests: + - test_title: bapedibupi + test_id: bapedibupi + desc: "test 1" + - test_id: "pine apple" + test_title: "pine apple" + desc: "test 2" + ` + expected := `--- +meta: + enabled: true + name: 123456.yaml +tests: + - test_title: 123456-1 + test_id: 1 + desc: "test 1" + - test_id: 2 + test_title: 123456-2 + desc: "test 2" +` + out, err := NewTestRenumberer().processYaml("123456", []byte(contents)) + s.Require().NoError(err) + + s.Equal(expected, string(out)) +}