pkg/utils: Move CLI utility functions to cmd
pkg/utils has been in Go Toolbox since its birth. Along the way it accumulated a number of functions where a few of them are purely CLI related. Since the majority of functions in the package are related to some "deeper" functionality in Toolbox, it makes more sense to move the selected few to package cmd. This will make pkg/utils a bit leaner and create a dedicated space for cmd utility functions to live in. In the process the error creation functions no longer require the executableBase argument to be passed to them. https://github.com/containers/toolbox/pull/819
This commit is contained in:
parent
3aeb7cf288
commit
be4d3974ef
12 changed files with 109 additions and 90 deletions
|
@ -143,7 +143,7 @@ func create(cmd *cobra.Command, args []string) error {
|
||||||
var err error
|
var err error
|
||||||
release, err = utils.ParseRelease(createFlags.distro, createFlags.release)
|
release, err = utils.ParseRelease(createFlags.distro, createFlags.release)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err := utils.CreateErrorInvalidRelease(executableBase)
|
err := createErrorInvalidRelease()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -471,7 +471,7 @@ func createHelp(cmd *cobra.Command, args []string) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := utils.ShowManual("toolbox-create"); err != nil {
|
if err := showManual("toolbox-create"); err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "Error: %s\n", err)
|
fmt.Fprintf(os.Stderr, "Error: %s\n", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -696,7 +696,7 @@ func pullImage(image, release string) (bool, error) {
|
||||||
fmt.Println("Image required to create toolbox container.")
|
fmt.Println("Image required to create toolbox container.")
|
||||||
|
|
||||||
prompt := fmt.Sprintf("Download %s (500MB)? [y/N]:", imageFull)
|
prompt := fmt.Sprintf("Download %s (500MB)? [y/N]:", imageFull)
|
||||||
shouldPullImage = utils.AskForConfirmation(prompt)
|
shouldPullImage = askForConfirmation(prompt)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !shouldPullImage {
|
if !shouldPullImage {
|
||||||
|
|
|
@ -111,7 +111,7 @@ func enter(cmd *cobra.Command, args []string) error {
|
||||||
var err error
|
var err error
|
||||||
release, err = utils.ParseRelease(enterFlags.distro, enterFlags.release)
|
release, err = utils.ParseRelease(enterFlags.distro, enterFlags.release)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err := utils.CreateErrorInvalidRelease(executableBase)
|
err := createErrorInvalidRelease()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -178,7 +178,7 @@ func enterHelp(cmd *cobra.Command, args []string) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := utils.ShowManual("toolbox-enter"); err != nil {
|
if err := showManual("toolbox-enter"); err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "Error: %s\n", err)
|
fmt.Fprintf(os.Stderr, "Error: %s\n", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,7 +88,7 @@ func helpShowManual(args []string) error {
|
||||||
manual = "toolbox-" + args[0]
|
manual = "toolbox-" + args[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := utils.ShowManual(manual); err != nil {
|
if err := showManual(manual); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -350,7 +350,7 @@ func initContainerHelp(cmd *cobra.Command, args []string) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := utils.ShowManual("toolbox-init-container"); err != nil {
|
if err := showManual("toolbox-init-container"); err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "Error: %s\n", err)
|
fmt.Fprintf(os.Stderr, "Error: %s\n", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -185,7 +185,7 @@ func listHelp(cmd *cobra.Command, args []string) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := utils.ShowManual("toolbox-list"); err != nil {
|
if err := showManual("toolbox-list"); err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "Error: %s\n", err)
|
fmt.Fprintf(os.Stderr, "Error: %s\n", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,7 +122,7 @@ func rmHelp(cmd *cobra.Command, args []string) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := utils.ShowManual("toolbox-rm"); err != nil {
|
if err := showManual("toolbox-rm"); err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "Error: %s\n", err)
|
fmt.Fprintf(os.Stderr, "Error: %s\n", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,7 +122,7 @@ func rmiHelp(cmd *cobra.Command, args []string) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := utils.ShowManual("toolbox-rmi"); err != nil {
|
if err := showManual("toolbox-rmi"); err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "Error: %s\n", err)
|
fmt.Fprintf(os.Stderr, "Error: %s\n", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -174,7 +174,7 @@ func rootHelp(cmd *cobra.Command, args []string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := utils.ShowManual(manual); err != nil {
|
if err := showManual(manual); err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "Error: %s\n", err)
|
fmt.Fprintf(os.Stderr, "Error: %s\n", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,7 +109,7 @@ func run(cmd *cobra.Command, args []string) error {
|
||||||
var err error
|
var err error
|
||||||
release, err = utils.ParseRelease(runFlags.distro, runFlags.release)
|
release, err = utils.ParseRelease(runFlags.distro, runFlags.release)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err := utils.CreateErrorInvalidRelease(executableBase)
|
err := createErrorInvalidRelease()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -170,13 +170,13 @@ func runCommand(container string,
|
||||||
logrus.Debugf("Container %s not found", container)
|
logrus.Debugf("Container %s not found", container)
|
||||||
|
|
||||||
if pedantic {
|
if pedantic {
|
||||||
err := utils.CreateErrorContainerNotFound(container, executableBase)
|
err := createErrorContainerNotFound(container)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
containers, err := getContainers()
|
containers, err := getContainers()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err := utils.CreateErrorContainerNotFound(container, executableBase)
|
err := createErrorContainerNotFound(container)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,7 +194,7 @@ func runCommand(container string,
|
||||||
|
|
||||||
if promptForCreate {
|
if promptForCreate {
|
||||||
prompt := "No toolbox containers found. Create now? [y/N]"
|
prompt := "No toolbox containers found. Create now? [y/N]"
|
||||||
shouldCreateContainer = utils.AskForConfirmation(prompt)
|
shouldCreateContainer = askForConfirmation(prompt)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !shouldCreateContainer {
|
if !shouldCreateContainer {
|
||||||
|
@ -383,7 +383,7 @@ func runHelp(cmd *cobra.Command, args []string) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := utils.ShowManual("toolbox-run"); err != nil {
|
if err := showManual("toolbox-run"); err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "Error: %s\n", err)
|
fmt.Fprintf(os.Stderr, "Error: %s\n", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
92
src/cmd/utils.go
Normal file
92
src/cmd/utils.go
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"strings"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
// askForConfirmation prints prompt to stdout and waits for response from the
|
||||||
|
// user
|
||||||
|
//
|
||||||
|
// Expected answers are: "yes", "y", "no", "n"
|
||||||
|
//
|
||||||
|
// Answers are internally converted to lower case.
|
||||||
|
//
|
||||||
|
// The default answer is "no" ([y/N])
|
||||||
|
func askForConfirmation(prompt string) bool {
|
||||||
|
var retVal bool
|
||||||
|
|
||||||
|
for {
|
||||||
|
fmt.Printf("%s ", prompt)
|
||||||
|
|
||||||
|
var response string
|
||||||
|
|
||||||
|
fmt.Scanf("%s", &response)
|
||||||
|
if response == "" {
|
||||||
|
response = "n"
|
||||||
|
} else {
|
||||||
|
response = strings.ToLower(response)
|
||||||
|
}
|
||||||
|
|
||||||
|
if response == "no" || response == "n" {
|
||||||
|
break
|
||||||
|
} else if response == "yes" || response == "y" {
|
||||||
|
retVal = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return retVal
|
||||||
|
}
|
||||||
|
|
||||||
|
func createErrorContainerNotFound(container string) error {
|
||||||
|
var builder strings.Builder
|
||||||
|
fmt.Fprintf(&builder, "container %s not found\n", container)
|
||||||
|
fmt.Fprintf(&builder, "Use the 'create' command to create a toolbox.\n")
|
||||||
|
fmt.Fprintf(&builder, "Run '%s --help' for usage.", executableBase)
|
||||||
|
|
||||||
|
errMsg := builder.String()
|
||||||
|
return errors.New(errMsg)
|
||||||
|
}
|
||||||
|
|
||||||
|
func createErrorInvalidRelease() error {
|
||||||
|
var builder strings.Builder
|
||||||
|
fmt.Fprintf(&builder, "invalid argument for '--release'\n")
|
||||||
|
fmt.Fprintf(&builder, "Run '%s --help' for usage.", executableBase)
|
||||||
|
|
||||||
|
errMsg := builder.String()
|
||||||
|
return errors.New(errMsg)
|
||||||
|
}
|
||||||
|
|
||||||
|
// showManual tries to open the specified manual page using man on stdout
|
||||||
|
func showManual(manual string) error {
|
||||||
|
manBinary, err := exec.LookPath("man")
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, exec.ErrNotFound) {
|
||||||
|
return errors.New("man(1) not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors.New("failed to lookup man(1)")
|
||||||
|
}
|
||||||
|
|
||||||
|
manualArgs := []string{"man", manual}
|
||||||
|
env := os.Environ()
|
||||||
|
|
||||||
|
stderrFd := os.Stderr.Fd()
|
||||||
|
stderrFdInt := int(stderrFd)
|
||||||
|
stdoutFd := os.Stdout.Fd()
|
||||||
|
stdoutFdInt := int(stdoutFd)
|
||||||
|
if err := syscall.Dup3(stdoutFdInt, stderrFdInt, 0); err != nil {
|
||||||
|
return errors.New("failed to redirect standard error to standard output")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := syscall.Exec(manBinary, manualArgs, env); err != nil {
|
||||||
|
return errors.New("failed to invoke man(1)")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -12,6 +12,7 @@ sources = files(
|
||||||
'cmd/rmi.go',
|
'cmd/rmi.go',
|
||||||
'cmd/root.go',
|
'cmd/root.go',
|
||||||
'cmd/run.go',
|
'cmd/run.go',
|
||||||
|
'cmd/utils.go',
|
||||||
'pkg/podman/podman.go',
|
'pkg/podman/podman.go',
|
||||||
'pkg/shell/shell.go',
|
'pkg/shell/shell.go',
|
||||||
'pkg/utils/utils.go',
|
'pkg/utils/utils.go',
|
||||||
|
|
|
@ -20,7 +20,6 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
|
||||||
"os/user"
|
"os/user"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
@ -136,32 +135,6 @@ func init() {
|
||||||
ContainerNameDefault = containerNamePrefixDefault + "-" + releaseDefault
|
ContainerNameDefault = containerNamePrefixDefault + "-" + releaseDefault
|
||||||
}
|
}
|
||||||
|
|
||||||
func AskForConfirmation(prompt string) bool {
|
|
||||||
var retVal bool
|
|
||||||
|
|
||||||
for {
|
|
||||||
fmt.Printf("%s ", prompt)
|
|
||||||
|
|
||||||
var response string
|
|
||||||
|
|
||||||
fmt.Scanf("%s", &response)
|
|
||||||
if response == "" {
|
|
||||||
response = "n"
|
|
||||||
} else {
|
|
||||||
response = strings.ToLower(response)
|
|
||||||
}
|
|
||||||
|
|
||||||
if response == "no" || response == "n" {
|
|
||||||
break
|
|
||||||
} else if response == "yes" || response == "y" {
|
|
||||||
retVal = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return retVal
|
|
||||||
}
|
|
||||||
|
|
||||||
func CallFlatpakSessionHelper() (string, error) {
|
func CallFlatpakSessionHelper() (string, error) {
|
||||||
logrus.Debug("Calling org.freedesktop.Flatpak.SessionHelper.RequestSession")
|
logrus.Debug("Calling org.freedesktop.Flatpak.SessionHelper.RequestSession")
|
||||||
|
|
||||||
|
@ -191,25 +164,6 @@ func CallFlatpakSessionHelper() (string, error) {
|
||||||
return path, nil
|
return path, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateErrorContainerNotFound(container, executableBase string) error {
|
|
||||||
var builder strings.Builder
|
|
||||||
fmt.Fprintf(&builder, "container %s not found\n", container)
|
|
||||||
fmt.Fprintf(&builder, "Use the 'create' command to create a toolbox.\n")
|
|
||||||
fmt.Fprintf(&builder, "Run '%s --help' for usage.", executableBase)
|
|
||||||
|
|
||||||
errMsg := builder.String()
|
|
||||||
return errors.New(errMsg)
|
|
||||||
}
|
|
||||||
|
|
||||||
func CreateErrorInvalidRelease(executableBase string) error {
|
|
||||||
var builder strings.Builder
|
|
||||||
fmt.Fprintf(&builder, "invalid argument for '--release'\n")
|
|
||||||
fmt.Fprintf(&builder, "Run '%s --help' for usage.", executableBase)
|
|
||||||
|
|
||||||
errMsg := builder.String()
|
|
||||||
return errors.New(errMsg)
|
|
||||||
}
|
|
||||||
|
|
||||||
func EnsureXdgRuntimeDirIsSet(uid int) {
|
func EnsureXdgRuntimeDirIsSet(uid int) {
|
||||||
if _, ok := os.LookupEnv("XDG_RUNTIME_DIR"); !ok {
|
if _, ok := os.LookupEnv("XDG_RUNTIME_DIR"); !ok {
|
||||||
logrus.Debug("XDG_RUNTIME_DIR is unset")
|
logrus.Debug("XDG_RUNTIME_DIR is unset")
|
||||||
|
@ -819,31 +773,3 @@ func ResolveImageName(distroCLI, imageCLI, releaseCLI string) (string, string, e
|
||||||
|
|
||||||
return image, release, nil
|
return image, release, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ShowManual(manual string) error {
|
|
||||||
manBinary, err := exec.LookPath("man")
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, exec.ErrNotFound) {
|
|
||||||
return errors.New("man(1) not found")
|
|
||||||
}
|
|
||||||
|
|
||||||
return errors.New("failed to lookup man(1)")
|
|
||||||
}
|
|
||||||
|
|
||||||
manualArgs := []string{"man", manual}
|
|
||||||
env := os.Environ()
|
|
||||||
|
|
||||||
stderrFd := os.Stderr.Fd()
|
|
||||||
stderrFdInt := int(stderrFd)
|
|
||||||
stdoutFd := os.Stdout.Fd()
|
|
||||||
stdoutFdInt := int(stdoutFd)
|
|
||||||
if err := syscall.Dup3(stdoutFdInt, stderrFdInt, 0); err != nil {
|
|
||||||
return errors.New("failed to redirect standard error to standard output")
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := syscall.Exec(manBinary, manualArgs, env); err != nil {
|
|
||||||
return errors.New("failed to invoke man(1)")
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue