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  }