From 806f49c472355258871cd17b3ce7c11d2f950c8c Mon Sep 17 00:00:00 2001 From: Arsen Musayelyan Date: Thu, 29 Dec 2022 12:25:37 -0800 Subject: [PATCH] Move CLI helper functions into internal/cliutils --- build.go | 11 ++-- cli.go | 91 ---------------------------- info.go | 3 +- install.go | 21 +------ internal/cliutils/prompt.go | 114 ++++++++++++++++++++++++++++++++++++ 5 files changed, 124 insertions(+), 116 deletions(-) delete mode 100644 cli.go create mode 100644 internal/cliutils/prompt.go diff --git a/build.go b/build.go index 363f13b..be07111 100644 --- a/build.go +++ b/build.go @@ -41,6 +41,7 @@ import ( "go.arsenm.dev/logger/log" "go.arsenm.dev/lure/distro" "go.arsenm.dev/lure/download" + "go.arsenm.dev/lure/internal/cliutils" "go.arsenm.dev/lure/internal/config" "go.arsenm.dev/lure/internal/cpu" "go.arsenm.dev/lure/internal/repos" @@ -186,13 +187,13 @@ func buildPackage(ctx context.Context, script string, mgr manager.Manager) ([]st return nil, nil, err } - err = promptViewScript(script, vars.Name) + err = cliutils.PromptViewScript(script, vars.Name, cfg.PagerStyle) if err != nil { log.Fatal("Failed to prompt user to view build script").Err(err).Send() } if !archMatches(vars.Architectures) { - buildAnyway, err := yesNoPrompt("Your system's CPU architecture doesn't match this package. Do you want to build anyway?", true) + buildAnyway, err := cliutils.YesNoPrompt("Your system's CPU architecture doesn't match this package. Do you want to build anyway?", true) if err != nil { return nil, nil, err } @@ -267,7 +268,7 @@ func buildPackage(ctx context.Context, script string, mgr manager.Manager) ([]st } log.Info("Installing build dependencies").Send() - installPkgs(ctx, flattenFoundPkgs(found, "install"), notFound, mgr) + installPkgs(ctx, cliutils.FlattenPkgs(found, "install"), notFound, mgr) } var builtDeps, builtNames, repoDeps []string @@ -279,7 +280,7 @@ func buildPackage(ctx context.Context, script string, mgr manager.Manager) ([]st return nil, nil, err } - scripts := getScriptPaths(flattenFoundPkgs(found, "install")) + scripts := getScriptPaths(cliutils.FlattenPkgs(found, "install")) for _, script := range scripts { pkgPaths, pkgNames, err := buildPackage(ctx, script, mgr) if err != nil { @@ -490,7 +491,7 @@ func buildPackage(ctx context.Context, script string, mgr manager.Manager) ([]st } if len(buildDeps) > 0 { - removeBuildDeps, err := yesNoPrompt("Would you like to remove build dependencies?", false) + removeBuildDeps, err := cliutils.YesNoPrompt("Would you like to remove build dependencies?", false) if err != nil { return nil, nil, err } diff --git a/cli.go b/cli.go deleted file mode 100644 index fb91c5d..0000000 --- a/cli.go +++ /dev/null @@ -1,91 +0,0 @@ -package main - -import ( - "os" - - "github.com/AlecAivazis/survey/v2" - "go.arsenm.dev/logger/log" - "go.arsenm.dev/lure/internal/db" - "go.arsenm.dev/lure/internal/pager" -) - -// pkgPrompt asks the user to choose between multiple packages. -// The user may choose multiple packages. -func pkgPrompt(options []db.Package, verb string) ([]db.Package, error) { - names := make([]string, len(options)) - for i, option := range options { - names[i] = option.Repository + "/" + option.Name + " " + option.Version - } - - prompt := &survey.MultiSelect{ - Options: names, - Message: "Choose which package(s) to " + verb, - } - - var choices []int - err := survey.AskOne(prompt, &choices) - if err != nil { - return nil, err - } - - out := make([]db.Package, len(choices)) - for i, choiceIndex := range choices { - out[i] = options[choiceIndex] - } - - return out, nil -} - -// yesNoPrompt asks the user a yes or no question, using def as the default answer -func yesNoPrompt(msg string, def bool) (bool, error) { - var answer bool - err := survey.AskOne( - &survey.Confirm{ - Message: msg, - Default: def, - }, - &answer, - ) - return answer, err -} - -func promptViewScript(script string, name string) error { - view, err := yesNoPrompt("Would you like to view the build script for "+name, false) - if err != nil { - return err - } - - if view { - err = showScript(script, name) - if err != nil { - return err - } - - cont, err := yesNoPrompt("Would you still like to continue?", false) - if err != nil { - return err - } - - if !cont { - log.Fatal("User chose not to continue after reading script").Send() - } - } - - return nil -} - -func showScript(path, name string) error { - scriptFl, err := os.Open(path) - if err != nil { - return err - } - defer scriptFl.Close() - - str, err := pager.SyntaxHighlightBash(scriptFl, cfg.PagerStyle) - if err != nil { - return err - } - - pgr := pager.New(name, str) - return pgr.Run() -} diff --git a/info.go b/info.go index 25cb18a..c1e0ea6 100644 --- a/info.go +++ b/info.go @@ -26,6 +26,7 @@ import ( "github.com/urfave/cli/v2" "go.arsenm.dev/lure/distro" + "go.arsenm.dev/lure/internal/cliutils" "go.arsenm.dev/lure/internal/overrides" "go.arsenm.dev/lure/internal/repos" "gopkg.in/yaml.v3" @@ -51,7 +52,7 @@ func infoCmd(c *cli.Context) error { os.Exit(1) } - pkgs := flattenFoundPkgs(found, "show") + pkgs := cliutils.FlattenPkgs(found, "show") var names []string all := c.Bool("all") diff --git a/install.go b/install.go index 176c608..21df007 100644 --- a/install.go +++ b/install.go @@ -25,6 +25,7 @@ import ( "go.arsenm.dev/logger/log" "github.com/urfave/cli/v2" + "go.arsenm.dev/lure/internal/cliutils" "go.arsenm.dev/lure/internal/config" "go.arsenm.dev/lure/internal/db" "go.arsenm.dev/lure/internal/repos" @@ -52,7 +53,7 @@ func installCmd(c *cli.Context) error { log.Fatal("Error finding packages").Err(err).Send() } - installPkgs(c.Context, flattenFoundPkgs(found, "install"), notFound, mgr) + installPkgs(c.Context, cliutils.FlattenPkgs(found, "install"), notFound, mgr) return nil } @@ -80,24 +81,6 @@ func getScriptPaths(pkgs []db.Package) []string { return scripts } -// flattenFoundPkgs attempts to flatten the map of slices of packages into a single slice -// of packages by prompting the users if multiple packages match. -func flattenFoundPkgs(found map[string][]db.Package, verb string) []db.Package { - var outPkgs []db.Package - for _, pkgs := range found { - if len(pkgs) > 1 { - choices, err := pkgPrompt(pkgs, verb) - if err != nil { - log.Fatal("Error prompting for choice of package").Send() - } - outPkgs = append(outPkgs, choices...) - } else if len(pkgs) == 1 { - outPkgs = append(outPkgs, pkgs[0]) - } - } - return outPkgs -} - // installScripts builds and installs LURE build scripts func installScripts(ctx context.Context, mgr manager.Manager, scripts []string) { for _, script := range scripts { diff --git a/internal/cliutils/prompt.go b/internal/cliutils/prompt.go new file mode 100644 index 0000000..cf58746 --- /dev/null +++ b/internal/cliutils/prompt.go @@ -0,0 +1,114 @@ +package cliutils + +import ( + "os" + + "github.com/AlecAivazis/survey/v2" + "go.arsenm.dev/logger/log" + "go.arsenm.dev/lure/internal/db" + "go.arsenm.dev/lure/internal/pager" +) + +// YesNoPrompt asks the user a yes or no question, using def as the default answer +func YesNoPrompt(msg string, def bool) (bool, error) { + var answer bool + err := survey.AskOne( + &survey.Confirm{ + Message: msg, + Default: def, + }, + &answer, + ) + return answer, err +} + +// PromptViewScript asks the user if they'd like to see a script, +// shows it if they answer yes, then asks if they'd still like to +// continue, and exits if they answer no. +func PromptViewScript(script, name, style string) error { + view, err := YesNoPrompt("Would you like to view the build script for "+name, false) + if err != nil { + return err + } + + if view { + err = ShowScript(script, name, style) + if err != nil { + return err + } + + cont, err := YesNoPrompt("Would you still like to continue?", false) + if err != nil { + return err + } + + if !cont { + log.Fatal("User chose not to continue after reading script").Send() + } + } + + return nil +} + +// ShowScript uses the built-in pager to display a script at a +// given path, in the given syntax highlighting style. +func ShowScript(path, name, style string) error { + scriptFl, err := os.Open(path) + if err != nil { + return err + } + defer scriptFl.Close() + + str, err := pager.SyntaxHighlightBash(scriptFl, style) + if err != nil { + return err + } + + pgr := pager.New(name, str) + return pgr.Run() +} + +// FlattenPkgs attempts to flatten the a map of slices of packages into a single slice +// of packages by prompting the user if multiple packages match. +func FlattenPkgs(found map[string][]db.Package, verb string) []db.Package { + var outPkgs []db.Package + for _, pkgs := range found { + if len(pkgs) > 1 { + choices, err := PkgPrompt(pkgs, verb) + if err != nil { + log.Fatal("Error prompting for choice of package").Send() + } + outPkgs = append(outPkgs, choices...) + } else if len(pkgs) == 1 { + outPkgs = append(outPkgs, pkgs[0]) + } + } + return outPkgs +} + +// PkgPrompt asks the user to choose between multiple packages. +// The user may choose multiple packages. +func PkgPrompt(options []db.Package, verb string) ([]db.Package, error) { + names := make([]string, len(options)) + for i, option := range options { + names[i] = option.Repository + "/" + option.Name + " " + option.Version + } + + prompt := &survey.MultiSelect{ + Options: names, + Message: "Choose which package(s) to " + verb, + } + + var choices []int + err := survey.AskOne(prompt, &choices) + if err != nil { + return nil, err + } + + out := make([]db.Package, len(choices)) + for i, choiceIndex := range choices { + out[i] = options[choiceIndex] + } + + return out, nil +}