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