package lectable import ( "context" "flag" "fmt" "io" "log" "golang.org/x/xerrors" ) const cmdName = "lectable" var ( subCommands = []cmd{ &cmdDownload{}, &cmdPDF{}, } dispatch = make(map[string]cmd, len(subCommands)) maxSubcommandName int ) func init() { for _, r := range subCommands { n := r.name() l := len(n) if l > maxSubcommandName { maxSubcommandName = l } dispatch[n] = r } } // Run the lectable func Run(ctx context.Context, argv []string, outStream, errStream io.Writer) error { log.SetOutput(errStream) nameAndVer := fmt.Sprintf("%s (v%s rev:%s)", cmdName, version, revision) fs := flag.NewFlagSet(nameAndVer, flag.ContinueOnError) fs.SetOutput(errStream) fs.Usage = func() { fmt.Fprintf(fs.Output(), "Usage of %s:\n", nameAndVer) fs.PrintDefaults() fmt.Fprintf(fs.Output(), "\nCommands:\n") formatCommands(fs.Output()) } ver := fs.Bool("version", false, "display version") if err := fs.Parse(argv); err != nil { return err } if *ver { return printVersion(outStream) } argv = fs.Args() if len(argv) < 1 { fs.Usage() return xerrors.New("no subcommand specified") } rnr, ok := dispatch[argv[0]] if !ok { return xerrors.Errorf("unknown subcommand: %s", argv[0]) } return rnr.run(context.Background(), argv[1:], outStream, errStream) } func printVersion(out io.Writer) error { _, err := fmt.Fprintf(out, "%s v%s (rev:%s)\n", cmdName, version, revision) return err } func formatCommands(out io.Writer) { format := fmt.Sprintf(" %%-%ds %%s\n", maxSubcommandName) for _, r := range subCommands { fmt.Fprintf(out, format, r.name(), r.description()) } }