constabulary / gb

gb, the project based build tool for Go
https://getgb.io/
MIT License
2.15k stars 150 forks source link

`gb list` Package struct #648

Open kegsay opened 7 years ago

kegsay commented 7 years ago

I want to create a dependency graph of my project which uses gb. I naively thought I could do what these slides suggest, but alas, it does not work.

Currently there is this command:

$ gb help list
usage: gb list [-s] [-f format] [-json] [packages]

List lists packages imported by the project.

The default output shows the package import paths:

    % gb list github.com/constabulary/...
    github.com/constabulary/gb
    github.com/constabulary/gb/cmd
    github.com/constabulary/gb/cmd/gb
    github.com/constabulary/gb/cmd/gb-env
    github.com/constabulary/gb/cmd/gb-list

Flags:
    -f
        alternate format for the list, using the syntax of package template.
        The default output is equivalent to -f '{{.ImportPath}}'. The struct
        being passed to the template is currently an instance of gb.Package.
        This structure is under active development and it's contents are not
        guaranteed to be stable.
[...]

gb.Package currently looks like:

// Package represents a resolved package from the Project with respect to the Context.
type Package struct {
    *Context
    *importer.Package
    TestScope     bool
    ExtraIncludes string // hook for test
    Stale         bool   // is the package out of date wrt. its cached copy
    Imports       []*Package
}

// importer.Package
type Package struct {
    importer               // the importer context that loaded this package
    Dir           string   // directory containing package sources
    Name          string   // package name
    ImportPath    string   // import path of package ("" if unknown)
    Root          string   // root of Go tree where this package lives
    SrcRoot       string   // package source root directory ("" if unknown)
    PkgTargetRoot string   // architecture dependent install root directory ("" if unknown)
    Standard      bool     // package found in GOROOT
    AllTags       []string // tags that can influence file selection in this directory
    ConflictDir   string   // this directory shadows Dir in $GOPATH

    // Source files
    GoFiles        []string // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles)
    CgoFiles       []string // .go source files that import "C"
    IgnoredGoFiles []string // .go source files ignored for this build
    CFiles         []string // .c source files
    CXXFiles       []string // .cc, .cpp and .cxx source files
    MFiles         []string // .m (Objective-C) source files
    HFiles         []string // .h, .hh, .hpp and .hxx source files
    SFiles         []string // .s source files
    SwigFiles      []string // .swig files
    SwigCXXFiles   []string // .swigcxx files
    SysoFiles      []string // .syso system object files to add to archive

    // Cgo directives
    CgoCFLAGS    []string // Cgo CFLAGS directives
    CgoCPPFLAGS  []string // Cgo CPPFLAGS directives
    CgoCXXFLAGS  []string // Cgo CXXFLAGS directives
    CgoLDFLAGS   []string // Cgo LDFLAGS directives
    CgoPkgConfig []string // Cgo pkg-config directives

    // Dependency information
    Imports   []string                    // imports from GoFiles, CgoFiles
    ImportPos map[string][]token.Position // line information for Imports

    // Test information
    TestGoFiles    []string                    // _test.go files in package
    TestImports    []string                    // imports from TestGoFiles
    TestImportPos  map[string][]token.Position // line information for TestImports
    XTestGoFiles   []string                    // _test.go files outside package
    XTestImports   []string                    // imports from XTestGoFiles
    XTestImportPos map[string][]token.Position // line information for XTestImports
}

This contrasts with go list:

$ go help list
usage: go list [-e] [-f format] [-json] [build flags] [packages]

List lists the packages named by the import paths, one per line.

The default output shows the package import path:

    bytes
    encoding/json
    github.com/gorilla/mux
    golang.org/x/net/html

The -f flag specifies an alternate format for the list, using the
syntax of package template.  The default output is equivalent to -f
'{{.ImportPath}}'. The struct being passed to the template is:

    type Package struct {
        Dir           string // directory containing package sources
        ImportPath    string // import path of package in dir
        ImportComment string // path in import comment on package statement
        Name          string // package name
        Doc           string // package documentation string
        Target        string // install path
        Shlib         string // the shared library that contains this package (only set when -linkshared)
        Goroot        bool   // is this package in the Go root?
        Standard      bool   // is this package part of the standard Go library?
        Stale         bool   // would 'go install' do anything for this package?
        Root          string // Go root or Go path dir containing this package

        // Source files
        GoFiles        []string // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles)
        CgoFiles       []string // .go sources files that import "C"
        IgnoredGoFiles []string // .go sources ignored due to build constraints
        CFiles         []string // .c source files
        CXXFiles       []string // .cc, .cxx and .cpp source files
        MFiles         []string // .m source files
        HFiles         []string // .h, .hh, .hpp and .hxx source files
        SFiles         []string // .s source files
        SwigFiles      []string // .swig files
        SwigCXXFiles   []string // .swigcxx files
        SysoFiles      []string // .syso object files to add to archive

        // Cgo directives
        CgoCFLAGS    []string // cgo: flags for C compiler
        CgoCPPFLAGS  []string // cgo: flags for C preprocessor
        CgoCXXFLAGS  []string // cgo: flags for C++ compiler
        CgoLDFLAGS   []string // cgo: flags for linker
        CgoPkgConfig []string // cgo: pkg-config names

        // Dependency information
        Imports []string // import paths used by this package
        Deps    []string // all (recursively) imported dependencies

        // Error information
        Incomplete bool            // this package or a dependency has an error
        Error      *PackageError   // error loading package
        DepsErrors []*PackageError // errors loading dependencies

        TestGoFiles  []string // _test.go files in package
        TestImports  []string // imports from TestGoFiles
        XTestGoFiles []string // _test.go files outside package
        XTestImports []string // imports from XTestGoFiles
    }

Whilst most of the fields look to be the same, Deps is noticeably missing from this. This means that you can't easily produce dependency graphs for gb projects. It looks like it should be added here but I'm not sure exactly how go list populates this list.

How easy/hard would it be to add in .Deps to importer.Package so I can generate pretty graphs? :innocent:

davecheney commented 7 years ago

It shouldn't be too hard to materialise .Deps, as long as it doesn't slow anything down.

kegsay commented 7 years ago

In case anyone cares, you can do this with go list provided you set GOPATH correctly e.g:

GOPATH=$GOPATH:$(pwd):$(pwd)/vendor

I'd still like to implement this into gb because I feel having parity with the equivalent go command is important, plus I think it's probably superficial enough to serve as a good starting point to get to know how this project works.

nubunto commented 7 years ago

This looks friendly enough for a beginner to gb. I'll take this.

nubunto commented 7 years ago

Actually, reading over some other issues I failed at discussing design before actually diving in the code. That being said, I did took a stab at it, but I think that proper guidance/pairing would help me out big time :)