Giter Site home page Giter Site logo

Comments (7)

bradleyfalzon avatar bradleyfalzon commented on September 23, 2024 1

Ah thanks @mholt, I see the issue.

It appears to be reproducible when the dependencies isn't installed at all. I.e. vendorcheck only alerts there's an issue when the program can compile.

[bradleyf@srv4 ~]$ docker run -it --rm golang:1.8 bash
root@54944206edc0:/go#
root@54944206edc0:/go#
root@54944206edc0:/go# mkdir src/vendtest && cd src/vendtest
root@54944206edc0:/go/src/vendtest# cat > main.go <<EOF
> package main
>
> import "github.com/pkg/errors"
>
> func main() {
>         println(errors.New("foo error"))
> }
> EOF
root@54944206edc0:/go/src/vendtest# go get github.com/FiloSottile/vendorcheck
root@54944206edc0:/go/src/vendtest# vendorcheck
root@54944206edc0:/go/src/vendtest# go get github.com/pkg/errors
root@54944206edc0:/go/src/vendtest# vendorcheck
[!] dependency not vendored: github.com/pkg/errors

You can see the first invocation of vendorcheck didn't detect the missing dependency, because it wasn't installed at all.

Could this have been the cause of your issue then?

from vendorcheck.

bradleyfalzon avatar bradleyfalzon commented on September 23, 2024 1

If this is the issue, then the simplest change would be to stop hiding compilation errors, and treat them as fatal:

diff --git a/main.go b/main.go
index 81ede3a..a3cc818 100644
--- a/main.go
+++ b/main.go
@@ -39,8 +39,8 @@ func main() {
 func missing(args []string, tests bool) {
        var conf loader.Config
        conf.ParserMode = parser.ImportsOnly
-       conf.AllowErrors = true
-       conf.TypeChecker.Error = func(error) {}
+       //conf.AllowErrors = true
+       conf.TypeChecker.DisableUnusedImportCheck = true
        for _, p := range args {
                if strings.Index(p, "/vendor/") != -1 {
                        // ignore vendored packages (if they are not imported by real ones)

This changes the behaviour into:

root@72c150e13374:/go/src/github.com/mholt/caddy# go install github.com/FileSottile/vendorcheck && vendorcheck ./...
/go/src/github.com/mholt/caddy/caddytls/config.go:12:2: could not import github.com/codahale/aesnicheck (cannot find package "github.com/codahale/aesnicheck" in any of:
        /go/src/github.com/mholt/caddy/vendor/github.com/codahale/aesnicheck (vendor tree)
        /usr/local/go/src/github.com/codahale/aesnicheck (from $GOROOT)
        /go/src/github.com/codahale/aesnicheck (from $GOPATH))
2017/07/23 04:28:29 couldn't load packages due to errors: github.com/mholt/caddy/caddytls

The DisableUnusedImportCheck is required because the parser is only loading the imports, and none of them are used, so the type checker reports those errors. We disable this check with the DisableUnusedImportCheck flag.

Once we add the dependency to out GOPATH, vendorcheck reports the violation correctly:

root@72c150e13374:/go/src/github.com/mholt/caddy# go get github.com/codahale/aesnicheck
root@72c150e13374:/go/src/github.com/mholt/caddy# go install github.com/FileSottile/vendorcheck && vendorcheck ./...
[!] dependency not vendored: github.com/codahale/aesnicheck

And when we vendor the dependency, we're no longer in violation:

root@72c150e13374:/go/src/github.com/mholt/caddy# mv $GOPATH/src/github.com/codahale vendor/github.com/
root@72c150e13374:/go/src/github.com/mholt/caddy# go install github.com/FileSottile/vendorcheck && vendorcheck ./...
root@72c150e13374:/go/src/github.com/mholt/caddy#

But this solution isn't ideal:

  1. vendorcheck may then fail when there's other types of errors, such as unused variables
  2. The cannot find package error is quite verbose, this was vendorcheck's responsibility, and it didn't handle that condition too well.

Other options could be to:

  1. String match on that particular cannot find package error and show a more appropriate error
  2. Document that vendorcheck needs a correct program (and show an error when it fails as discussed)

A final option could be using the AST from the parser instead of type checker to find all imports, and if a path for an import could not be found, show a more appropriate error. For example:

diff --git a/main.go b/main.go
index 81ede3a..fc89884 100644
--- a/main.go
+++ b/main.go
@@ -57,6 +57,40 @@ func missing(args []string, tests bool) {
                log.Fatal(err)
        }

+       importToFS := make(map[string]string) // map import path to fs path
+       for _, pi := range prog.AllPackages {
+               if len(pi.Files) == 0 {
+                       continue // virtual stdlib package
+               }
+               // Strip vendor prefix, import paths could be
+               // github.com/pkg/errors            <- not vendored
+               // foo/vendor/github.com/pkg/errors <- vendored
+               ipath := pi.String()
+               if indx := strings.LastIndex(pi.String(), "vendor/"); indx != -1 {
+                       ipath = pi.String()[indx+len("vendor/"):]
+               }
+               afile := prog.Fset.File(pi.Files[0].Pos()).Name()
+               importToFS[ipath] = filepath.Dir(afile)
+       }
+
+       for _, pi := range prog.Imported {
+               for _, file := range pi.Files {
+                       for _, imprt := range file.Imports {
+                               imprtPath := strings.Trim(imprt.Path.Value, `"`)
+                               fsPath, ok := importToFS[imprtPath]
+                               if !ok {
+                                       fmt.Printf("could not determine path for import %v\n", imprtPath)
+                               } else {
+                                       if !strings.Contains(fsPath, "/vendor/") {
+                                               fmt.Printf("dependency %v is not vendored (found at %v)\n", imprtPath, fsPath)
+                                       } else {
+                                               fmt.Printf("dependency %v *is* vendored (found at %v)\n", imprtPath, fsPath)
+                                       }
+                               }
+                       }
+               }
+       }
+
        exitCode := 0
        for _, pi := range prog.AllPackages {
                if len(pi.Files) == 0 {

Changes the behaviour to:

root@72c150e13374:/go/src/vendtest# vendorcheck ./...
could not determine path for import github.com/pkg/errors
root@72c150e13374:/go/src/vendtest# go get ./...
root@72c150e13374:/go/src/vendtest# vendorcheck ./...
dependency github.com/pkg/errors is not vendored (found at /go/src/github.com/pkg/errors)
[!] dependency not vendored: github.com/pkg/errors
root@72c150e13374:/go/src/vendtest# mkdir -p vendor/github.com/pkg && mv $GOPATH/src/github.com/pkg/errors vendor/github.com/pkg/
root@72c150e13374:/go/src/vendtest# vendorcheck ./...
dependency github.com/pkg/errors *is* vendored (found at /go/src/vendtest/vendor/github.com/pkg/errors)
root@72c150e13374:/go/src/vendtest#

The proposed patch still has at least two edge cases (stdlib imports and sub package imports would be incorrectly marked as a violation), but that's the general idea. It could replace then replace the existing for _, pi := range prog.AllPackages loop in missing function.

from vendorcheck.

bradleyfalzon avatar bradleyfalzon commented on September 23, 2024

This looks like it could just be due to vendorcheck doesn't, by default, check for dependencies in tests, and can be enabled with the -t option.

$ vendorcheck --help
Usage: vendorcheck [-t] package [package ...]
  -t    also check dependencies of test files
  -u    print unused vendored packages instead

from vendorcheck.

mholt avatar mholt commented on September 23, 2024

That's what I thought at first too, but the file the error is reported from (caddytls/config.go) is not a test file.

from vendorcheck.

mholt avatar mholt commented on September 23, 2024

@bradleyfalzon Wow, yes, I do believe that is accurate: the Go tool reports that the dependency was not found in my GOROOT or GOPATH at all. Nice work digging into this. My preference leans toward the AST since it doesn't rely on the program being correct, BUT I do understand the complexities of that. I'll let @FiloSottile give his feedback.

from vendorcheck.

bradleyfalzon avatar bradleyfalzon commented on September 23, 2024

Thanks @mholt, I'm of two minds, I think hiding the error and documenting that vendorcheck requires a correct program is probably enough. The scenario where not all dependencies are there is probably rare, and if it fails to compile its clear something wasn't vendored.

Also, the above AST method probably has some edge cases I haven't thought of.

from vendorcheck.

mholt avatar mholt commented on September 23, 2024

For a near-term solution, I'd definitely be OK going with requiring a correct program. Much simpler and less error-prone than trying to hunt down the problems of traversing the AST...

from vendorcheck.

Related Issues (5)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.