diff --git a/docs/Makefile b/docs/Makefile index d151576140..9545b55ed0 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -8,7 +8,10 @@ ci: .PHONY: dev dev: - npx docusaurus start + # --no-open means that the browser will not be opened on start. + # This is done to avoid opening many tabs repeatedly when editing + # docusaurus.config.js. + npx docusaurus start --no-open .PHONY: build build: diff --git a/docs/bin/import-regal-docs.sh b/docs/bin/import-regal-docs.sh new file mode 100755 index 0000000000..08964e68a8 --- /dev/null +++ b/docs/bin/import-regal-docs.sh @@ -0,0 +1,89 @@ +#!/usr/bin/env bash + +set -euo pipefail + +if ! command -v curl >/dev/null 2>&1 +then + echo "curl could not be found" + exit 1 +fi + +if ! command -v unzip >/dev/null 2>&1 +then + echo "unzip could not be found" + exit 1 +fi + +download_regal() { + ref="heads/main" + if [[ -v VERSION ]]; then + ref="tags/$VERSION"; + fi + + # examples + # https://github.com/open-policy-agent/regal/archive/refs/heads/main.zip + # https://github.com/open-policy-agent/regal/archive/refs/tags/v0.35.1.zip + url="https://github.com/open-policy-agent/regal/archive/refs/$ref.zip" + + curl --silent -L -o regal.zip "$url" +} + +if [[ ! -e regal.zip ]]; then + download_regal +else + echo "Using existing regal.zip" +fi + +tempdir=$(mktemp -d) + +unzip regal.zip -d "$tempdir" 2>&1 > /dev/null + +mv $tempdir/*/* $tempdir + +regal_docs_src="$tempdir/docs" +regal_docs_dest="projects/regal" + +rm -rf "$regal_docs_dest" +mkdir -p "$regal_docs_dest" + +# copy assets +rsync -ah "$regal_docs_src/assets/." "$regal_docs_dest/assets" --delete + +# generate index +readme_sections_dir="$regal_docs_src/readme-sections" +manifest="$readme_sections_dir/website-manifest" + +tmpfile=$(mktemp) + +while IFS= read -r file; do + section_path="$readme_sections_dir/$file" + + if [[ -f "$section_path" ]]; then + cat "$section_path" >> "$tmpfile" + echo -e "\n" >> "$tmpfile" + else + echo "Section file not found: $section_path" >&2 + exit 1 + fi +done < "$manifest" + +mv $tmpfile "$regal_docs_dest/index.md" + +# copy in rules +cp -r "$regal_docs_src/rules" "$regal_docs_dest/" + +# generate other files +find "$regal_docs_src" -type f -name '*.md.yaml' | while read -r yaml_file; do + md_file="$(dirname $yaml_file)/$(basename "$yaml_file" .yaml)" + md_file_rel=${md_file#"$regal_docs_src/"} + dest_md_file="$regal_docs_dest/$md_file_rel" + + mkdir -p "$(dirname $dest_md_file)" + + if [[ ! -e $md_file ]]; then + echo "Warning: $md_file missing" + else + echo -e "---\n$(cat $yaml_file)\n---\n\n" > $dest_md_file + cat $md_file >> $dest_md_file + fi +done diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js index ef31bdc34b..966b0fb53d 100644 --- a/docs/docusaurus.config.js +++ b/docs/docusaurus.config.js @@ -6,6 +6,7 @@ import fs from "fs/promises"; const path = require("path"); const { loadPages } = require("./src/lib/ecosystem/loadPages"); +const { loadRules } = require("./src/lib/projects/regal/loadRules"); const baseUrl = "/"; @@ -136,13 +137,28 @@ const baseUrl = "/"; { href: "https://blog.openpolicyagent.org/", label: "Blog" }, ], }, + { + type: "dropdown", + label: "Projects", + position: "right", + items: [ + { to: "/docs", label: "OPA" }, + { to: "/projects/regal", label: "Regal" }, + { + type: "html", + value: "
+_A debugging session in VS Code_
+
+:::info
+In order to use the Debug Adapter, you must be using
+[Regal v0.27.0](https://github.com/open-policy-agent/regal/releases/v0.27.0) or greater,
+as well as a compatible client. See [Editor Support](https://openpolicyagent.org/projects/regal/editor-support) for
+more details.
+:::
+
+## Getting Started
+
+See the documentation in the Editor Support page for supported clients:
+
+* [Visual Studio Code](https://openpolicyagent.org/projects/regal/editor-support#visual-studio-code)
+* [Neovim](https://openpolicyagent.org/projects/regal/editor-support#neovim)
+
+## Features
+
+The Regal Debug Adapter currently supports the following features:
+
+### Breakpoints
+
+Breakpoints allow you to continue execution of a policy until a given point.
+This can be helpful for:
+
+* Inspection of variables at a given point in time
+* Seeing how many times a given block of Rego code is executed, if at all
+* Avoiding the need to step through code as it's run line by line
+
+
+
+### Variable Inspection
+
+Either at a breakpoint or while stepping through code, you can inspect the
+local variables in scope as well as the contents of the global `input` and
+`data` documents.
+
+`input` will be loaded from `input.json` in the workspace if it exists.
+
+
+
+### Print Statements
+
+Print statements are also supported, these are shown in the debug console:
+
+
diff --git a/docs/projects/regal/editor-support.md b/docs/projects/regal/editor-support.md
new file mode 100644
index 0000000000..ae4e8d1072
--- /dev/null
+++ b/docs/projects/regal/editor-support.md
@@ -0,0 +1,161 @@
+---
+sidebar_position: 7
+---
+
+
+# Editor Support
+
+## Visual Studio Code
+
+[vscode-opa](https://marketplace.visualstudio.com/items?itemName=tsandall.opa) -
+the official OPA extension for Visual Studio Code - now supports the Regal language server.
+
+To see Regal linting as you work, install the extension at version `0.13.3` or later
+and open a workspace with Rego files.
+
+The plugin will automatically find and use [Regal config](https://openpolicyagent.org/projects/regal#configuration).
+
+### Debug Adapter Protocol (DAP)
+
+From
+[`v0.17.0`](https://github.com/open-policy-agent/vscode-opa/blob/main/CHANGELOG.md#0170)
+onwards, the OPA extension for Visual Studio Code supports the
+[Regal Debug Adapter](https://openpolicyagent.org/projects/regal/debug-adapter).
+
+To start a new debug session use the code action `Debug` found above a Rego rule
+or package.
+
+
+
+Breakpoints can be added by clicking in the gutter to the left of the editor.
+Print statements will be shown in the debug console.
+
+## Zed
+
+[Zed](https://zed.dev) is a modern open-source code editor with focus on performance and simplicity.
+
+Zed supports Rego via Regal and the [zed-rego](https://github.com/StyraInc/zed-rego) extension developed by the Styra
+community. The extension provides syntax highlighting, linting, and most of the other language server features provided
+by Regal.
+
+## Neovim
+
+[Neovim](https://neovim.io/) supports both the Language Server Protocol and the Debug Adapter Protocol.
+
+Generally, the Regal binary should be [installed](https://openpolicyagent.org/projects/regal#getting-started)
+first. [`mason.vim`](https://github.com/williamboman/mason.nvim) users can install the
+Regal binary with `:MasonInstall regal`
+([package definition](https://github.com/mason-org/mason-registry/blob/2024-07-23-asian-hate/packages/regal/package.yaml)).
+
+### Language Server Protocol (LSP)
+
+There are a number of different plugins available for Neovim which integrate
+with language servers using the Language Server Protocol.
+
+Below are a number of different plugin options to configure a language server
+client for Regal in Neovim.
+
+#### nvim-lspconfig
+
+[nvim-lspconfig](https://github.com/neovim/nvim-lspconfig) has native support for the
+Regal language server. Use the configuration below to configure Regal:
+
+```lua
+require('lspconfig').regal.setup()
+```
+
+#### none-ls
+
+[none-ls](https://github.com/nvimtools/none-ls.nvim) - Use Neovim as a
+language server to inject LSP diagnostics, code actions, and more via Lua.
+
+Minimal installation via [VimPlug](https://github.com/junegunn/vim-plug)
+
+```vim
+Plug 'nvim-lua/plenary.nvim'
+Plug 'nvimtools/none-ls.nvim'
+
+lua <
+
+Future versions of Regal may include also [compilation errors](https://github.com/open-policy-agent/regal/issues/745)
+as part of diagnostics messages.
+
+### Hover
+
+The hover feature means that moving the mouse over certain parts of the code will bring up a tooltip with documentation
+for the code under the cursor. This is particularly useful for built-in functions, as it allows you to quickly look up
+the meaning of the function, and the arguments it expects.
+
+
+
+The Regal language server currently supports hover for all built-in functions OPA provides.
+
+### Go to definition
+
+Go to definition allows references to rules and functions to be clicked on (while holding `ctrl/cmd`), and the editor
+will navigate to the definition of the rule or function.
+
+### Folding ranges
+
+Regal provides folding ranges for any policy being edited. Folding ranges are areas of the code that can be collapsed
+or expanded, which may be useful for hiding content that is not relevant to the current task.
+
+
+
+Regal supports folding ranges for blocks, imports and comments.
+
+### Document and workspace symbols
+
+Document and workspace symbols allow policy authors to quickly scan and navigate to symbols (like rules and functions)
+anywhere in the document or workspace.
+
+
+
+VS Code additionally provides an "Outline" view, which is a nice visual representation of the symbols in the document.
+
+
+
+### Inlay hints
+
+Inlay hints help developers quickly understand the meaning of the arguments passed passed to functions in the code,
+by showing the name of the argument next to the value. Inlay hints can additionally be hovered for more information,
+like the expected type of the argument.
+
+
+
+Regal currently supports inlay hints for all built-in functions. Future versions may support inlay hints for
+user-defined functions too.
+
+### Formatting
+
+By default, Regal uses the `opa fmt` formatter for formatting Rego. This is made available as a command in editors,
+but also via a [code action](#code-actions) when unformatted files are encountered.
+
+
+
+Two other formatters are also available — `opa fmt --rego-v1` and `regal fix`. See the docs on
+[Fixing Violations](fixing.md) for more information about the `fix` command. Which formatter to use
+can be set via the `formatter` configuration option, which can be passed to Regal via the client (see
+the documentation for your client for how to do that).
+
+### Code completions
+
+Code completions, or suggestions, is likely one of the most useful features of the Regal language server. And best of
+all, you don't need to do anything special for it to happen! Just write your policy as you normally would, and Regal
+will provide suggestions for anything that could be relevant in the context that you're typing. This could for example
+be suggestions for:
+
+- Built-in functions
+- Local variables
+- Imported packages
+- References from anywhere in the workspace
+- And much more!
+
+
+
+New completion providers are added continuously, so if you have a suggestion for
+a new completion, please
+[open an issue](https://github.com/open-policy-agent/regal/issues)!
+
+### Code actions
+
+Code actions are actions that appear in the editor when certain conditions are met. One example would be "quick fixes"
+that may appear when a linter rule has been violated. Code actions can be triggered by clicking on the lightbulb icon
+that appears on the line with a diagnostic message, or by pressing `ctrl/cmd + .` when the cursor is on the line.
+
+
+
+Once evaluation has completed, the result is also pretty-printed in a tooltip when hovering the rule. This is
+particularly useful when the result contains more data than can fit on a single line!
+
+Note that when evaluating incrementally defined rules, the result reflects evaluation of the whole **document**,
+not a single rule definition. To make this clear, the result will be displayed next to each definition of the
+same rule.
+
+In addition to showing the result of evaluation, the "Evaluate" code lens will also display the output of any
+`print` calls made in rule bodies. This can be really helpful when trying to figure out _why_ the rule evaluated
+the way it did, or where rule evaluation failed.
+
+
+
+Policy evaluation often depends on **input**. This can be provided via an `input.json` or `input.yaml` file which
+Regal will search for first in the same directory as the policy file evaluated. If not found there, Regal will proceed
+to search each parent directory up until the workspace root directory. It is recommended to add `input.json/yaml` to
+your `.gitignore` file so that you can work freely with evaluation in any directory without having your input
+accidentally committed.
+
+#### Editor support
+
+The Evaluation code lens is supported in any language server client that
+supports the running of code lenses. The evaluation result is saved to
+`output.json` in the default case.
+
+The displaying of evaluation results in the current file or buffer is currently
+only supported in the
+[OPA VS Code extension](https://github.com/open-policy-agent/vscode-opa) and
+for Neovim users in
+[nvim-dap-rego](https://github.com/rinx/nvim-dap-rego/).
+
+### Code lenses (Debugging)
+
+Regal also implements the
+[Debug Adapter Protocol](https://microsoft.github.io/debug-adapter-protocol/).
+This allows users to trigger debugging sessions for their policies by invoking a
+code lens on a rule. For more information, see the [Debug Adapter](./debug-adapter.md)
+page.
+
+#### Editor support
+
+While the code lens feature is part of the LSP specification, the action that is triggered by a code lens
+isn't necessarily part of the standard. The language server protocol does not provide a native method for requesting
+evaluation, so Regal will handle that on its own, and differently depending on what the client supports.
+
+- Currently, only the [OPA VS Code extension](https://github.com/open-policy-agent/vscode-opa) and
+ [nvim-dap-rego](https://github.com/rinx/nvim-dap-rego/) is capable of handling
+ the request to display evaluation results on the same line as the package or rule evaluated.
+- [Neovim](https://neovim.io/) does not support the requests natively, but
+ [nvim-dap-rego](https://github.com/rinx/nvim-dap-rego/) provides handlers to support them.
+ Please follow [the instructions](https://github.com/rinx/nvim-dap-rego/blob/main/README.md#lsp-handlers) in
+ nvim-dap-rego README.
+- [Zed](https://github.com/StyraInc/zed-rego) does not support the code lens feature at all at this point in time. As
+ soon as it does, Regal will provide them.
+- Displaying the result of evaluation requires customized code in the client. Currently only VS Code and Neovim
+ has the required modifications to handle this, and is thus the only editor to currently support "inline display"
+ of the result.
+ For other editors that support the code lens feature, Regal will instead write the result of evaluation to an
+ `output.json` file.
+
+## Unsupported features
+
+See the
+[open issues](https://github.com/open-policy-agent/regal/issues?q=is%3Aissue+is%3Aopen+label%3A%22language+server+protocol%22)
+with the `language server protocol` label for a list of features that are not yet supported by the Regal language
+server, but that are planned for the future. If you have suggestions for anything else, please create a new issue!
+
+Also note that not all clients (i.e. editors) may support all features of a language server! See the
+[editor support](./editor-support.md) page for information about Regal support in different editors.
diff --git a/docs/projects/regal/opa-one-dot-zero.md b/docs/projects/regal/opa-one-dot-zero.md
new file mode 100644
index 0000000000..f64e8a4462
--- /dev/null
+++ b/docs/projects/regal/opa-one-dot-zero.md
@@ -0,0 +1,77 @@
+---
+sidebar_label: OPA 1.0
+sidebar_position: 14
+---
+
+
+# OPA 1.0 and Regal
+
+While we always recommend using the latest version of OPA, we're well aware that there may be situations where — for
+one reason or another — that might not be possible. As we want everyone to benefit from Regal, we do our very best to
+ensure it works seamlessly with OPA versions both before and after 1.0, and even projects that use a mix of both! While
+this should mostly work out of the box and without additional configuration, it's good to be aware of how Regal parses
+and lints policies of different versions of Rego, and how you can tell Regal to target only a specific version.
+
+**Note:** This document does not cover the specifics of OPA 1.0, but rather how Regal works with it. If you want to
+learn more about what OPA 1.0 is and how to upgrade, see the [related resources](#related-resources) at the bottom of
+this page.
+
+## Telling Regal which Rego version to target
+
+While Regal pretty accurately guesses the Rego version of the policies it's linting — and will adapt how it parses and
+asseses Rego files accordingly — telling Regal which version to target is always going to produce the most reliable
+results — and much faster too! Guessing which Rego version to target often involves multiple passes of parsing, and
+as some files are both valid Rego v0 and v1, there will always be some ambiguity. In order to avoid this, our
+recommendation is to always provide Regal with the Rego version(s) targeted. This can be done in a couple of ways, and
+the precedence of these methods is as listed below:
+
+1. Setting the `rego-version` configuration option under `project.roots` attribute
+2. Setting the `rego-version` configuration option under `project` attribute
+3. Setting the `rego_version` in a `.manifest` file in any directory (will apply to that directory and any below it)
+
+Note that it's is perfectly possible to use different `rego-version`s for different roots of a project:
+
+```yaml
+project:
+ rego-version: 1
+ roots:
+ # lib/legacy overriding project version to set versin 0
+ - path: lib/legacy
+ rego-version: 0
+ # main directory will inherit version 1 from project
+ - path: main
+```
+
+See the documentation covering Regal's [configuration](https://openpolicyagent.org/projects/regal#configuration) for more information
+on [configuring Rego version](https://openpolicyagent.org/projects/regal#configuring-rego-version) for your project.
+
+Finally, Regal will automatically parse and lint any file with a `_v0.rego` suffix as Rego v0. This is intended only
+for testing and development, where you sometimes may want to try something out using and older Rego version without
+configuration. Note that this has lower precedence than Rego versions set by other means, and should not be considered
+as anything but a convenience for testing.
+
+## Rules disabled with OPA 1.0
+
+Some linter rules don't really make sense to enforce post OPA 1.0, as they are now either enforced by OPA itself or
+otherwise no longer relevant. The following rules are now disabled by default, unless Regal is configured to target
+Rego versions before 1.0, or in the case where no configuration is provided, Regal determines that the project being
+linted is not yet using OPA 1.0:
+
+- [deprecated-builtin](https://openpolicyagent.org/projects/regal/rules/bugs/deprecated-builtin)
+- [import-shadows-import](https://openpolicyagent.org/projects/regal/rules/imports/import-shadows-import)
+- [rule-named-if](https://openpolicyagent.org/projects/regal/rules/bugs/rule-named-if)
+- [use-contains](https://openpolicyagent.org/projects/regal/rules/idiomatic/use-contains)
+- [use-if](https://openpolicyagent.org/projects/regal/rules/idiomatic/use-if)
+- [use-rego-v1](https://openpolicyagent.org/projects/regal/rules/imports/use-rego-v1)
+
+Except for the `deprecated-bultin` rule — which is disabled simply because there currently are no deprecated built-ins
+in OPA 1.0 — these rules are now enforced automatically by OPA, and so there's no reason for Regal to duplicate that
+effort.
+
+## Related Resources
+
+- OPA Docs: [Upgrading to v1.0](https://www.openpolicyagent.org/docs/v0-upgrade/)
+- OPA Docs: [v0 Backwards Compatibility](https://www.openpolicyagent.org/docs/v0-compatibility/)
+- Styra Blog: [Renovating Rego](https://www.styra.com/blog/renovating-rego/)
+- OPA Blog: [OPA 1.0 Is Coming, Here's What You Need to Know](https://blog.openpolicyagent.org/opa-1-0-is-coming-heres-what-you-need-to-know-c8fb0d258368)
+- OPA Blog: [Announcing OPA 1.0: A New Standard for Policy as Code](https://blog.openpolicyagent.org/announcing-opa-1-0-a-new-standard-for-policy-as-code-a6d8427ee828)
diff --git a/docs/projects/regal/pre-commit-hooks.md b/docs/projects/regal/pre-commit-hooks.md
new file mode 100644
index 0000000000..7df85bc2e3
--- /dev/null
+++ b/docs/projects/regal/pre-commit-hooks.md
@@ -0,0 +1,47 @@
+---
+sidebar_position: 6
+---
+
+
+# Pre-Commit Hooks
+
+[Pre-Commit](https://pre-commit.com) is a framework for managing and maintaining multi-language pre-commit hooks.
+This allows running Regal automatically whenever (and as the name implied, before )a Rego file is about to be committed.
+
+To use Regal with pre-commit, add this to your `.pre-commit-config.yaml`
+
+```yaml
+- repo: https://github.com/open-policy-agent/regal
+ rev: v0.7.0 # Use the ref you want to point at
+ hooks:
+ - id: regal-lint
+ # - id: ...
+```
+
+## Hooks Available
+
+### `regal-lint`
+
+
+
+Runs Regal against all staged `.rego` files, aborting the commit if any fail.
+
+- requires the `go` build chain is installed and available on `$PATH`
+- will build and install the tagged version of Regal in an isolated `GOPATH`
+- ensures compatibility between versions
+
+### `regal-lint-use-path`
+
+
+
+Runs Regal against all staged `.rego` files, aborting the commit if any fail.
+
+- requires the `regal` package is already installed and available on `$PATH`.
+
+### `regal-download`
+
+
+
+Runs Regal against all staged `.rego` files, aborting the commit if any fail.
+
+- Downloads the latest `regal` binary from Github.
diff --git a/docs/projects/regal/remote-features.md b/docs/projects/regal/remote-features.md
new file mode 100644
index 0000000000..e7731eae5d
--- /dev/null
+++ b/docs/projects/regal/remote-features.md
@@ -0,0 +1,32 @@
+---
+sidebar_position: 11
+---
+
+
+# Remote Features
+
+This page outlines the features of Regal that need internet access to function.
+
+## Checking for Updates
+
+Regal will check for updates on startup. If a new version is available,
+Regal will notify you by writing a message in stderr.
+
+An example of such a message is:
+
+```txt
+A new version of Regal is available (v0.23.1). You are running v0.23.0.
+See https://github.com/open-policy-agent/regal/releases/tag/v0.23.1 for the latest release.
+```
+
+This message is based on the local version set in the Regal binary, and **no
+user data is sent** to GitHub where the releases are hosted.
+
+This same function will also write to the file at: `$HOME/.config/regal/latest_version.json`,
+this is used as a cache of the latest version to avoid consuming excessive
+GitHub API rate limits when using Regal.
+
+This functionality can be disabled in two ways:
+
+* Using `.regal/config.yaml` / `.regal.yaml`: set `features.remote.check-version` to `false`.
+* Using an environment variable: set `REGAL_DISABLE_CHECK_VERSION` to `true`.
diff --git a/docs/projects/regal/rules/_category_.json b/docs/projects/regal/rules/_category_.json
new file mode 100644
index 0000000000..f8f3c8357a
--- /dev/null
+++ b/docs/projects/regal/rules/_category_.json
@@ -0,0 +1 @@
+{ "collapsed": false }
diff --git a/docs/projects/regal/rules/bugs/annotation-without-metadata.md b/docs/projects/regal/rules/bugs/annotation-without-metadata.md
new file mode 100644
index 0000000000..baeb022d26
--- /dev/null
+++ b/docs/projects/regal/rules/bugs/annotation-without-metadata.md
@@ -0,0 +1,49 @@
+# annotation-without-metadata
+
+**Summary**: Annotation without metadata
+
+**Category**: Bugs
+
+**Avoid**
+```rego
+package policy
+
+# description: allow allows
+allow if {
+ # ... some conditions
+}
+```
+
+**Prefer**
+```rego
+package policy
+
+# METADATA
+# description: allow allows
+allow if {
+ # ... some conditions
+}
+```
+
+## Rationale
+
+A comment that starts with `+ regal+
+ adj : of notable excellence or magnificence : splendid +
+ -- Merriam-Webster +
No matching rules
+ : ( +| Rule | +Summary | +
|---|---|
| + {rule.id} + | +{rule.summary} | +