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 }