github.com/please-build/puku@v1.7.3-0.20240516143641-f7d7f4941f57/cmd/puku/puku.go (about)

     1  package main
     2  
     3  import (
     4  	"os"
     5  	"path/filepath"
     6  
     7  	"github.com/peterebden/go-cli-init/v5/flags"
     8  	clilogging "github.com/peterebden/go-cli-init/v5/logging"
     9  
    10  	"github.com/please-build/puku/config"
    11  	"github.com/please-build/puku/generate"
    12  	"github.com/please-build/puku/graph"
    13  	"github.com/please-build/puku/licences"
    14  	"github.com/please-build/puku/logging"
    15  	"github.com/please-build/puku/migrate"
    16  	"github.com/please-build/puku/please"
    17  	"github.com/please-build/puku/proxy"
    18  	"github.com/please-build/puku/sync"
    19  	"github.com/please-build/puku/watch"
    20  	"github.com/please-build/puku/work"
    21  )
    22  
    23  var opts = struct {
    24  	Usage     string
    25  	Verbosity clilogging.Verbosity `short:"v" long:"verbosity" description:"Verbosity of output (error, warning, notice, info, debug)" default:"info"`
    26  
    27  	Fmt struct {
    28  		Args struct {
    29  			Paths []string `positional-arg-name:"packages" description:"The packages to process"`
    30  		} `positional-args:"true"`
    31  	} `command:"fmt" description:"Format build files in the provided paths"`
    32  	Sync struct {
    33  		Format string `short:"f" long:"format" choice:"json" choice:"text" default:"text" description:"output format when outputting to stdout"` //nolint
    34  		Write  bool   `short:"w" long:"write" description:"Whether to write the files back or just print them to stdout"`
    35  	} `command:"sync" description:"Synchronises the go.mod to the third party build file"`
    36  	Lint struct {
    37  		Format string `short:"f" long:"format" choice:"json" choice:"text" default:"text" description:"output format when outputting to stdout"` //nolint
    38  		Args   struct {
    39  			Paths []string `positional-arg-name:"packages" description:"The packages to process"`
    40  		} `positional-args:"true"`
    41  	} `command:"lint" description:"Lint build files in the provided paths"`
    42  	Watch struct {
    43  		Args struct {
    44  			Paths []string `positional-arg-name:"packages" description:"The packages to process"`
    45  		} `positional-args:"true"`
    46  	} `command:"watch" description:"Watch build files in the provided paths and update them when needed"`
    47  	Migrate struct {
    48  		Write          bool     `short:"w" long:"write" description:"Whether to write the files back or just print them to stdout"`
    49  		Format         string   `short:"f" long:"format" choice:"json" choice:"text" default:"text" description:"output format when outputting to stdout"` //nolint
    50  		ThirdPartyDirs []string `long:"third_party_dir" description:"Directories to find go_module rules to migrate"`
    51  		UpdateGoMod    bool     `short:"g" long:"update_go_mod" description:"Update the go mod with the module(s) being migrated"`
    52  		Args           struct {
    53  			Modules []string `positional-arg-name:"modules" description:"The modules to migrate to go_repo"`
    54  		} `positional-args:"true"`
    55  	} `command:"migrate" description:"Migrates from go_module to go_repo"`
    56  	Licenses struct {
    57  		Update struct {
    58  			Format string `short:"f" long:"format" choice:"json" choice:"text" default:"text" description:"output format when outputting to stdout"` //nolint
    59  			Write  bool   `short:"w" long:"write" description:"Whether to write the files back or just print them to stdout"`
    60  			Args   struct {
    61  				Paths []string `positional-arg-name:"packages" description:"The packages to process"`
    62  			} `positional-args:"true"`
    63  		} `command:"update" description:"Updates licences in the given paths"`
    64  	} `command:"licences" description:"Commands relating to licences"`
    65  }{
    66  	Usage: `
    67  puku is a tool used to generate and update Go targets in build files
    68  `,
    69  }
    70  
    71  var log = logging.GetLogger()
    72  
    73  var funcs = map[string]func(conf *config.Config, plzConf *please.Config, orignalWD string) int{
    74  	"fmt": func(_ *config.Config, plzConf *please.Config, orignalWD string) int {
    75  		paths := work.MustExpandPaths(orignalWD, opts.Fmt.Args.Paths)
    76  		if err := generate.Update(plzConf, paths...); err != nil {
    77  			log.Fatalf("%v", err)
    78  		}
    79  		return 0
    80  	},
    81  	"sync": func(_ *config.Config, plzConf *please.Config, _ string) int {
    82  		g := graph.New(plzConf.BuildFileNames())
    83  		if opts.Sync.Write {
    84  			if err := sync.Sync(plzConf, g); err != nil {
    85  				log.Fatalf("%v", err)
    86  			}
    87  		} else {
    88  			if err := sync.SyncToStdout(opts.Sync.Format, plzConf, g); err != nil {
    89  				log.Fatalf("%v", err)
    90  			}
    91  		}
    92  		return 0
    93  	},
    94  	"lint": func(_ *config.Config, plzConf *please.Config, orignalWD string) int {
    95  
    96  		paths := work.MustExpandPaths(orignalWD, opts.Lint.Args.Paths)
    97  		if err := generate.UpdateToStdout(opts.Lint.Format, plzConf, paths...); err != nil {
    98  			log.Fatalf("%v", err)
    99  		}
   100  		return 0
   101  	},
   102  	"watch": func(_ *config.Config, plzConf *please.Config, orignalWD string) int {
   103  		paths := work.MustExpandPaths(orignalWD, opts.Watch.Args.Paths)
   104  		if err := generate.Update(plzConf, paths...); err != nil {
   105  			log.Fatalf("%v", err)
   106  		}
   107  
   108  		if err := watch.Watch(plzConf, paths...); err != nil {
   109  			log.Fatalf("%v", err)
   110  		}
   111  		return 0
   112  	},
   113  	"migrate": func(conf *config.Config, plzConf *please.Config, orignalWD string) int {
   114  		paths := opts.Migrate.ThirdPartyDirs
   115  		if len(paths) == 0 {
   116  			paths = []string{conf.GetThirdPartyDir()}
   117  		}
   118  		paths = work.MustExpandPaths(orignalWD, paths)
   119  		if opts.Migrate.Write {
   120  			if err := migrate.Migrate(conf, plzConf, opts.Migrate.UpdateGoMod, opts.Migrate.Args.Modules, paths); err != nil {
   121  				log.Fatalf("%v", err)
   122  			}
   123  		} else {
   124  			if err := migrate.MigrateToStdout(opts.Migrate.Format, conf, plzConf, opts.Migrate.UpdateGoMod, opts.Migrate.Args.Modules, paths); err != nil {
   125  				log.Fatalf("%v", err)
   126  			}
   127  		}
   128  		return 0
   129  	},
   130  	"update": func(_ *config.Config, plzConf *please.Config, orignalWD string) int {
   131  		paths := work.MustExpandPaths(orignalWD, opts.Licenses.Update.Args.Paths)
   132  		l := licences.New(proxy.New(proxy.DefaultURL), graph.New(plzConf.BuildFileNames()))
   133  		if opts.Licenses.Update.Write {
   134  			if err := l.Update(paths); err != nil {
   135  				log.Fatalf("%v", err)
   136  			}
   137  		} else {
   138  			if err := l.UpdateToStdout(opts.Licenses.Update.Format, paths); err != nil {
   139  				log.Fatalf("%v", err)
   140  			}
   141  		}
   142  		return 0
   143  	},
   144  }
   145  
   146  func main() {
   147  	cmd := flags.ParseFlagsOrDie("puku", &opts, nil)
   148  	logging.InitLogging(opts.Verbosity)
   149  
   150  	wd, err := os.Getwd()
   151  	if err != nil {
   152  		log.Fatalf("failed to get wd: %v", err)
   153  	}
   154  
   155  	root, err := work.FindRoot()
   156  	if err != nil {
   157  		log.Fatalf("%v", err)
   158  	}
   159  
   160  	wd, err = filepath.Rel(root, wd)
   161  	if err != nil {
   162  		log.Fatalf("failed to get wd: %v", err)
   163  	}
   164  
   165  	if err := os.Chdir(root); err != nil {
   166  		log.Fatalf("failed to set working dir to repo root: %v", err)
   167  	}
   168  
   169  	conf, err := config.ReadConfig(".")
   170  	if err != nil {
   171  		log.Fatalf("failed to read config: %v", err)
   172  	}
   173  
   174  	plzConf, err := please.QueryConfig(conf.GetPlzPath())
   175  	if err != nil {
   176  		log.Fatalf("failed to query config: %w", err)
   177  	}
   178  	os.Exit(funcs[cmd](conf, plzConf, wd))
   179  }