github.com/spotify/syslog-redirector-golang@v0.0.0-20140320174030-4859f03d829a/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] [-race] [-f format] [-json] [-tags 'tag list'] [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}}'.  One extra template function is available, "join",
    31  which calls strings.Join. 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          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          HFiles   []string       // .h, .hh, .hpp and .hxx source files
    51          SFiles   []string       // .s source files
    52          SwigFiles []string      // .swig files
    53          SwigCXXFiles []string   // .swigcxx files
    54          SysoFiles []string      // .syso object files to add to archive
    55  
    56          // Cgo directives
    57          CgoCFLAGS    []string // cgo: flags for C compiler
    58          CgoCPPFLAGS  []string // cgo: flags for C preprocessor
    59          CgoCXXFLAGS  []string // cgo: flags for C++ compiler
    60          CgoLDFLAGS   []string // cgo: flags for linker
    61          CgoPkgConfig []string // cgo: pkg-config names
    62  
    63          // Dependency information
    64          Imports []string // import paths used by this package
    65          Deps    []string // all (recursively) imported dependencies
    66  
    67          // Error information
    68          Incomplete bool            // this package or a dependency has an error
    69          Error      *PackageError   // error loading package
    70          DepsErrors []*PackageError // errors loading dependencies
    71  
    72          TestGoFiles  []string // _test.go files in package
    73          TestImports  []string // imports from TestGoFiles
    74          XTestGoFiles []string // _test.go files outside package
    75          XTestImports []string // imports from XTestGoFiles
    76      }
    77  
    78  The -json flag causes the package data to be printed in JSON format
    79  instead of using the template format.
    80  
    81  The -e flag changes the handling of erroneous packages, those that
    82  cannot be found or are malformed.  By default, the list command
    83  prints an error to standard error for each erroneous package and
    84  omits the packages from consideration during the usual printing.
    85  With the -e flag, the list command never prints errors to standard
    86  error and instead processes the erroneous packages with the usual
    87  printing.  Erroneous packages will have a non-empty ImportPath and
    88  a non-nil Error field; other information may or may not be missing
    89  (zeroed).
    90  
    91  The -tags flag specifies a list of build tags, like in the 'go build'
    92  command.
    93  
    94  The -race flag causes the package data to include the dependencies
    95  required by the race detector.
    96  
    97  For more about specifying packages, see 'go help packages'.
    98  	`,
    99  }
   100  
   101  func init() {
   102  	cmdList.Run = runList // break init cycle
   103  	cmdList.Flag.Var(buildCompiler{}, "compiler", "")
   104  	cmdList.Flag.Var((*stringsFlag)(&buildContext.BuildTags), "tags", "")
   105  }
   106  
   107  var listE = cmdList.Flag.Bool("e", false, "")
   108  var listFmt = cmdList.Flag.String("f", "{{.ImportPath}}", "")
   109  var listJson = cmdList.Flag.Bool("json", false, "")
   110  var listRace = cmdList.Flag.Bool("race", false, "")
   111  var nl = []byte{'\n'}
   112  
   113  func runList(cmd *Command, args []string) {
   114  	out := newTrackingWriter(os.Stdout)
   115  	defer out.w.Flush()
   116  
   117  	if *listRace {
   118  		buildRace = true
   119  	}
   120  
   121  	var do func(*Package)
   122  	if *listJson {
   123  		do = func(p *Package) {
   124  			b, err := json.MarshalIndent(p, "", "\t")
   125  			if err != nil {
   126  				out.Flush()
   127  				fatalf("%s", err)
   128  			}
   129  			out.Write(b)
   130  			out.Write(nl)
   131  		}
   132  	} else {
   133  		tmpl, err := template.New("main").Funcs(template.FuncMap{"join": strings.Join}).Parse(*listFmt)
   134  		if err != nil {
   135  			fatalf("%s", err)
   136  		}
   137  		do = func(p *Package) {
   138  			if err := tmpl.Execute(out, p); err != nil {
   139  				out.Flush()
   140  				fatalf("%s", err)
   141  			}
   142  			if out.NeedNL() {
   143  				out.Write([]byte{'\n'})
   144  			}
   145  		}
   146  	}
   147  
   148  	load := packages
   149  	if *listE {
   150  		load = packagesAndErrors
   151  	}
   152  
   153  	for _, pkg := range load(args) {
   154  		do(pkg)
   155  	}
   156  }
   157  
   158  // TrackingWriter tracks the last byte written on every write so
   159  // we can avoid printing a newline if one was already written or
   160  // if there is no output at all.
   161  type TrackingWriter struct {
   162  	w    *bufio.Writer
   163  	last byte
   164  }
   165  
   166  func newTrackingWriter(w io.Writer) *TrackingWriter {
   167  	return &TrackingWriter{
   168  		w:    bufio.NewWriter(w),
   169  		last: '\n',
   170  	}
   171  }
   172  
   173  func (t *TrackingWriter) Write(p []byte) (n int, err error) {
   174  	n, err = t.w.Write(p)
   175  	if n > 0 {
   176  		t.last = p[n-1]
   177  	}
   178  	return
   179  }
   180  
   181  func (t *TrackingWriter) Flush() {
   182  	t.w.Flush()
   183  }
   184  
   185  func (t *TrackingWriter) NeedNL() bool {
   186  	return t.last != '\n'
   187  }