From 73c5b7538ed4af7a487ca400fd46c3f6fa768bcf Mon Sep 17 00:00:00 2001 From: Ivan Date: Wed, 30 Dec 2020 19:20:02 +0200 Subject: [PATCH] Add -f option for portable configs (#21) * Add -f option for portable configs --- README.md | 26 +++++++++++++++++++++++++- main.go | 14 +++++++++++--- options.go | 32 ++++++++++++++++++++++++++++---- options_test.go | 46 +++++++++++++++++++++++++++++++++++++++++----- 4 files changed, 105 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index fe8c911..6ae50a4 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,31 @@ go install ## Usage -`smug [:window name] [-w window name]... [--attach]`. +``` +smug [] [-f, --file ] [-w, --windows ]... [-a, --attach] [-d, --debug] +``` + +### Options: + +``` +-f, --file A custom path to a config file +-w, --windows List of windows to start. If session exists, those windows will be attached to current session. +-a, --attach Force switch client for a session +-d, --debug Print all commands to ~/.config/smug/smug.log +``` + +### Examples: + +``` +$ smug start blog +$ smug start blog:win1 +$ smug start blog -w win1 +$ smug start blog:win1,win2 +$ smug stop blog +$ smug start blog --attach +$ smug start -f ./project.yml -w win1 -w win2 +$ smug stop -f ./project.yml -w win1 +``` ### Examples diff --git a/main.go b/main.go index a8a6971..af5b6b5 100644 --- a/main.go +++ b/main.go @@ -12,10 +12,12 @@ const version = "v0.1.6" var usage = fmt.Sprintf(`Smug - tmux session manager. Version %s + Usage: - smug [-w ]... [--attach] [--debug] + smug [] [-f, --file ] [-w, --windows ]... [-a, --attach] [-d, --debug] Options: + -f, --file %s -w, --windows %s -a, --attach %s -d, --debug %s @@ -27,7 +29,7 @@ Examples: $ smug start blog:win1,win2 $ smug stop blog $ smug start blog --attach -`, version, WindowsUsage, AttachUsage, DebugUsage) +`, version, FileUsage, WindowsUsage, AttachUsage, DebugUsage) func main() { options, err := ParseOptions(os.Args[1:], func() { @@ -45,7 +47,13 @@ func main() { } userConfigDir := filepath.Join(ExpandPath("~/"), ".config/smug") - configPath := filepath.Join(userConfigDir, options.Project+".yml") + + var configPath string + if options.Config != "" { + configPath = options.Config + } else { + configPath = filepath.Join(userConfigDir, options.Project+".yml") + } f, err := ioutil.ReadFile(configPath) if err != nil { diff --git a/options.go b/options.go index f16a387..62630ab 100644 --- a/options.go +++ b/options.go @@ -12,9 +12,12 @@ const ( CommandStop = "stop" ) +var validCommands = []string{CommandStart, CommandStop} + type Options struct { Command string Project string + Config string Windows []string Attach bool Debug bool @@ -26,25 +29,36 @@ const ( WindowsUsage = "List of windows to start. If session exists, those windows will be attached to current session." AttachUsage = "Force switch client for a session" DebugUsage = "Print all commands to ~/.config/smug/smug.log" + FileUsage = "A custom path to a config file" ) // Creates a new FlagSet. // Moved it to a variable to be able to override it in the tests. var NewFlagSet = func(cmd string) *pflag.FlagSet { - return pflag.NewFlagSet(cmd, pflag.ContinueOnError) + f := pflag.NewFlagSet(cmd, pflag.ContinueOnError) + return f } func ParseOptions(argv []string, helpRequested func()) (Options, error) { - if len(argv) < 2 { + if len(argv) == 0 { + helpRequested() + return Options{}, ErrHelp + } + + if argv[0] == "--help" || argv[0] == "-h" { helpRequested() return Options{}, ErrHelp } cmd := argv[0] - project := argv[1] + if !Contains(validCommands, cmd) { + helpRequested() + return Options{}, ErrHelp + } flags := NewFlagSet(cmd) + config := flags.StringP("file", "f", "", FileUsage) windows := flags.StringArrayP("windows", "w", []string{}, WindowsUsage) attach := flags.BoolP("attach", "a", false, AttachUsage) debug := flags.BoolP("debug", "d", false, DebugUsage) @@ -58,6 +72,16 @@ func ParseOptions(argv []string, helpRequested func()) (Options, error) { return Options{}, err } + if len(argv) < 2 && *config == "" { + helpRequested() + return Options{}, ErrHelp + } + + var project string + if *config == "" { + project = argv[1] + } + if strings.Contains(project, ":") { parts := strings.Split(project, ":") project = parts[0] @@ -65,5 +89,5 @@ func ParseOptions(argv []string, helpRequested func()) (Options, error) { windows = &wl } - return Options{cmd, project, *windows, *attach, *debug}, nil + return Options{cmd, project, *config, *windows, *attach, *debug}, nil } diff --git a/options_test.go b/options_test.go index d392344..0832dd7 100644 --- a/options_test.go +++ b/options_test.go @@ -15,31 +15,43 @@ var usageTestTable = []struct { }{ { []string{"start", "smug"}, - Options{"start", "smug", []string{}, false, false}, + Options{"start", "smug", "", []string{}, false, false}, nil, 0, }, { []string{"start", "smug", "-w", "foo"}, - Options{"start", "smug", []string{"foo"}, false, false}, + Options{"start", "smug", "", []string{"foo"}, false, false}, nil, 0, }, { []string{"start", "smug:foo,bar"}, - Options{"start", "smug", []string{"foo", "bar"}, false, false}, + Options{"start", "smug", "", []string{"foo", "bar"}, false, false}, nil, 0, }, { []string{"start", "smug", "--attach", "--debug"}, - Options{"start", "smug", []string{}, true, true}, + Options{"start", "smug", "", []string{}, true, true}, nil, 0, }, { []string{"start", "smug", "-ad"}, - Options{"start", "smug", []string{}, true, true}, + Options{"start", "smug", "", []string{}, true, true}, + nil, + 0, + }, + { + []string{"start", "-f", "test.yml"}, + Options{"start", "", "test.yml", []string{}, false, false}, + nil, + 0, + }, + { + []string{"start", "-f", "test.yml", "-w", "win1", "-w", "win2"}, + Options{"start", "", "test.yml", []string{"win1", "win2"}, false, false}, nil, 0, }, @@ -55,6 +67,30 @@ var usageTestTable = []struct { ErrHelp, 1, }, + { + []string{"start"}, + Options{}, + ErrHelp, + 1, + }, + { + []string{"test"}, + Options{}, + ErrHelp, + 1, + }, + { + []string{}, + Options{}, + ErrHelp, + 1, + }, + { + []string{"--help"}, + Options{}, + ErrHelp, + 1, + }, } func TestParseOptions(t *testing.T) {