StyraInc / regal

Regal is a linter and language server for Rego, bringing your policy development experience to the next level!
https://docs.styra.com/regal
Apache License 2.0
251 stars 34 forks source link

Provide `regal fix` and LSP Code Action for `directory-package-mismatch` #1025

Closed anderseknert closed 1 week ago

anderseknert commented 2 weeks ago

Having restructured our own code as part of building the directory-package-mismatch rule, I'm now more convinced that this change is good, or even great, for large projects in particular. In order to make it simpler for users to remediate this though, we'll need to follow up with a regal fix fixer (that potentially can fix entire projects) and a Code Action that can fix this for a single file from within the comfort of one's editor.

regal fix

One thing we need to ensure here is that the fix must not run if there are notices emitted by the linter. Notices mean we don't have enough information to determine whether the package is correct or not. So either we respect that, or we make a new and better attempt to find out.

Another thing we'll need to ensure is that this command cleans up empty directories that it has left behind. So for example, if there's a project that looks like this:

code/
  foo/
    policy1.rego  # package policy.foo.bar
    policy2.rego. # package policy.foo.baz
README.md

Running regal fix . in the project root directory, the result would be:

policy/
  foo/
    bar/
      policy1.rego  # package policy.foo.bar
    baz/
      policy2.rego. # package policy.foo.baz
README.md

And the code directory no longer there.

Code Action

Should not be too complicated. Really just a new code action triggering an execute command which does the fix. Since it'll involve moving a file, we'll want to ensure the result is immediately apparent in the editor, and that things like possible issues are now reported at the new location.

anderseknert commented 2 weeks ago

One obvious thing to take into account is whether a file of that name already exists in the directory targeted 😅 If that's the case, we could just add a number, or some identifer like _moved, or simply fail.