build(deps): bump github.com/open-policy-agent/opa from 0.51.0 to 0.59.0

Bumps [github.com/open-policy-agent/opa](https://github.com/open-policy-agent/opa) from 0.51.0 to 0.59.0.
- [Release notes](https://github.com/open-policy-agent/opa/releases)
- [Changelog](https://github.com/open-policy-agent/opa/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-policy-agent/opa/compare/v0.51.0...v0.59.0)

---
updated-dependencies:
- dependency-name: github.com/open-policy-agent/opa
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
dependabot[bot]
2023-12-05 09:47:11 +01:00
committed by Ralf Haferkamp
parent a6a6c22c14
commit 1f069c7c00
197 changed files with 73803 additions and 3024 deletions
+117 -28
View File
@@ -11,6 +11,7 @@ import (
"regexp"
"sort"
"strings"
"unicode"
"github.com/open-policy-agent/opa/ast"
"github.com/open-policy-agent/opa/internal/future"
@@ -24,6 +25,8 @@ type Opts struct {
// of partial evaluation, arguments maybe have been shuffled around, but still
// carry along their original source locations.
IgnoreLocations bool
RegoV1 bool
}
// defaultLocationFile is the file name used in `Ast()` for terms
@@ -35,15 +38,27 @@ const defaultLocationFile = "__format_default__"
// Rego module. If they don't, Source will return an error resulting from the attempt
// to parse the bytes.
func Source(filename string, src []byte) ([]byte, error) {
return SourceWithOpts(filename, src, Opts{})
}
func SourceWithOpts(filename string, src []byte, opts Opts) ([]byte, error) {
module, err := ast.ParseModule(filename, string(src))
if err != nil {
return nil, err
}
formatted, err := Ast(module)
if opts.RegoV1 {
errors := ast.CheckRegoV1(module)
if len(errors) > 0 {
return nil, errors
}
}
formatted, err := AstWithOpts(module, opts)
if err != nil {
return nil, fmt.Errorf("%s: %v", filename, err)
}
return formatted, nil
}
@@ -80,6 +95,8 @@ type fmtOpts struct {
// for ref heads -- if they do, we'll print all of them in a different way
// than if they don't.
refHeads bool
regoV1 bool
}
func AstWithOpts(x interface{}, opts Opts) ([]byte, error) {
@@ -98,6 +115,12 @@ func AstWithOpts(x interface{}, opts Opts) ([]byte, error) {
o := fmtOpts{}
if opts.RegoV1 {
o.regoV1 = true
o.ifs = true
o.contains = true
}
// Preprocess the AST. Set any required defaults and calculate
// values required for printing the formatted output.
ast.WalkNodes(x, func(x ast.Node) bool {
@@ -119,6 +142,9 @@ func AstWithOpts(x interface{}, opts Opts) ([]byte, error) {
case *ast.Import:
switch {
case isRegoV1Compatible(n):
o.contains = true
o.ifs = true
case future.IsAllFutureKeywords(n):
o.contains = true
o.ifs = true
@@ -150,8 +176,15 @@ func AstWithOpts(x interface{}, opts Opts) ([]byte, error) {
switch x := x.(type) {
case *ast.Module:
for kw := range extraFutureKeywordImports {
x.Imports = ensureFutureKeywordImport(x.Imports, kw)
if o.regoV1 {
x.Imports = ensureRegoV1Import(x.Imports)
}
if o.regoV1 || moduleIsRegoV1Compatible(x) {
x.Imports = future.FilterFutureImports(x.Imports)
} else {
for kw := range extraFutureKeywordImports {
x.Imports = ensureFutureKeywordImport(x.Imports, kw)
}
}
w.writeModule(x, o)
case *ast.Package:
@@ -263,13 +296,12 @@ func (w *writer) writeModule(module *ast.Module, o fmtOpts) {
return locLess(comments[i], comments[j])
})
// XXX: The parser currently duplicates comments for some reason, so we need
// to remove duplicates here.
comments = dedupComments(comments)
sort.Slice(others, func(i, j int) bool {
return locLess(others[i], others[j])
})
comments = trimTrailingWhitespaceInComments(comments)
comments = w.writePackage(pkg, comments)
var imports []*ast.Import
var rules []*ast.Rule
@@ -288,6 +320,14 @@ func (w *writer) writeModule(module *ast.Module, o fmtOpts) {
}
}
func trimTrailingWhitespaceInComments(comments []*ast.Comment) []*ast.Comment {
for _, c := range comments {
c.Text = bytes.TrimRightFunc(c.Text, unicode.IsSpace)
}
return comments
}
func (w *writer) writePackage(pkg *ast.Package, comments []*ast.Comment) []*ast.Comment {
comments = w.insertComments(comments, pkg.Location)
@@ -345,7 +385,7 @@ func (w *writer) writeRule(rule *ast.Rule, isElse bool, o fmtOpts, comments []*a
return comments
}
if o.ifs && partialSetException {
if (o.regoV1 || o.ifs) && partialSetException {
w.write(" if")
if len(rule.Body) == 1 {
if rule.Body[0].Location.Row == rule.Head.Location.Row {
@@ -453,7 +493,7 @@ func (w *writer) writeElse(rule *ast.Rule, o fmtOpts, comments []*ast.Comment) [
func (w *writer) writeHead(head *ast.Head, isDefault, isExpandedConst bool, o fmtOpts, comments []*ast.Comment) []*ast.Comment {
ref := head.Ref()
if head.Key != nil && head.Value == nil {
if head.Key != nil && head.Value == nil && !head.HasDynamicRef() {
ref = ref.GroundPrefix()
}
if o.refHeads || len(ref) == 1 {
@@ -484,8 +524,26 @@ func (w *writer) writeHead(head *ast.Head, isDefault, isExpandedConst bool, o fm
w.write("]")
}
}
if head.Value != nil && (head.Key != nil || ast.Compare(head.Value, ast.BooleanTerm(true)) != 0 || isExpandedConst || isDefault) {
if head.Assign {
if head.Value != nil &&
(head.Key != nil || ast.Compare(head.Value, ast.BooleanTerm(true)) != 0 || isExpandedConst || isDefault) {
// in rego v1, explicitly print value for ref-head constants that aren't partial set assignments, e.g.:
// * a -> parser error, won't reach here
// * a.b -> a contains "b"
// * a.b.c -> a.b.c := true
// * a.b.c.d -> a.b.c.d := true
isRegoV1RefConst := o.regoV1 && isExpandedConst && head.Key == nil && len(head.Args) == 0
if head.Location == head.Value.Location && head.Name != "else" && !isRegoV1RefConst {
// If the value location is the same as the location of the head,
// we know that the value is generated, i.e. f(1)
// Don't print the value (` = true`) as it is implied.
return comments
}
if head.Assign || o.regoV1 {
// preserve assignment operator, and enforce it if formatting for Rego v1
w.write(" := ")
} else {
w.write(" = ")
@@ -732,7 +790,12 @@ func (w *writer) writeTermParens(parens bool, term *ast.Term, comments []*ast.Co
func (w *writer) writeRef(x ast.Ref) {
if len(x) > 0 {
w.writeTerm(x[0], nil)
parens := false
_, ok := x[0].Value.(ast.Call)
if ok {
parens = x[0].Location.Text[0] == 40 // Starts with "("
}
w.writeTermParens(parens, x[0], nil)
path := x[1:]
for _, t := range path {
switch p := t.Value.(type) {
@@ -807,6 +870,7 @@ func (w *writer) writeCall(parens bool, x ast.Call, loc *ast.Location, comments
}
func (w *writer) writeInOperator(parens bool, operands []*ast.Term, comments []*ast.Comment, loc *ast.Location, f *types.Function) []*ast.Comment {
if len(operands) != len(f.Args()) {
// The number of operands does not math the arity of the `in` operator
operator := ast.Member.Name
@@ -909,12 +973,17 @@ func (w *writer) writeObjectComprehension(object *ast.ObjectComprehension, loc *
}
func (w *writer) writeComprehension(open, close byte, term *ast.Term, body ast.Body, loc *ast.Location, comments []*ast.Comment) []*ast.Comment {
if term.Location.Row-loc.Row > 1 {
if term.Location.Row-loc.Row >= 1 {
w.endLine()
w.startLine()
}
comments = w.writeTerm(term, comments)
parens := false
_, ok := term.Value.(ast.Call)
if ok {
parens = term.Location.Text[0] == 40 // Starts with "("
}
comments = w.writeTermParens(parens, term, comments)
w.write(" |")
return w.writeComprehensionBody(open, close, body, term.Location, loc, comments)
@@ -1280,21 +1349,6 @@ func skipPast(open, close byte, loc *ast.Location) (int, int) {
return i, offset
}
func dedupComments(comments []*ast.Comment) []*ast.Comment {
if len(comments) == 0 {
return nil
}
filtered := []*ast.Comment{comments[0]}
for i := 1; i < len(comments); i++ {
if comments[i].Location.Equal(comments[i-1].Location) {
continue
}
filtered = append(filtered, comments[i])
}
return filtered
}
// startLine begins a line with the current indentation level.
func (w *writer) startLine() {
w.inline = true
@@ -1386,6 +1440,24 @@ func ensureFutureKeywordImport(imps []*ast.Import, kw string) []*ast.Import {
return append(imps, imp)
}
func ensureRegoV1Import(imps []*ast.Import) []*ast.Import {
return ensureImport(imps, ast.RegoV1CompatibleRef)
}
func ensureImport(imps []*ast.Import, path ast.Ref) []*ast.Import {
for _, imp := range imps {
p := imp.Path.Value.(ast.Ref)
if p.Equal(path) {
return imps
}
}
imp := &ast.Import{
Path: ast.NewTerm(path),
}
imp.Location = defaultLocation(imp)
return append(imps, imp)
}
// ArgErrDetail but for `fmt` checks since compiler has not run yet.
type ArityFormatErrDetail struct {
Have []string `json:"have"`
@@ -1418,3 +1490,20 @@ func (d *ArityFormatErrDetail) Lines() []string {
"want: " + "(" + strings.Join(d.Want, ",") + ")",
}
}
func moduleIsRegoV1Compatible(m *ast.Module) bool {
for _, imp := range m.Imports {
if isRegoV1Compatible(imp) {
return true
}
}
return false
}
// isRegoV1Compatible returns true if the passed *ast.Import is `rego.v1`
func isRegoV1Compatible(imp *ast.Import) bool {
path := imp.Path.Value.(ast.Ref)
return len(path) == 2 &&
ast.RegoRootDocument.Equal(path[0]) &&
path[1].Equal(ast.StringTerm("v1"))
}