github.com/euank/go@v0.0.0-20160829210321-495514729181/src/cmd/go/list.go (about) 1 // Copyright 2011 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package main 6 7 import ( 8 "bufio" 9 "encoding/json" 10 "io" 11 "os" 12 "strings" 13 "text/template" 14 ) 15 16 var cmdList = &Command{ 17 UsageLine: "list [-e] [-f format] [-json] [build flags] [packages]", 18 Short: "list packages", 19 Long: ` 20 List lists the packages named by the import paths, one per line. 21 22 The default output shows the package import path: 23 24 bytes 25 encoding/json 26 github.com/gorilla/mux 27 golang.org/x/net/html 28 29 The -f flag specifies an alternate format for the list, using the 30 syntax of package template. The default output is equivalent to -f 31 '{{.ImportPath}}'. The struct being passed to the template is: 32 33 type Package struct { 34 Dir string // directory containing package sources 35 ImportPath string // import path of package in dir 36 ImportComment string // path in import comment on package statement 37 Name string // package name 38 Doc string // package documentation string 39 Target string // install path 40 Shlib string // the shared library that contains this package (only set when -linkshared) 41 Goroot bool // is this package in the Go root? 42 Standard bool // is this package part of the standard Go library? 43 Stale bool // would 'go install' do anything for this package? 44 StaleReason string // explanation for Stale==true 45 Root string // Go root or Go path dir containing this package 46 ConflictDir string // this directory shadows Dir in $GOPATH 47 BinaryOnly bool // binary-only package: cannot be recompiled from sources 48 49 // Source files 50 GoFiles []string // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles) 51 CgoFiles []string // .go sources files that import "C" 52 IgnoredGoFiles []string // .go sources ignored due to build constraints 53 CFiles []string // .c source files 54 CXXFiles []string // .cc, .cxx and .cpp source files 55 MFiles []string // .m source files 56 HFiles []string // .h, .hh, .hpp and .hxx source files 57 FFiles []string // .f, .F, .for and .f90 Fortran source files 58 SFiles []string // .s source files 59 SwigFiles []string // .swig files 60 SwigCXXFiles []string // .swigcxx files 61 SysoFiles []string // .syso object files to add to archive 62 63 // Cgo directives 64 CgoCFLAGS []string // cgo: flags for C compiler 65 CgoCPPFLAGS []string // cgo: flags for C preprocessor 66 CgoCXXFLAGS []string // cgo: flags for C++ compiler 67 CgoFFLAGS []string // cgo: flags for Fortran compiler 68 CgoLDFLAGS []string // cgo: flags for linker 69 CgoPkgConfig []string // cgo: pkg-config names 70 71 // Dependency information 72 Imports []string // import paths used by this package 73 Deps []string // all (recursively) imported dependencies 74 75 // Error information 76 Incomplete bool // this package or a dependency has an error 77 Error *PackageError // error loading package 78 DepsErrors []*PackageError // errors loading dependencies 79 80 TestGoFiles []string // _test.go files in package 81 TestImports []string // imports from TestGoFiles 82 XTestGoFiles []string // _test.go files outside package 83 XTestImports []string // imports from XTestGoFiles 84 } 85 86 The error information, if any, is 87 88 type PackageError struct { 89 ImportStack []string // shortest path from package named on command line to this one 90 Pos string // position of error (if present, file:line:col) 91 Err string // the error itself 92 } 93 94 The template function "join" calls strings.Join. 95 96 The template function "context" returns the build context, defined as: 97 98 type Context struct { 99 GOARCH string // target architecture 100 GOOS string // target operating system 101 GOROOT string // Go root 102 GOPATH string // Go path 103 CgoEnabled bool // whether cgo can be used 104 UseAllFiles bool // use files regardless of +build lines, file names 105 Compiler string // compiler to assume when computing target paths 106 BuildTags []string // build constraints to match in +build lines 107 ReleaseTags []string // releases the current release is compatible with 108 InstallSuffix string // suffix to use in the name of the install dir 109 } 110 111 For more information about the meaning of these fields see the documentation 112 for the go/build package's Context type. 113 114 The -json flag causes the package data to be printed in JSON format 115 instead of using the template format. 116 117 The -e flag changes the handling of erroneous packages, those that 118 cannot be found or are malformed. By default, the list command 119 prints an error to standard error for each erroneous package and 120 omits the packages from consideration during the usual printing. 121 With the -e flag, the list command never prints errors to standard 122 error and instead processes the erroneous packages with the usual 123 printing. Erroneous packages will have a non-empty ImportPath and 124 a non-nil Error field; other information may or may not be missing 125 (zeroed). 126 127 For more about build flags, see 'go help build'. 128 129 For more about specifying packages, see 'go help packages'. 130 `, 131 } 132 133 func init() { 134 cmdList.Run = runList // break init cycle 135 addBuildFlags(cmdList) 136 } 137 138 var listE = cmdList.Flag.Bool("e", false, "") 139 var listFmt = cmdList.Flag.String("f", "{{.ImportPath}}", "") 140 var listJson = cmdList.Flag.Bool("json", false, "") 141 var nl = []byte{'\n'} 142 143 func runList(cmd *Command, args []string) { 144 buildModeInit() 145 out := newTrackingWriter(os.Stdout) 146 defer out.w.Flush() 147 148 var do func(*Package) 149 if *listJson { 150 do = func(p *Package) { 151 b, err := json.MarshalIndent(p, "", "\t") 152 if err != nil { 153 out.Flush() 154 fatalf("%s", err) 155 } 156 out.Write(b) 157 out.Write(nl) 158 } 159 } else { 160 var cachedCtxt *Context 161 context := func() *Context { 162 if cachedCtxt == nil { 163 cachedCtxt = newContext(&buildContext) 164 } 165 return cachedCtxt 166 } 167 fm := template.FuncMap{ 168 "join": strings.Join, 169 "context": context, 170 } 171 tmpl, err := template.New("main").Funcs(fm).Parse(*listFmt) 172 if err != nil { 173 fatalf("%s", err) 174 } 175 do = func(p *Package) { 176 if err := tmpl.Execute(out, p); err != nil { 177 out.Flush() 178 fatalf("%s", err) 179 } 180 if out.NeedNL() { 181 out.Write(nl) 182 } 183 } 184 } 185 186 load := packages 187 if *listE { 188 load = packagesAndErrors 189 } 190 191 for _, pkg := range load(args) { 192 // Show vendor-expanded paths in listing 193 pkg.TestImports = pkg.vendored(pkg.TestImports) 194 pkg.XTestImports = pkg.vendored(pkg.XTestImports) 195 196 do(pkg) 197 } 198 } 199 200 // TrackingWriter tracks the last byte written on every write so 201 // we can avoid printing a newline if one was already written or 202 // if there is no output at all. 203 type TrackingWriter struct { 204 w *bufio.Writer 205 last byte 206 } 207 208 func newTrackingWriter(w io.Writer) *TrackingWriter { 209 return &TrackingWriter{ 210 w: bufio.NewWriter(w), 211 last: '\n', 212 } 213 } 214 215 func (t *TrackingWriter) Write(p []byte) (n int, err error) { 216 n, err = t.w.Write(p) 217 if n > 0 { 218 t.last = p[n-1] 219 } 220 return 221 } 222 223 func (t *TrackingWriter) Flush() { 224 t.w.Flush() 225 } 226 227 func (t *TrackingWriter) NeedNL() bool { 228 return t.last != '\n' 229 }