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