OpenPeeDeeP / depguard

Go linter that checks if package imports are in a list of acceptable packages.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

make it easier to deny "some" packages from a dependency

thaJeztah opened this issue · comments

I am trying to configure depguard to prevent introduction of additional packages from a dependencies in our project (https://github.com/containerd/containerd), but so far I haven't found a good way to construct this in golangci-lint's configuration. It's very possible that I just didin't find the right combination, so let me try to describe our case;

We currently depend on the libcontainer/user package from runc (github.com/opencontainers/runc/libcontainer/user), want to prevent additional packages being used from that depository (libcontainer should only be used for existing code, and not for new things).

The containerd maintainers have put effort into moving away from libcontainer dependencies, with the exception of the libcontainer/user package (which is pending to be moved to a separate module).

We want to use depguard to prevent accidentally re-introducing further (indirect) dependencies from runc, and want to "deny" all of github.com/opencontainers/runc, with the exeception of the existing libcontainer/user package.

My initial attempt was to create a rule that denies all of github.com/opencontainers/runc, and allows github.com/opencontainers/runc/libcontainer/user;

linters-settings:
  depguard:
    rules:
      libcontainer:
        allow:
          - "github.com/opencontainers/runc/libcontainer/user$"
        deny:
          - pkg: github.com/opencontainers/runc
            desc: We don't want to introduce more dependencies on runc (libcontainer), unless there is no other option.

Unfortunately, this doesn't work, because (IIUC);

  • rules with a deny list default "allow all"
  • unless an allow is configured, in which case only packages in the allow list are accepted (and are not part of the deny list

While there is a convenience variable for stdlib ($gostd), there is no equivalent for "all" dependencies (the default), and because our project has many dependencies; constructing a list of all allowed (existing) packages would result in a very long (and hard to maintain) configuration.

Likewise, a deny list for the github.com/opencontainers/runc dependency (and anything inside it) is also hard to maintain, as it would require us to maintain a full list of all packages in the repository (to prevent missing any new package added to that repository). To illustrate; this is what that would look like just for the libcontainer package in runc;

rules:
  libcontainer:
    deny:
      - pkg: "github.com/opencontainers/runc"
      - pkg: "github.com/opencontainers/runc/libcontainer"
      - pkg: "github.com/opencontainers/runc/libcontainer/apparmor"
      - pkg: "github.com/opencontainers/runc/libcontainer/capabilities"
      - pkg: "github.com/opencontainers/runc/libcontainer/cgroups"
      - pkg: "github.com/opencontainers/runc/libcontainer/configs"
      - pkg: "github.com/opencontainers/runc/libcontainer/devices"
      - pkg: "github.com/opencontainers/runc/libcontainer/integration"
      - pkg: "github.com/opencontainers/runc/libcontainer/intelrdt"
      - pkg: "github.com/opencontainers/runc/libcontainer/keys"
      - pkg: "github.com/opencontainers/runc/libcontainer/keys"
      - pkg: "github.com/opencontainers/runc/libcontainer/logs"
      - pkg: "github.com/opencontainers/runc/libcontainer/nsenter"
      - pkg: "github.com/opencontainers/runc/libcontainer/seccomp"
      - pkg: "github.com/opencontainers/runc/libcontainer/specconv"
      - pkg: "github.com/opencontainers/runc/libcontainer/system"
      - pkg: "github.com/opencontainers/runc/libcontainer/userns"
      - pkg: "github.com/opencontainers/runc/libcontainer/utils"

Perhaps I overlooked existing ones! So if there are options I overlooked, I'm "all ears" 😄

#56

Would something like the LAX vs STRICT variable work? Instead of saying in allow AND not in deny, but in allow OR not in deny.

I believe that would give the appearance of the "all" you are specifying.

If you pull the latest of the V2 branch and try with listMode = Lax, I believe this covers your situation where it is allowed by default.

Specifically these tests seem to handle what you are trying to do.
https://github.com/OpenPeeDeeP/depguard/blob/f7542dc092be642d323fe22d8ec405580c53e5a8/settings_test.go#L834C1-L839C6
https://github.com/OpenPeeDeeP/depguard/blob/f7542dc092be642d323fe22d8ec405580c53e5a8/settings_test.go#L823C1-L827C6

I'll close this ticket once this repo is tagged.

I am actually going to close for now. I've got a few other things I want to push in v2.2.0. So added a milestone to track it.