open-policy-agent / opa

Open Policy Agent (OPA) is an open source, general-purpose policy engine.
https://www.openpolicyagent.org
Apache License 2.0
9.33k stars 1.29k forks source link

opa fmt 2.0 #4508

Open anderseknert opened 2 years ago

anderseknert commented 2 years ago

The opa fmt command is great! The current version however has not moved at the same pace as the rest of the project, and could benefit from a remake. Creating this ticket to collect ideas and feature requests for a possible next iteration of the opa fmt command.

Some initial ideas from myself and previous tickets on the topic:

Original ticket: https://github.com/open-policy-agent/opa/issues/4076

Original ticket: https://github.com/open-policy-agent/opa/issues/2958

Original ticket: https://github.com/open-policy-agent/opa/issues/1549

More suggestions are welcome!

oren-zohar commented 2 years ago

@anderseknert not sure if this one is included in the list, but what about controlling the indentation (spaces vs tabs)

anderseknert commented 2 years ago

Thanks @oren-zohar!

Yeah I think controlling (i.e. configuration of) anything at all (indentation, max line length, style preferences) is a topic that definitely should be up for discussion. go fmt famously does not allow that, and I think the opa fmt command is largely modeled after that, but there are many other formatting tools that do allow configuration, so.. I don't know 🤷😄

One obvious benefit of keeping a single coherent model for formatting is of course that any policy formatted with the tool will pass the formatter checks regardless of where it came from. And maintenance of the tool will likely be more cumbersome if configuration is added to the mix. Perhaps a middle way could be to make the code modular enough that it's easy for anyone to simply extract it and build their own customizations on top of it.

anderseknert commented 2 years ago

Sorting and grouping imports!

import data.aws.iam.user.excluded_principal_name
import data.assertions.assert_not_in
import data.test_helpers.create_with_properties
import future.keywords
import data.aws.iam.user.deny
import data.assertions.assert_in
import data.test_helpers.with_properties

=>

import future.keywords

import data.aws.iam.user.deny
import data.aws.iam.user.excluded_principal_name

import data.assertions.assert_in
import data.assertions.assert_not_in

import data.test_helpers.create_with_properties
import data.test_helpers.with_properties
srenatus commented 2 years ago

It would be nice to have both --fail and --diff at the same time. Right now, --fail trumps --diff.

NitroCao commented 2 years ago

Optimize long lines.

dropped_capabilities[affected] {
    ctrs := containers[_]
    affected = {"image": ctrs.image, "caps_dropped": {cap | cap := ctrs.securityContext.capabilities.drop[_]; count(cap) > 0}}
}

=>

dropped_capabilities[affected] {
    ctrs := containers[_]
    affected = {
        "image": ctrs.image,
        "caps_dropped": {cap |
            cap := ctrs.securityContext.capabilities.drop[_]
            count(cap) > 0
        },
    }
}
oren-zohar commented 2 years ago

It would be nice to have both --fail and --diff at the same time. Right now, --fail trumps --diff.

also --fail and --list please!

anderseknert commented 2 years ago

The formatting currently applied to else clauses, where opa fmt adds a body with an empty true in it, feels like a low-hanging fruit to improve. I.e:

number := 10 {
    input.foo
} else := 20

formats to ->

number := 10 {
    input.foo
} else := 20 {
    true
}

The body added to the else clause here is IMHO redundant, and does not help make the rule more readable.

EDIT: This was fixed in OPA v0.47.0 :)

stale[bot] commented 2 years ago

This issue has been automatically marked as inactive because it has not had any activity in the last 30 days.

charlieegan3 commented 1 year ago

Related to https://github.com/StyraInc/rego-style-guide/pull/19 merged today, might it make sense to automatically correct this? i.e.

 full_name := name {
     name := concat(", ", [input.first_name, input.last_name])
 }

 divide_by_ten(x) := y {
     y := x / 10
 }

Formats to:

 full_name := concat(", ", [input.first_name, input.last_name])

 divide_by_ten(x) := x / 10
anderseknert commented 1 year ago

@charlieegan3 it does make sense, although it's hard to say where the responsibilities of the formatter starts and ends. I could imagine this as a linter rule just as well. Well, if we had one, that is 😆

stale[bot] commented 1 year ago

This issue has been automatically marked as inactive because it has not had any activity in the last 30 days.

stale[bot] commented 1 year ago

This issue has been automatically marked as inactive because it has not had any activity in the last 30 days.

shinebayar-g commented 3 months ago

I'd like to add feature request for print width / line length feature. opa fmt is formatting multi line string to a really long line.

Before (please ignore + usage, that seems to be wrong) image

After image

stale[bot] commented 2 months ago

This issue has been automatically marked as inactive because it has not had any activity in the last 30 days. Although currently inactive, the issue could still be considered and actively worked on in the future. More details about the use-case this issue attempts to address, the value provided by completing it or possible solutions to resolve it would help to prioritize the issue.