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