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

richer dep semantics

frioux opened this issue · comments

One thing we do at ZR is have a set of packages called ./common/go/...; these packages are intended to be used by any other part of our monorepo, and thus are roots of the dep graph and are forbidden (by policy) from depending on other parts of the repo. We currently implement this with a gnarly go list invocation, but it just struck me that this could be a nice bit of depguard functionality, though I'm not sure what the interface would look like. Maybe it's some kind of new type (whitelist, blacklist, graph-blacklist?)

Does this make sense? If this is too weird or special case I'm fine implementing it elsewhere.

Just to make sure I understand, you are asking about local imports? So in a package, you have a local imports to ../../common/go or whatever the local reference would be, that you don't want them to use?

So I guess you are not using golangci lint then? I think I can modify the command here then without touching the package. I may get to this tonight. Are you thinking glob or regular expression?

If you are using golangci lint, it gives you the option to filter down like you suggest.

Rereading I may understand a bit better. You have many packages in single repo (mono repo which I would love to chat with you about cause we are doing that at ACS Technologies). You want a set of deps to be black/white listed from some of those packages, black/white list other deps for a different set of packages in the the same repo? Presumingly with glob?

here's our current actual implementation, which I think would both be sped up and maybe more generally useful with these richer semantics:

    # Complain if anything in common imports our code from outside of common.
    list=$(go list -f '{{ .ImportPath }} {{ join .Deps " " }} {{ join .TestImports " " }} {{ join .XTestImports " " }}' $packages)
    out=$(echo "$list" \
        | awk '/^go\.zr.org\/common\// {for (f=2; f<=NF; f++) {split($f,s,"/");if (s[1]=="go.zr.org" && s[2] != "common") {print $1" imports "$f" from outside of common!"}}}')
    [ "$out" != "" ] && echo "$out" && failures+=("FAIL: Please fix the above imports.")

So something like the following configuration would help. Maybe not this exactly as I need to see what I am given in terms of currently running lint for package, but I think it gets the point across.

{
    "go.zr.org/other/...": {
        "type": "blacklist",
        "packages": [
            "go.zr.org/common"
        ]
    }
}

I wonder if we can come up with a better configuration structure to support this and #13

#15 long awaited! But this is a proof of concept PR. I still have more vetting I need to do before I import it into golangci-lint. Doesn't do the functions as that will need to pull in more information and probably slow down the lint pretty badly.

I made it a new command called constraints even though it uses the same stuff under the hood as depguard, to make transitions easier, it made the most since to make it different.

Found an issue with the pattern/prefix matching... And it is criticle... first iteration actually has the same issue... Will take a minute to solve in the most efficient and easy to maintain fashion.

Sorry I didn't come back to this, but my WIP V2 branch already has a list of files for a listing in mind.

Have this working in the v2 branch to eventually get tagged.