Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: StyraInc/regal
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v0.24.0
Choose a base ref
...
head repository: StyraInc/regal
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v0.25.0
Choose a head ref
Loading
Showing with 3,128 additions and 425 deletions.
  1. +2 −2 .github/workflows/build.yaml
  2. +3 −3 .github/workflows/codeql.yml
  3. +3 −3 .github/workflows/scorecard.yml
  4. +70 −0 .github/workflows/update-example-index.yaml
  5. +6 −0 .gitignore
  6. +1 −0 .golangci.yaml
  7. +15 −13 README.md
  8. +27 −0 build/capabilities.json
  9. +62 −0 build/workflows/update-example-index/process.rego
  10. +46 −33 bundle/regal/ast/ast.rego
  11. +0 −36 bundle/regal/ast/ast_test.rego
  12. +22 −0 bundle/regal/ast/rule_heads.rego
  13. +35 −0 bundle/regal/ast/rule_heads_test.rego
  14. +55 −16 bundle/regal/ast/search.rego
  15. +2 −0 bundle/regal/capabilities.rego
  16. +5 −0 bundle/regal/config/provided/data.yaml
  17. +2 −2 bundle/regal/main.rego
  18. +6 −1 bundle/regal/rules/bugs/argument_always_wildcard.rego
  19. +9 −0 bundle/regal/rules/bugs/argument_always_wildcard_test.rego
  20. +20 −2 bundle/regal/rules/bugs/redundant_existence_check.rego
  21. +20 −1 bundle/regal/rules/bugs/redundant_existence_check_test.rego
  22. +88 −0 bundle/regal/rules/bugs/unused_output_variable.rego
  23. +133 −0 bundle/regal/rules/bugs/unused_output_variable_test.rego
  24. +1 −1 bundle/regal/rules/bugs/var_shadows_builtin.rego
  25. +1 −1 bundle/regal/rules/custom/naming_convention.rego
  26. +1 −1 bundle/regal/rules/idiomatic/non_raw_regex_pattern.rego
  27. +21 −3 bundle/regal/rules/idiomatic/non_raw_regex_pattern_test.rego
  28. +3 −13 bundle/regal/rules/idiomatic/use_some_for_output_vars.rego
  29. +35 −0 bundle/regal/rules/idiomatic/use_strings_count.rego
  30. +42 −0 bundle/regal/rules/idiomatic/use_strings_count_test.rego
  31. +3 −6 bundle/regal/rules/style/default_over_else.rego
  32. +12 −2 bundle/regal/rules/style/default_over_not.rego
  33. +5 −1 bundle/regal/rules/style/line_length.rego
  34. +12 −5 bundle/regal/rules/style/line_length_test.rego
  35. +3 −3 bundle/regal/rules/style/messy_rule.rego
  36. +13 −0 bundle/regal/rules/style/messy_rule_test.rego
  37. +4 −4 bundle/regal/rules/style/prefer_snake_case.rego
  38. +54 −5 bundle/regal/rules/style/prefer_snake_case_test.rego
  39. +2 −5 bundle/regal/rules/style/unnecessary_some.rego
  40. +3 −5 bundle/regal/rules/style/use_assignment_operator.rego
  41. +5 −5 bundle/regal/rules/testing/metasyntactic_variable.rego
  42. +42 −6 bundle/regal/rules/testing/metasyntactic_variable_test.rego
  43. +2 −2 bundle/regal/util/util.rego
  44. +2 −0 cmd/constants.go
  45. +11 −0 cmd/fix.go
  46. +1 −0 cmd/languageserver.go
  47. +27 −0 cmd/lint.go
  48. +8 −1 cmd/test.go
  49. +1 −1 docs/CONTRIBUTING.md
  50. +8 −0 docs/adopters.md
  51. BIN docs/assets/lsp/evalcodelens.png
  52. BIN docs/assets/lsp/evalcodelensprint.png
  53. +8 −3 docs/cicd.md
  54. +39 −8 docs/editor-support.md
  55. +5 −0 docs/fixing.md
  56. +58 −4 docs/language-server.md
  57. +4 −0 docs/rules/bugs/argument-always-wildcard.md
  58. +1 −1 docs/rules/bugs/rule-shadows-builtin.md
  59. +103 −0 docs/rules/bugs/unused-output-variable.md
  60. +1 −1 docs/rules/bugs/var-shadows-builtin.md
  61. +1 −1 docs/rules/idiomatic/prefer-set-or-object-rule.md
  62. +50 −0 docs/rules/idiomatic/use-strings-count.md
  63. +3 −2 docs/rules/imports/redundant-alias.md
  64. +2 −0 docs/rules/testing/metasyntactic-variable.md
  65. +6 −6 e2e/cli_test.go
  66. +8 −1 e2e/testdata/violations/most_violations.rego
  67. +9 −8 go.mod
  68. +45 −42 go.sum
  69. +35 −0 internal/lsp/bundles/bundles.go
  70. +101 −0 internal/lsp/bundles/bundles_test.go
  71. +235 −0 internal/lsp/bundles/cache.go
  72. +165 −0 internal/lsp/bundles/cache_test.go
  73. +4 −4 internal/lsp/cache/cache.go
  74. +9 −0 internal/lsp/clients/clients.go
  75. +169 −0 internal/lsp/eval.go
  76. +127 −0 internal/lsp/eval_test.go
  77. +2 −1 internal/lsp/examples/examples.go
  78. +16 −15 internal/lsp/examples/index.json
  79. +0 −28 internal/lsp/format.go
  80. +64 −11 internal/lsp/rego/rego.go
  81. +429 −38 internal/lsp/server.go
  82. +61 −50 internal/lsp/server_test.go
  83. +28 −8 internal/lsp/types/types.go
  84. +94 −7 pkg/fixer/fixer.go
  85. +107 −2 pkg/fixer/fixer_test.go
  86. +0 −1 pkg/fixer/fixes/fixes.go
  87. +64 −1 pkg/reporter/reporter.go
  88. +121 −0 pkg/reporter/reporter_test.go
4 changes: 2 additions & 2 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
@@ -56,11 +56,11 @@ jobs:
path: ~/go/bin/rq
key: ${{ runner.os }}-${{ runner.arch }}-go-rq-${{ env.RQ_VERSION }}
- run: build/do.rq pull_request
- uses: golangci/golangci-lint-action@a4f60bb28d35aeee14e6880718e0c85ff1882e64 # v6.0.1
- uses: golangci/golangci-lint-action@aaa42aa0628b4ae2578232a66b541047968fac86 # v6.1.0
if: matrix.os.name == 'linux'
with:
version: v1.59.0
- uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4
- uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4.3.6
with:
name: regal-${{ matrix.os.name }}
path: regal
6 changes: 3 additions & 3 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
@@ -27,14 +27,14 @@ jobs:
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7

- name: Initialize CodeQL
uses: github/codeql-action/init@4fa2a7953630fd2f3fb380f21be14ede0169dd4f # v3.25.12
uses: github/codeql-action/init@429e1977040da7a23b6822b13c129cd1ba93dbb2 # v3.26.2
with:
languages: ${{ matrix.language }}

- name: Autobuild
uses: github/codeql-action/autobuild@4fa2a7953630fd2f3fb380f21be14ede0169dd4f # v3.25.12
uses: github/codeql-action/autobuild@429e1977040da7a23b6822b13c129cd1ba93dbb2 # v3.26.2

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@4fa2a7953630fd2f3fb380f21be14ede0169dd4f # v3.25.12
uses: github/codeql-action/analyze@429e1977040da7a23b6822b13c129cd1ba93dbb2 # v3.26.2
with:
category: "/language:${{matrix.language}}"
6 changes: 3 additions & 3 deletions .github/workflows/scorecard.yml
Original file line number Diff line number Diff line change
@@ -25,20 +25,20 @@ jobs:
persist-credentials: false

- name: "Run analysis"
uses: ossf/scorecard-action@dc50aa9510b46c811795eb24b2f1ba02a914e534 # v2.3.3
uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0
with:
results_file: results.sarif
results_format: sarif
publish_results: true

- name: "Upload artifact"
uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4
uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4.3.6
with:
name: SARIF file
path: results.sarif
retention-days: 5

- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@4fa2a7953630fd2f3fb380f21be14ede0169dd4f # v3.25.12
uses: github/codeql-action/upload-sarif@429e1977040da7a23b6822b13c129cd1ba93dbb2 # v3.26.2
with:
sarif_file: results.sarif
70 changes: 70 additions & 0 deletions .github/workflows/update-example-index.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# this workflow is used to update the internal/lsp/examples/index.json
# file containing an index of the content available on
# http://docs.styra.com/opa/rego-by-example
name: Update Examples Index

on:
workflow_dispatch:
schedule:
- cron: '0 1 * * *' # Run daily at 1 AM UTC

jobs:
update-examples-index:
env:
RQ_VERSION: v0.0.9
name: Update Examples Index
runs-on: ubuntu-22.04
permissions:
contents: write # this is needed to open a pull request
pull-requests: write # this is also needed to open a pull request
steps:
- name: Check out code
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7

- uses: open-policy-agent/setup-opa@34a30e8a924d1b03ce2cf7abe97250bbb1f332b5 # v2.2.0
with:
version: edge
static: true

- name: Set up go for rq
uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2
with:
go-version-file: go.mod

- name: Restore rq cache
id: cache-rq
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
with:
path: ~/go/bin/rq
key: ${{ runner.os }}-${{ runner.arch }}-go-rq-${{ env.RQ_VERSION }}
- run: go install git.sr.ht/~charles/rq/cmd/rq@${{ env.RQ_VERSION }}
if: steps.cache-rq.outputs.cache-hit != 'true'
- name: Cache rq binary
if: steps.cache-rq.outputs.cache-hit != 'true'
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
with:
path: ~/go/bin/rq
key: ${{ runner.os }}-${{ runner.arch }}-go-rq-${{ env.RQ_VERSION }}

- name: Fetch sitemap and convert to JSON
run: |
set -o pipefail
TEMP_DIR=$(mktemp -d)
curl -L https://docs.styra.com/sitemap.xml -o "$TEMP_DIR/sitemap.xml"
cat "$TEMP_DIR/sitemap.xml" | \
rq -i xml --indent " " | \
opa eval 'data.process.symbols' \
-d build/workflows/update-example-index/process.rego \
--format=pretty \
--stdin-input | \
tee internal/lsp/examples/index.json
- name: Open a pull request
uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c # v6.1.0
with:
title: "lsp: Update rego-by-examples index"
commit-message: "lsp: Update rego-by-examples index"
base: main
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -4,3 +4,9 @@ dist/

/regal
/regal.exe

# These two files are used by the Regal evaluation Code Lens, where input.json
# defines the input to use for evaluation, and output.json is where the output
# ends up unless the client supports presenting it in a different way.
input.json
output.json
1 change: 1 addition & 0 deletions .golangci.yaml
Original file line number Diff line number Diff line change
@@ -25,6 +25,7 @@ linters:
- nolintlint
- depguard
- gomoddirectives # need replacements for wasip1
- execinquery # deprecated
linters-settings:
tagliatelle:
case:
28 changes: 15 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Regal

[![Build Status](https://github.com/styrainc/regal/workflows/Build/badge.svg?branch=main)](https://github.com/styrainc/regal/actions)
![OPA v0.66.0](https://openpolicyagent.org/badge/v0.66.0)
![OPA v0.67.0](https://openpolicyagent.org/badge/v0.67.0)

Regal is a linter and language server for [Rego](https://www.openpolicyagent.org/docs/latest/policy-language/), helping
you write better policies and have fun while doing it!
@@ -60,7 +60,12 @@ brew install styrainc/packages/regal
```

<details>
<summary><strong>Manual download options</strong></summary>
<summary><strong>Other Installation Options</strong></summary>

Please see [Packages](https://docs.styra.com/regal/adopters#packaging)
for a list of package repositories which distribute Regal.

Manual installation commands:

**MacOS (Apple Silicon)**
```shell
@@ -88,16 +93,8 @@ curl.exe -L -o regal.exe "https://github.com/StyraInc/regal/releases/latest/down
docker pull ghcr.io/styrainc/regal:latest
```

**asdf**
```shell
asdf plugin add regal
asdf install regal latest
asdf global regal latest
```

See all versions, and checksum files, at the Regal [releases](https://github.com/StyraInc/regal/releases/) page, and
published Docker images at the [packages](https://github.com/StyraInc/regal/pkgs/container/regal) page.

</details>

### Try it out!
@@ -201,6 +198,7 @@ The following rules are currently available:
| bugs | [rule-shadows-builtin](https://docs.styra.com/regal/rules/bugs/rule-shadows-builtin) | Rule name shadows built-in |
| bugs | [top-level-iteration](https://docs.styra.com/regal/rules/bugs/top-level-iteration) | Iteration in top-level assignment |
| bugs | [unassigned-return-value](https://docs.styra.com/regal/rules/bugs/unassigned-return-value) | Non-boolean return value unassigned |
| bugs | [unused-output-variable](https://docs.styra.com/regal/rules/bugs/unused-output-variable) | Unused output variable |
| bugs | [var-shadows-builtin](https://docs.styra.com/regal/rules/bugs/var-shadows-builtin) | Variable name shadows built-in |
| bugs | [zero-arity-function](https://docs.styra.com/regal/rules/bugs/zero-arity-function) | Avoid functions without args |
| custom | [forbidden-function-call](https://docs.styra.com/regal/rules/custom/forbidden-function-call) | Forbidden function call |
@@ -219,6 +217,7 @@ The following rules are currently available:
| idiomatic | [use-if](https://docs.styra.com/regal/rules/idiomatic/use-if) | Use the `if` keyword |
| idiomatic | [use-in-operator](https://docs.styra.com/regal/rules/idiomatic/use-in-operator) | Use in to check for membership |
| idiomatic | [use-some-for-output-vars](https://docs.styra.com/regal/rules/idiomatic/use-some-for-output-vars) | Use `some` to declare output variables |
| idiomatic | [use-strings-count](https://docs.styra.com/regal/rules/idiomatic/use-strings-count) | Use `strings.count` where possible |
| imports | [avoid-importing-input](https://docs.styra.com/regal/rules/imports/avoid-importing-input) | Avoid importing input |
| imports | [circular-import](https://docs.styra.com/regal/rules/imports/circular-import) | Circular import |
| imports | [ignored-import](https://docs.styra.com/regal/rules/imports/ignored-import) | Reference ignores import |
@@ -598,12 +597,13 @@ are:
from the linter report
- `sarif` - [SARIF](https://sarifweb.azurewebsites.net/) JSON output, for consumption by tools processing code analysis
reports
- `junit` - JUnit XML output, e.g. for CI servers like GitLab that show these results in a merge request.

## OPA Check and Strict Mode

Linting with Regal assumes syntactically correct Rego. If there are errors parsing any files during linting, the
process is aborted and any parser errors are logged similarly to OPA. OPA itself provides a "linter" of sorts,
via the `opa check` comand and its `--strict` flag. This checks the provided Rego files not only for syntax errors,
via the `opa check` command and its `--strict` flag. This checks the provided Rego files not only for syntax errors,
but also for OPA [strict mode](https://www.openpolicyagent.org/docs/latest/policy-language/#strict-mode) violations.

> **Note** It is recommended to run `opa check --strict` as part of your policy build process, and address any violations
@@ -648,6 +648,8 @@ The Regal language server currently supports the following LSP features:
- [x] [use-rego-v1](https://docs.styra.com/regal/rules/imports/use-rego-v1)
- [x] [use-assignment-operator](https://docs.styra.com/regal/rules/style/use-assignment-operator)
- [x] [no-whitespace-comment](https://docs.styra.com/regal/rules/style/no-whitespace-comment)
- [x] [Code lenses](https://github.com/StyraInc/regal/blob/main/docs/language-server.md#code-lenses-evaluation)
(click to evaluate any package or rule directly in the editor)

See the
[documentation page for the language server](https://github.com/StyraInc/regal/blob/main/docs/language-server.md)
@@ -696,13 +698,13 @@ in the near future:

- [ ] Allow remediation of more `style` category rules using the `regal fix` command
- [ ] Add [unused-rule](https://github.com/StyraInc/regal/issues/358) linter
- [ ] Add [unused-output-variable](https://github.com/StyraInc/regal/issues/60) linter
- [x] Add [unused-output-variable](https://github.com/StyraInc/regal/issues/60) linter

### Language Server

- [ ] Make "Check on save" unnecessary by allowing diagnostics to include
[compilation errors](https://github.com/StyraInc/regal/issues/745)
- [ ] Add Code Lens to "Evaluate" any rule or package
- [x] Add Code Lens to "Evaluate" any rule or package (VS Code only, initially)
- [ ] Implement [Signature Help](https://github.com/StyraInc/regal/issues/695) feature

The roadmap is updated when all the current items have been completed.
27 changes: 27 additions & 0 deletions build/capabilities.json
Original file line number Diff line number Diff line change
@@ -4983,6 +4983,33 @@
"type": "function"
}
},
{
"name": "strings.count",
"description": "Returns the number of non-overlapping instances of a substring in a string.",
"categories": [
"strings"
],
"decl": {
"args": [
{
"description": "string to search in",
"name": "search",
"type": "string"
},
{
"description": "substring to look for",
"name": "substring",
"type": "string"
}
],
"result": {
"description": "count of occurrences, `0` if not found",
"name": "output",
"type": "number"
},
"type": "function"
}
},
{
"name": "strings.render_template",
"description": "Renders a templated string with given template variables injected. For a given templated string and key/value mapping, values will be injected into the template where they are referenced by key.\n\tFor examples of templating syntax, see https://pkg.go.dev/text/template",
62 changes: 62 additions & 0 deletions build/workflows/update-example-index/process.rego
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package process

import rego.v1

symbols := {"keywords": _keywords, "builtins": _builtins}

_keywords[name] := path if {
some p in _pages
p[0] == "keywords"

name := p[1]

path := concat("/", p)
}

_builtins[name] := path if {
some p in _pages
p[0] == "builtins"

l := count(p)

l == 2

name := p[1]

count({p |
some p in _pages
p[0] == "builtins"
p[1] == name
}) < 2

path := concat("/", p)
}

_builtins[name] := path if {
some p in _pages
p[0] == "builtins"

l := count(p)

l > 2

name := concat(
".",
[
replace(p[1], "_", "."),
concat(".", array.slice(p, 2, l)),
],
)

path := concat("/", p)
}

_prefix := "https://docs.styra.com/opa/rego-by-example/"

_pages contains page if {
some url in input.urlset.url

startswith(url.loc, _prefix)

page := split(trim_prefix(url.loc, _prefix), "/")
}
Loading