package cmd import ( "context" "errors" "fmt" "net/url" "os" "path/filepath" "strings" "go.jolheiser.com/vanity/cmd/flags" "go.jolheiser.com/vanity/contrib" "go.jolheiser.com/vanity/database" "go.jolheiser.com/vanity/go-vanity" "go.jolheiser.com/vanity/router" "github.com/AlecAivazis/survey/v2" "github.com/urfave/cli/v2" "go.jolheiser.com/beaver/color" ) var yellow = color.FgYellow func New() *cli.App { app := cli.NewApp() app.Name = "vanity" app.Usage = "Vanity Import URLs" app.Version = router.Version app.Commands = []*cli.Command{ &Add, &Remove, &Server, &Update, } app.Flags = []cli.Flag{ &cli.StringFlag{ Name: "server", Aliases: []string{"s"}, Usage: "vanity server to use", Value: vanity.DefaultServer, EnvVars: []string{"VANITY_SERVER"}, Destination: &flags.Server, }, &cli.StringFlag{ Name: "token", Aliases: []string{"t"}, Usage: "vanity auth token to use", DefaultText: "${VANITY_TOKEN}", EnvVars: []string{"VANITY_TOKEN"}, Destination: &flags.Token, }, &cli.StringFlag{ Name: "database", Aliases: []string{"d"}, Usage: "path to vanity database for server", Value: dbPath(), DefaultText: "`${HOME}/vanity.db` or `${BINPATH}/vanity.db`", EnvVars: []string{"VANITY_DATABASE"}, Destination: &flags.Database, }, &cli.BoolFlag{ Name: "systemd-service", Usage: "Output example systemd service", Destination: &flags.SystemdService, Hidden: true, }, } app.Action = action return app } func action(ctx *cli.Context) error { if flags.SystemdService { fmt.Println(contrib.SystemdService) return nil } return cli.ShowAppHelp(ctx) } func dbPath() string { fn := "vanity.db" home, err := os.UserHomeDir() if err != nil { bin, err := os.Executable() if err != nil { return fn } return filepath.Join(filepath.Dir(bin), fn) } return filepath.Join(home, fn) } func localOrToken(_ *cli.Context) error { if flags.Local && flags.Token == "" { return errors.New("server interaction requires --token") } return nil } func listPackages() ([]vanity.Package, error) { var pkgs []vanity.Package if flags.Local { db, err := database.Load(flags.Database) if err != nil { return pkgs, err } pkgs, err = db.Packages() if err != nil { return pkgs, err } } else { client := vanity.New(flags.Token, vanity.WithServer(flags.Server)) info, err := client.Info(context.Background()) if err != nil { return pkgs, err } pkgs = info.Packages } return pkgs, nil } func pkgPrompt(def vanity.Package) (vanity.Package, error) { if def.Branch == "" { def.Branch = "main" } var pkg vanity.Package questions := []*survey.Question{ { Name: "name", Prompt: &survey.Input{Message: "Name", Default: def.Name}, Validate: survey.Required, }, { Name: "description", Prompt: &survey.Multiline{Message: "Description", Default: def.Description}, Validate: survey.Required, }, { Name: "branch", Prompt: &survey.Input{Message: "Branch", Default: def.Branch}, Validate: survey.Required, }, { Name: "weburl", Prompt: &survey.Input{Message: "Web URL", Default: def.WebURL}, Validate: validURL, }, } if err := survey.Ask(questions, &pkg); err != nil { return pkg, err } defHTTP, defSSH := def.CloneHTTP, def.CloneSSH if def.WebURL != pkg.WebURL { u, err := url.Parse(pkg.WebURL) if err != nil { return pkg, err } defHTTP = pkg.WebURL + ".git" defSSH = fmt.Sprintf("git@%s:%s.git", u.Host, strings.TrimPrefix(u.Path, "/")) } questions = []*survey.Question{ { Name: "clonehttp", Prompt: &survey.Input{Message: "HTTP(S) CLone URL", Default: defHTTP}, Validate: validURL, }, { Name: "clonessh", Prompt: &survey.Input{Message: "SSH CLone URL", Default: defSSH}, Validate: survey.Required, }, } if err := survey.Ask(questions, &pkg); err != nil { return pkg, err } return pkg, nil }