Files
releases/docs/projects/regal/rules/idiomatic/directory-package-mismatch.md
T
Charlie Egan 071f4ea99b docs: Update broken links (#8285)
* Update Regal documentation

Sync documentation with upstream Regal repository to reflect latest changes.

This addresses a number of broken link issues from the checker before.

Signed-off-by: Charlie Egan <charlie_egan@apple.com>

* docs: Update release links

these links create some issues in the link checker report.

https://github.com/open-policy-agent/opa/issues/8278

```
Errors in ./docs/docs/deploy/aws/ec2.mdx

[404] https://github.com/open-policy-agent/opa/releases/download/v%7B%7Bversion%7D%7D/opa_linux_amd64 | Rejected status code (this depends on your "accept" configuration): Not Found
Errors in ./docs/docs/deploy/azure/vm.mdx

[404] https://github.com/open-policy-agent/opa/releases/download/v%7B%7Bversion%7D%7D/opa_linux_amd64 | Error (cached)
Errors in ./docs/docs/deploy/google-cloud/gce.mdx

[404] https://github.com/open-policy-agent/opa/releases/download/v%7B%7Bversion%7D%7D/opa_linux_amd64 | Error (cached)
```

These are not actually broken, they are just untemplated when the checker sees them.

I figured since they are long lines we can use use a $REPO variable instead,
to ensure that we only have valid https:// starting links on those pages.

Signed-off-by: Charlie Egan <charlie_egan@apple.com>

* Remove broken blog link

https://github.com/open-policy-agent/opa/issues/8278

this link appears to be gone with no redirect.

Signed-off-by: Charlie Egan <charlie_egan@apple.com>

* docs: Fix outdated and broken documentation URLs

Update various documentation links, SlideShare links, and external references
that were resulting in redirects.

Fixes https://github.com/open-policy-agent/opa/issues/8278

Signed-off-by: Charlie Egan <charlie_egan@apple.com>

* Update broken regal links

The other rules are using abs links here.

Signed-off-by: Charlie Egan <charlie_egan@apple.com>

---------

Signed-off-by: Charlie Egan <charlie_egan@apple.com>
2026-02-03 16:58:04 +00:00

6.5 KiB

directory-package-mismatch

Summary: Directory structure should mirror package

Category: Idiomatic

Automatically fixable: Yes

Rationale

Quickly finding the package you're looking for in a policy repository is made much easier when package paths are mirrored in the directory structure of your project. Meaning that if the name of your package is permissions.users.claims, it should reside in a file under the permissions/users/claims directory. Note however that any number of files can contribute to the same package! The permissions/users/claims directory may thus contain several policy files that all declare package permissions.users.claims.

Example

An example of directory structure for a project following this convention might look like this:

# Directory structure                   # Package path
.
├── README.md
└── bundle
    └── authorization
        ├── main.rego                   # authorization
        └── rbac
            ├── data.json               # authorization.rbac
            ├── roles
            │   └── roles.rego          # authorization.rbac.roles
            │   └── roles_test.rego     # authorization.rbac.roles_test
            └── users
                ├── customers.rego      # authorization.rbac.users
                ├── customers_test.rego # authorization.rbac.users_test
                ├── internal.rego       # authorization.rbac.users
                └── internal_test.rego  # authorization.rbac.users_test

Tests

Astute observers may notice that the test files in the example above are placed in the same directory as the policies they test. This may seem to contradict the test-outside-test-package rule, which says that any test package should have a _test suffix in its package path. However, putting tests next to the file they target arguably makes it easier to find, and is a common practice in the OPA community. This rule therefore by default ignores the _test suffix when determining whether the package path matches the directory structure.

This behavior can be changed by setting the exclude-test-suffix configuration option to false, in which case package paths with a _test suffix also will be required to reside in a directory with a _test suffix.

Setting the exclude-test-suffix option to false means the example from above would now look like this:

# Directory structure                   # Package path
.
├── README.md
└── bundle
    └── authorization
        ├── main.rego                   # authorization
        └── rbac
            ├── data.json               # authorization.rbac
            ├── roles
            │   └── roles.rego          # authorization.rbac.roles
            ├── roles_test
            │   └── roles_test.rego     # authorization.rbac.roles_test
            ├── users
            │   ├── customers.rego      # authorization.rbac.users
            │   └── internal.rego       # authorization.rbac.users
            └── users_test
                ├── customers_test.rego # authorization.rbac.users_test
                └── internal_test.rego  # authorization.rbac.users_test

Whichever way you choose is up to you. Consistency is key!

Bundles

While directory structure doesn't matter to OPA when parsing policies, directories parsed as bundles will read data (data.json or data.yaml) files and insert the data in the data document tree based on the directory structure relative to the bundle root. Having policies structured in the same manner provides a uniform experience, and makes it easier to understand where both policies and data come from.

regal fix & Editor Support

Regal's fix command can automatically rename files in a project to ensure compliance with this rule. This is particularly useful when refactoring a project with many files.

:::info Note that files will be renamed relative to their nearest root, see the documentation on roots when using this rule with policy roots different from the project root. :::

Editors integrating Regal's language server will automatically display suggestions for idiomatic package paths based on the directory structure in which a policy resides. The image below demonstrates a new policy being created inside an authorization/rbac/roles directory, and the editor (via Regal) suggesting the package path authorization.rbac.roles.

<img src={require('../../assets/rules/pkg_name_completion.png').default} alt="Package path auto-completion in VS Code"/>

In addition, empty files will be be 'formatted' to have the correct package based on the directory structure. Newly created Rego files are treated in much the same way. When a new file is created, the server will send a series of edits back to set the content. If exclude-test-suffix is set to false, the file will also be moved if required to the _test directory for that package.

Configuration Options

This linter rule provides the following configuration options:

rules:
  idiomatic:
    directory-package-mismatch:
      # one of "error", "warning", "ignore"
      level: error
      # exclude _test suffixes from package paths before comparing
      # them to directory structure paths. when set to false, a
      # package like authz.policy_test would need to be placed in
      # an authz/policy_test directory, and if set to true (default)
      # would be expected to be in authz/policy
      exclude-test-suffix: true