ask

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 28, 2021 License: Apache-2.0 Imports: 7 Imported by: 0

README

Ask

Ask is a library to create interactive prompts in the terminal using Go. Create prompts, forms and dialogs in the command line.

func main() {
	b, err := ask.Bool("Are you sure?").Default(true).Ask()

	if err != nil {
		panic(err)
	}

	if !b {
		fmt.Println("No.")
		os.Exit(1)
	}

	fmt.Println("Yes.")
}

Ask animated demo

Features

  • Read input from terminal and return a typed value
  • Restrict valid input to a finite set of choices
  • Auto-complete (for paths and choices) with tab
  • Hide password input

Install

go get gitlab.com/loderunner/ask

Usage

To prompt the user for a value, create one of the typed "Askers" and use Ask.

asker := ask.String("Enter your name:")
name, err := asker.Ask()

or chain the calls for a simpler syntax:

name, err := ask.String("Enter your name:").Ask()

Ask prints out the prompt given as argument, and waits for user input. Input is terminated when the user ends the line by pressing Return. Ask then returns the value entered by the user in the terminal. err is set if there was an error reading from the terminal, or if the user-entered value could not be coerced to the Asker's type (see below).

Formatting prompt

The Asker's prompt can be customized further by using the ask.*f functions. These are just shortcuts to Go's fmt package. I.e.

ask.Stringf("Player #%d input:", playerNumber).Ask()

is a shortcut for

prompt := fmt.Sprintf("Player #%d input:", playerNumber)
ask.Stringf(prompt).Ask()

Here is an example using Intf.

hobbits := []string{"Frodo", "Sam", "Merry", "Pippin"}
for _, name := range hobbits {
	age, err := ask.Intf("How old is %s?", name).Ask()
	if err != nil {
		panic(err)
	}
	fmt.Printf("%d is such a nice age to go adventuring for a hobbit!\n", age)
}
Configuring Askers

Once the asker has been created, it can be configured by calling a number of methods, before finally calling Ask to collect user input. Configuration options can change the prompt behavior, the input validation or the default value (see below).

Configuration methods return the configured Asker, making it easy to chain method calls, to configure and prompt user in a single line of code.

meals := []string{
	"Breakfast",
	"Second Breakfast",
	"Elevenses",
	"Luncheon",
	"Afternoon Tea",
	"Dinner",
	"Supper",
}
favoriteMeal, err := ask.String("Which meal is your favorite?").
	Choices(meals...).
	Default("Second Breakfast").
	Ask()
Default values

Askers can take a default value using Default. Ask will return the default value if no input was given. If your asker has a default value, it will be displayed after the custom prompt.

dwarfCount, _ := ask.Int("How many dwarves should go reclaim Lonely Mountain?").
	Default(13).
	Ask()
if dwarfCount >= 10 {
	fmt.Printf("%d is a lot of dwarves.\n", dwarfCount)
}

Output:

How many dwarves should go reclaim Lonely Mountain? [13]
	<User presses Return without entering a value>
13 is a lot of dwarves
Restricting choices

It can be useful to restrict the possible choices to a prompt, to a finite set of values. Choices allows configuring the Asker to prompt for a set of choices and will return an error if the user enters a value outside of these choices.

what, _ := ask.String("What have the orcs taken to Isengard?").
	Choices("orcs", "hobbits", "elves").
	Ask()
fmt.Printf("They've taken the %s to Isengard!", what)

Output:

What have the orcs taken to Isengard? [orcs/hobbits/elves] hobbits
They've taken the hobbits to Isengard!

⚠ Using Default to set a default value not in the restricted choices will result in undefined behavior.

Password input

Using Password on a StringAsker will the input when the user types their input.

Tab completion
Asker types
String

Using String or Stringf will create a StringAsker. StringAsker.Ask expects any string and returns it.

StringAsker supports Default, Choices and Password.

Int

Using Int or Intf will create an IntAsker. IntAsker.Ask expects the user to enter a text that can be parsed with strconv.Atoi and returns an int.

IntAsker supports Default and Choices.

Float

Using Float or Floatf will create a FloatAsker. FloatAsker.Ask expects the user to enter a text that can be parsed with strconv.ParseFloat and returns a float64.

FloatAsker supports Default and Choices.

Boolean

Using Bool or Boolf will create a BoolAsker. BoolAsker.Ask expects the user to enter either yes or no, or the shorthands y or n. yes or y will return true, no or n will return false.

BoolAsker supports Default.

Path

Using Path or Pathf will create a PathAsker. PathAsker.Ask expects the user to enter any string and returns it. PathAsker behaves just like StringAsker, except for the tab completion which resolves the given path to find possible completions.

PathAsker supports Default.

Errors

Ask will returns error in two cases:

  • failure to read input
  • failure to parse input (or coerce it to restricted choices)

Errors use Go 1.13 error wrapping. Use errors.Unwrap to find the underlying error (if there is one).

License

   Copyright 2017 Pantomath SAS
   Copyright 2021 Charles Francoise

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

Documentation

Overview

Package ask collects information from the user through the command line in a Q&A style.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type BoolAsker

type BoolAsker struct {
	// contains filtered or unexported fields
}

BoolAsker is an object that can ask for a bool on the command line.

func Bool

func Bool(message string) *BoolAsker

Bool returns a BoolAsker that will prompt the user with message when Ask is called.

Example
package main

import (
	"fmt"
	"os"

	"gitlab.com/loderunner/ask"
)

func main() {
	b, err := ask.Bool("Are you sure?").Default(true).Ask()
	if err != nil {
		panic(err)
	}
	if !b {
		fmt.Println("No.")
		os.Exit(1)
	}
	fmt.Println("Yes.")
}
Output:

func Boolf

func Boolf(format string, args ...interface{}) *BoolAsker

Boolf returns a BoolAsker that will prompt the user with a message according to a format specifier. See the fmt package for formatting rules.

func (*BoolAsker) Ask

func (ba *BoolAsker) Ask() (bool, error)

Ask prompts the user by displaying the BoolAsker's message, reads from standard input until it encounters a newline or EOF, converts the input to a bool and returns the bool. If the user enters an empty input and a default bool is set, the default int will be returned. Returns an error if stdin could not be read, if the input is too large for memory, or if the input could not be converted to bool.

Case-insensitive inputs "y" and "yes" convert to true, "n" and "no" convert to false.

func (*BoolAsker) Default

func (ba *BoolAsker) Default(def bool) *BoolAsker

Default sets the default bool for the BoolAsker. The default bool is returned from Ask if the user entered an empty input.

type FloatAsker

type FloatAsker struct {
	// contains filtered or unexported fields
}

FloatAsker is an object that can ask for a float on the command line.

func Float

func Float(message string) *FloatAsker

Float returns an FloatAsker that will prompt the user with message when Ask is called.

func Floatf

func Floatf(format string, args ...interface{}) *FloatAsker

Floatf returns an FloatAsker that will prompt the user with a message according to a format specifier. See the fmt package for formatting rules.

func (*FloatAsker) Ask

func (fa *FloatAsker) Ask() (float64, error)

Ask prompts the user by displaying the FloatAsker's message, reads from standard input until it encounters a newline or EOF, converts the input to a float and returns the float. If the user enters an empty input and a default float is set, the default float will be returned. Returns an error if stdin could not be read, if the input is too large for memory, or if the input could not be converted to memory.

func (*FloatAsker) Choices

func (fa *FloatAsker) Choices(choices ...float64) *FloatAsker

Choices sets an arbitrary number of choices for the user input. The list of choices will be automatically displayed when prompting the user. If the user enters a choice not in the list, Ask will return an error. If the set of available "choices" does not contain the default, behavior is undefined.

func (*FloatAsker) Default

func (fa *FloatAsker) Default(def float64) *FloatAsker

Default sets the default float for the FloatAsker. The default float is returned from Ask if the user entered an empty input.

type IntAsker

type IntAsker struct {
	// contains filtered or unexported fields
}

IntAsker is an object that can ask for an int on the command line.

func Int

func Int(message string) *IntAsker

Int returns an IntAsker that will prompt the user with message when Ask is called.

func Intf

func Intf(format string, args ...interface{}) *IntAsker

Intf returns an IntAsker that will prompt the user with a message according to a format specifier. See the fmt package for formatting rules.

func (*IntAsker) Ask

func (ia *IntAsker) Ask() (int, error)

Ask prompts the user by displaying the IntAsker's message, reads from standard input until it encounters a newline or EOF, converts the input to an int and returns the int. If the user enters an empty input and a default int is set, the default int will be returned. Returns an error if stdin could not be read, if the input is too large for memory, or if the input could not be converted to memory.

func (*IntAsker) Choices

func (ia *IntAsker) Choices(choices ...int) *IntAsker

Choices sets an arbitrary number of choices for the user input. The list of choices will be automatically displayed when prompting the user. If the user enters a choice not in the list, Ask will return an error. If the set of available "choices" does not contain the default, behavior is undefined.

func (*IntAsker) Default

func (ia *IntAsker) Default(def int) *IntAsker

Default sets the default int for the IntAsker. The default int is returned from Ask if the user entered an empty input.

type PathAsker

type PathAsker struct {
	// contains filtered or unexported fields
}

PathAsker is an object that can ask for a path on the command line.

func Path

func Path(message string) *PathAsker

Path returns a PathAsker that will prompt the user with message when Ask is called.

Example
package main

import (
	"fmt"
	"path/filepath"

	"gitlab.com/loderunner/ask"
)

func main() {
	s, err := ask.Path("Enter path:").
		Ask()
	if err != nil {
		panic(err)
	}
	abs, err := filepath.Abs(s)
	if err != nil {
		panic(err)
	}
	fmt.Println(abs)
}
Output:

func Pathf

func Pathf(format string, args ...interface{}) *PathAsker

Pathf returns a PathAsker that will prompt the user with a message according to a format specifier. See the fmt package for formatting rules.

func (*PathAsker) Ask

func (pa *PathAsker) Ask() (string, error)

Ask prompts the user by displaying the PathAsker's message, reads from standard input until it encounters a newline or EOF and returns the input path. If the user enters an empty input and a default path is set, the default path will be returned. The user can auto-complete the path using TAB in the bash style. Returns an error if stdin could not be read, or if the input is too large for memory.

func (*PathAsker) Default

func (pa *PathAsker) Default(def string) *PathAsker

Default sets the default path for the PathAsker. The default path is returned from Ask if the user entered an empty input.

Example
dir, err := homedir.Dir()
if err != nil {
	panic(err)
}
dir = filepath.Join(dir, ".ask")
dir, err = ask.Path("Enter configuration directory:").Default(dir).Ask()
if err != nil {
	panic(err)
}
configPath := filepath.Join(dir, "config.yml")
fmt.Printf("Configuration will be saved at %s\n", configPath)
Output:

type StringAsker

type StringAsker struct {
	// contains filtered or unexported fields
}

StringAsker is an object that can ask for a string on the command line.

func String

func String(message string) *StringAsker

String returns a StringAsker that will prompt the user with message when Ask is called.

func Stringf

func Stringf(format string, args ...interface{}) *StringAsker

Stringf returns a StringAsker that will prompt the user with a message according to a format specifier. See the fmt package for formatting rules.

func (*StringAsker) Ask

func (sa *StringAsker) Ask() (string, error)

Ask prompts the user by displaying the StringAsker's message, reads from standard input until it encounters a newline or EOF and returns the input string. If the user enters an empty input and a default string is set, the default string will be returned. Returns an error if stdin could not be read, or if the input is too large for memory.

func (*StringAsker) Choices

func (sa *StringAsker) Choices(choices ...string) *StringAsker

Choices sets an arbitrary number of choices for the user input. The list of choices will be automatically displayed when prompting the user and choices will be available to auto-completion using TAB in the readline style. If the user enters a choice not in the list, Ask will return an error. If the set of available "choices" does not contain the default, behavior is undefined.

Example
package main

import (
	"fmt"

	"gitlab.com/loderunner/ask"
)

func main() {
	s, err := ask.String("What time of day is it?").
		Choices("morning", "midday", "afternoon", "evening", "night").
		Ask()
	if err != nil {
		panic(err)
	}
	fmt.Println("Good", s, "!")
}
Output:

func (*StringAsker) Default

func (sa *StringAsker) Default(def string) *StringAsker

Default sets the default string for the StringAsker. The default string is returned from Ask if the user entered no input. The default value will be automatically displayed when prompting the user. If the default is not in the set of available choices, behavior is undefined (see StringAsker.Choices).

func (*StringAsker) Password

func (sa *StringAsker) Password() *StringAsker

Password sets the password flag for the StringAsker. If password flag is set, the Prompt will not display user input.

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL