[小ネタ][Golang]Surveyでインストーラ風のターミナル入力を作ってみた
とある調査にてインタラクティブにターミナルから入力や選択できるインストーラのようなものを作れるかを調べる機会がありました。 使用している言語がGolangであったため、Golangでライブラリがあるかを調べたところ、survey というライブラリがありました。
surveyのサイトを見れば何ができるかは分かりますが、自分のユースケースに合うかを検証するため、インストーラ風の入力のサンプルを作ってみました。今回はこのサンプルについて書いてみたいと思います。
作ったプログラムのターミナル入力
先にどのようなターミナル入力ができたかを書きたいと思います。何かのインストールやシステム設定する処理を想定し
- ユーザ名
- パスワード
- OSを選択
- インストールするオプションを複数選択
- 詳細コメントを入力するかを yes/no で選択
- (yesを選択時)複数行の詳細コメントを入力
- インストールするかを yes/no で確認
の入力や選択を行うサンプルとなります。ターミナル上での入力は以下のようになります(分かりやすいように一部改行を入れるなど加工をしております)。
? Please input user name. testname ? Please type your system password.: ***** ? Please select install OS.: [Use arrows to move, type to filter] Windows Linux > Mac ? Please select install options: [Use arrows to move, space to select, <right> to all, <left> to none, type to filter] [x] data backup [ ] log backup > [x] alert email ? Input detail?: (y/N) y ? Please input detail comment. [Enter 2 empty lines to finish]this is a sample. something. ? Would you like to insatll now?: (y/N) y
インストールやシステム設定でよくありそうな入力や選択、yes/no での処理の分岐は実現できそうでした。
作ったサンプルプログラム
上記のターミナル入力を行なった、今回作成したサンプルプログラムは以下となります。
package main import ( "fmt" "github.com/AlecAivazis/survey/v2" ) var questions = []*survey.Question{ { Name: "userName", Prompt: &survey.Input{Message: "Please input user name."}, Validate: survey.Required, }, { Name: "password", Prompt: &survey.Password{ Message: "Please type your system password.:", }, Validate: survey.Required, }, { Name: "os", Prompt: &survey.Select{ Message: "Please select install OS.:", Options: []string{"Windows", "Linux", "Mac"}, Default: "Mac", }, Validate: survey.Required, }, { Name: "options", Prompt: &survey.MultiSelect{ Message: "Please select install options:", Options: []string{"data backup", "log backup", "alert email"}, }, }, { Name: "inputDetail", Prompt: &survey.Confirm{ Message: "Input detail?:", }, Validate: survey.Required, }, } var answers struct { UserName string `survey:"userName"` Passowrd string `survey:"password"` OS string `survey:"os"` Options []string `survey:"options"` InputDetail bool `survey:"inputDetail"` } func main() { err := survey.Ask(questions, &answers) if err != nil { panic(err) } var detail string if answers.InputDetail { prompt := &survey.Multiline{ Message: "Please input detail comment.", } survey.AskOne(prompt, &detail) } var install bool prompt := &survey.Confirm{ Message: "Would you like to insatll now?:", } survey.AskOne(prompt, &install) if !install { fmt.Println("not install. finish.") return } fmt.Println("install start ...") fmt.Println(answers.UserName, answers.OS, answers.Options) fmt.Printf("detail comment:\n%s\n", detail) }
動かすには、Golangの実行環境と、「$ go get github.com/AlecAivazis/survey/v2」でのインストールを行う必要があります。
ユーザー名の入力〜詳細を入力するかのyes/no の選択までの連続した質問は、「questions」に格納して一括で出力しています(56行目)。
詳細を入力するかでyesを選択した場合の入力やインストールをするかの確認については、独立して出力し(66行目、73行目)、入力値によって処理を分岐させています。
まとめ
このような感じで、インストーラ風のターミナル入力を実現できることが分かりました。何かの役に立てば幸いです。