vanity/cmd/cmd.go

182 lines
4.0 KiB
Go

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
}