github.com/kekek/gb@v0.4.5-0.20170222120241-d4ba64b0b297/cmd/gb/list.go (about)

     1  package main
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"flag"
     7  	"fmt"
     8  	"io"
     9  	"log"
    10  	"os"
    11  	"strings"
    12  	"text/template"
    13  
    14  	"github.com/constabulary/gb"
    15  	"github.com/constabulary/gb/cmd"
    16  	"github.com/pkg/errors"
    17  )
    18  
    19  var (
    20  	format      string
    21  	formatStdin bool
    22  	jsonOutput  bool
    23  )
    24  
    25  func init() {
    26  	registerCommand(&cmd.Command{
    27  		Name:      "list",
    28  		UsageLine: `list [-s] [-f format] [-json] [packages]`,
    29  		Short:     "list the packages named by the importpaths",
    30  		Long: `
    31  List lists packages imported by the project.
    32  
    33  The default output shows the package import paths:
    34  
    35  	% gb list github.com/constabulary/...
    36  	github.com/constabulary/gb
    37  	github.com/constabulary/gb/cmd
    38  	github.com/constabulary/gb/cmd/gb
    39  	github.com/constabulary/gb/cmd/gb-env
    40  	github.com/constabulary/gb/cmd/gb-list
    41  
    42  Flags:
    43  	-f
    44  		alternate format for the list, using the syntax of package template.
    45  		The default output is equivalent to -f '{{.ImportPath}}'. The struct
    46  		being passed to the template is currently an instance of gb.Package.
    47  		This structure is under active development and it's contents are not
    48  		guaranteed to be stable.
    49  	-s
    50  		read format template from STDIN.
    51  	-json
    52  		prints output in structured JSON format. WARNING: gb.Package
    53  		structure is not stable and will change in the future!
    54  `,
    55  		Run: list,
    56  		AddFlags: func(fs *flag.FlagSet) {
    57  			fs.StringVar(&format, "f", "{{.ImportPath}}", "format template")
    58  			fs.BoolVar(&formatStdin, "s", false, "read format from stdin")
    59  			fs.BoolVar(&jsonOutput, "json", false, "outputs json. WARNING: gb.Package structure is not stable and will change in future")
    60  		},
    61  	})
    62  }
    63  
    64  func list(ctx *gb.Context, args []string) error {
    65  	if formatStdin {
    66  		var formatBuffer bytes.Buffer
    67  		io.Copy(&formatBuffer, os.Stdin)
    68  		format = formatBuffer.String()
    69  	}
    70  	pkgs, err := resolveRootPackages(ctx, args...)
    71  	if err != nil {
    72  		log.Fatalf("unable to resolve: %v", err)
    73  	}
    74  
    75  	if jsonOutput {
    76  		views := make([]*PackageView, 0, len(pkgs))
    77  		for _, pkg := range pkgs {
    78  			views = append(views, NewPackageView(pkg))
    79  		}
    80  		encoder := json.NewEncoder(os.Stdout)
    81  		if err := encoder.Encode(views); err != nil {
    82  			return errors.Wrap(err, "json encoding failed")
    83  		}
    84  	} else {
    85  		fm := template.FuncMap{
    86  			"join": strings.Join,
    87  		}
    88  		tmpl, err := template.New("list").Funcs(fm).Parse(format)
    89  		if err != nil {
    90  			return errors.Wrapf(err, "unable to parse template %q", format)
    91  		}
    92  
    93  		for _, pkg := range pkgs {
    94  			if err := tmpl.Execute(os.Stdout, pkg); err != nil {
    95  				return errors.Wrap(err, "unable to execute template")
    96  			}
    97  			fmt.Fprintln(os.Stdout)
    98  		}
    99  	}
   100  	return nil
   101  }
   102  
   103  // PackageView represents a package shown by list command in JSON format.
   104  // It is not stable and may be subject to change.
   105  type PackageView struct {
   106  	Dir         string
   107  	ImportPath  string
   108  	Name        string
   109  	Root        string
   110  	GoFiles     []string
   111  	Imports     []string
   112  	TestGoFiles []string
   113  	TestImports []string
   114  }
   115  
   116  // NewPackageView creates a *PackageView from gb Package.
   117  func NewPackageView(pkg *gb.Package) *PackageView {
   118  	return &PackageView{
   119  		Dir:         pkg.Dir,
   120  		ImportPath:  pkg.ImportPath,
   121  		Name:        pkg.Name,
   122  		Root:        pkg.Root,
   123  		GoFiles:     pkg.GoFiles,
   124  		Imports:     pkg.Package.Imports,
   125  		TestGoFiles: pkg.TestGoFiles,
   126  		TestImports: pkg.TestImports,
   127  	}
   128  }