github.com/fenixara/go@v0.0.0-20170127160404-96ea0918e670/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          TestGoFiles    []string // _test.go files in package
    63          XTestGoFiles   []string // _test.go files outside package
    64  
    65          // Cgo directives
    66          CgoCFLAGS    []string // cgo: flags for C compiler
    67          CgoCPPFLAGS  []string // cgo: flags for C preprocessor
    68          CgoCXXFLAGS  []string // cgo: flags for C++ compiler
    69          CgoFFLAGS    []string // cgo: flags for Fortran compiler
    70          CgoLDFLAGS   []string // cgo: flags for linker
    71          CgoPkgConfig []string // cgo: pkg-config names
    72  
    73          // Dependency information
    74          Imports      []string // import paths used by this package
    75          Deps         []string // all (recursively) imported dependencies
    76          TestImports  []string // imports from TestGoFiles
    77          XTestImports []string // imports from XTestGoFiles
    78  
    79          // Error information
    80          Incomplete bool            // this package or a dependency has an error
    81          Error      *PackageError   // error loading package
    82          DepsErrors []*PackageError // errors loading dependencies
    83      }
    84  
    85  Packages stored in vendor directories report an ImportPath that includes the
    86  path to the vendor directory (for example, "d/vendor/p" instead of "p"),
    87  so that the ImportPath uniquely identifies a given copy of a package.
    88  The Imports, Deps, TestImports, and XTestImports lists also contain these
    89  expanded imports paths. See golang.org/s/go15vendor for more about vendoring.
    90  
    91  The error information, if any, is
    92  
    93      type PackageError struct {
    94          ImportStack   []string // shortest path from package named on command line to this one
    95          Pos           string   // position of error (if present, file:line:col)
    96          Err           string   // the error itself
    97      }
    98  
    99  The template function "join" calls strings.Join.
   100  
   101  The template function "context" returns the build context, defined as:
   102  
   103  	type Context struct {
   104  		GOARCH        string   // target architecture
   105  		GOOS          string   // target operating system
   106  		GOROOT        string   // Go root
   107  		GOPATH        string   // Go path
   108  		CgoEnabled    bool     // whether cgo can be used
   109  		UseAllFiles   bool     // use files regardless of +build lines, file names
   110  		Compiler      string   // compiler to assume when computing target paths
   111  		BuildTags     []string // build constraints to match in +build lines
   112  		ReleaseTags   []string // releases the current release is compatible with
   113  		InstallSuffix string   // suffix to use in the name of the install dir
   114  	}
   115  
   116  For more information about the meaning of these fields see the documentation
   117  for the go/build package's Context type.
   118  
   119  The -json flag causes the package data to be printed in JSON format
   120  instead of using the template format.
   121  
   122  The -e flag changes the handling of erroneous packages, those that
   123  cannot be found or are malformed.  By default, the list command
   124  prints an error to standard error for each erroneous package and
   125  omits the packages from consideration during the usual printing.
   126  With the -e flag, the list command never prints errors to standard
   127  error and instead processes the erroneous packages with the usual
   128  printing.  Erroneous packages will have a non-empty ImportPath and
   129  a non-nil Error field; other information may or may not be missing
   130  (zeroed).
   131  
   132  For more about build flags, see 'go help build'.
   133  
   134  For more about specifying packages, see 'go help packages'.
   135  	`,
   136  }
   137  
   138  func init() {
   139  	cmdList.Run = runList // break init cycle
   140  	addBuildFlags(cmdList)
   141  }
   142  
   143  var listE = cmdList.Flag.Bool("e", false, "")
   144  var listFmt = cmdList.Flag.String("f", "{{.ImportPath}}", "")
   145  var listJson = cmdList.Flag.Bool("json", false, "")
   146  var nl = []byte{'\n'}
   147  
   148  func runList(cmd *Command, args []string) {
   149  	buildModeInit()
   150  	out := newTrackingWriter(os.Stdout)
   151  	defer out.w.Flush()
   152  
   153  	var do func(*Package)
   154  	if *listJson {
   155  		do = func(p *Package) {
   156  			b, err := json.MarshalIndent(p, "", "\t")
   157  			if err != nil {
   158  				out.Flush()
   159  				fatalf("%s", err)
   160  			}
   161  			out.Write(b)
   162  			out.Write(nl)
   163  		}
   164  	} else {
   165  		var cachedCtxt *Context
   166  		context := func() *Context {
   167  			if cachedCtxt == nil {
   168  				cachedCtxt = newContext(&buildContext)
   169  			}
   170  			return cachedCtxt
   171  		}
   172  		fm := template.FuncMap{
   173  			"join":    strings.Join,
   174  			"context": context,
   175  		}
   176  		tmpl, err := template.New("main").Funcs(fm).Parse(*listFmt)
   177  		if err != nil {
   178  			fatalf("%s", err)
   179  		}
   180  		do = func(p *Package) {
   181  			if err := tmpl.Execute(out, p); err != nil {
   182  				out.Flush()
   183  				fatalf("%s", err)
   184  			}
   185  			if out.NeedNL() {
   186  				out.Write(nl)
   187  			}
   188  		}
   189  	}
   190  
   191  	load := packages
   192  	if *listE {
   193  		load = packagesAndErrors
   194  	}
   195  
   196  	for _, pkg := range load(args) {
   197  		// Show vendor-expanded paths in listing
   198  		pkg.TestImports = pkg.vendored(pkg.TestImports)
   199  		pkg.XTestImports = pkg.vendored(pkg.XTestImports)
   200  
   201  		do(pkg)
   202  	}
   203  }
   204  
   205  // TrackingWriter tracks the last byte written on every write so
   206  // we can avoid printing a newline if one was already written or
   207  // if there is no output at all.
   208  type TrackingWriter struct {
   209  	w    *bufio.Writer
   210  	last byte
   211  }
   212  
   213  func newTrackingWriter(w io.Writer) *TrackingWriter {
   214  	return &TrackingWriter{
   215  		w:    bufio.NewWriter(w),
   216  		last: '\n',
   217  	}
   218  }
   219  
   220  func (t *TrackingWriter) Write(p []byte) (n int, err error) {
   221  	n, err = t.w.Write(p)
   222  	if n > 0 {
   223  		t.last = p[n-1]
   224  	}
   225  	return
   226  }
   227  
   228  func (t *TrackingWriter) Flush() {
   229  	t.w.Flush()
   230  }
   231  
   232  func (t *TrackingWriter) NeedNL() bool {
   233  	return t.last != '\n'
   234  }