From 362ea63b9759235d91ec2cc530abf2c2faf95304 Mon Sep 17 00:00:00 2001 From: Jeff Carr Date: Mon, 6 Jan 2025 15:44:56 -0600 Subject: [PATCH] adding bash completion handling --- Makefile | 2 +- argv.go | 177 +++++++++++++++++++++++++++++++++++++++++++++++-------- main.go | 10 ++++ 3 files changed, 165 insertions(+), 24 deletions(-) diff --git a/Makefile b/Makefile index 3d41721..ca8ff4d 100644 --- a/Makefile +++ b/Makefile @@ -50,7 +50,7 @@ readonly: install forge --list list --readonly config: install - forge --config + forge config scan: install forge do --scan diff --git a/argv.go b/argv.go index 99d11cd..f8a0620 100644 --- a/argv.go +++ b/argv.go @@ -1,5 +1,10 @@ package main +import ( + "fmt" + "os" +) + /* this parses the command line arguements */ @@ -9,6 +14,17 @@ var argv args type EmptyCmd struct { } +type PatchCmd struct { + List bool `arg:"--list" help:"list available patches"` + Show string `arg:"--show" help:"show a specific patch"` +} + +type CheckoutCmd struct { + User *FindCmd `arg:"subcommand:user" help:"git checkout user"` + Devel *FindCmd `arg:"subcommand:devel" help:"git checkout devel"` + Master *FindCmd `arg:"subcommand:master" help:"git checkout master"` +} + type FindCmd struct { All bool `arg:"--all" help:"select every repo (the default)"` Mine bool `arg:"--mine" help:"your repos as defined in the forge config"` @@ -19,24 +35,28 @@ type FindCmd struct { } type args struct { - List *FindCmd `arg:"subcommand:list" help:"just show a table of the current state"` - Dirty *EmptyCmd `arg:"subcommand:dirty" help:"check if your git repos are dirty"` - User *FindCmd `arg:"subcommand:user" help:"git checkout user"` - Devel *FindCmd `arg:"subcommand:devel" help:"git checkout devel"` - Master *FindCmd `arg:"subcommand:master" help:"git checkout master"` - GitPull *FindCmd `arg:"subcommand:pull" help:"run 'git pull'"` - Config *FindCmd `arg:"subcommand:config" help:"show your .config/forge/ settings"` - ListPatchSet bool `arg:"--list-patchset" help:"list patch sets"` - DryRun bool `arg:"--dry-run" help:"show what would be run"` - Fix bool `arg:"--fix" help:"fix config, save config & exit"` - Delete string `arg:"--delete" help:"delete this repo"` - URL string `arg:"--connect" help:"gowebd url"` - Register string `arg:"--register" help:"register your git URL (foo.com/mystuff) or (github.com/foo/bar)"` - GitReset bool `arg:"--git-reset" help:"run 'git reset --hard'"` - Scan bool `arg:"--scan" help:"reload protobuf from .git/"` - Force bool `arg:"--force" help:"force redo things"` - PatchSet string `arg:"--patchset" help:"make patch set"` - Apply string `arg:"--apply" help:"apply a patch set"` + List *FindCmd `arg:"subcommand:list" help:"just show a table of the current state"` + Dirty *EmptyCmd `arg:"subcommand:dirty" help:"check if your git repos are dirty"` + User *FindCmd `arg:"subcommand:user" help:"git checkout user"` + Devel *FindCmd `arg:"subcommand:devel" help:"git checkout devel"` + Master *FindCmd `arg:"subcommand:master" help:"git checkout master"` + Checkout *CheckoutCmd `arg:"subcommand:checkout" help:"switch git branches"` + Pathc *PatchCmd `arg:"subcommand:patch" help:"examine and make patch sets"` + GitPull *FindCmd `arg:"subcommand:pull" help:"run 'git pull'"` + Config *FindCmd `arg:"subcommand:config" help:"show your .config/forge/ settings"` + ListPatchSet bool `arg:"--list-patchset" help:"list patch sets"` + DryRun bool `arg:"--dry-run" help:"show what would be run"` + Fix bool `arg:"--fix" help:"fix config, save config & exit"` + Delete string `arg:"--delete" help:"delete this repo"` + URL string `arg:"--connect" help:"gowebd url"` + Register string `arg:"--register" help:"register your git URL (foo.com/mystuff) or (github.com/foo/bar)"` + GitReset bool `arg:"--git-reset" help:"run 'git reset --hard'"` + Scan bool `arg:"--scan" help:"reload protobuf from .git/"` + Force bool `arg:"--force" help:"force redo things"` + PatchSet string `arg:"--patchset" help:"make patch set"` + Apply string `arg:"--apply" help:"apply a patch set"` + Bash bool `arg:"--bash" help:"generage bash completion"` + BashAuto []string `arg:"--bash-auto" help:"generage bash completion"` } func (args) Version() string { @@ -48,11 +68,122 @@ func (a args) Description() string { forge -- in the spirit of things like sourceforge Examples: - forge --config # shows your forge config (~/.config/forge/) - forge find --all --pull # run 'git pull' in every repo - forge find --mine --user # checkout the user branch - forge find --all --devel # checkout the devel branch - forge find --all --master # checkout the master branch + forge config # shows your forge config (~/.config/forge/) + forge list # show every repo state + forge dirty # show only dirty repos + forge pull # run 'git pull' in every repo + forge checkout user # git checkout the user branch + forge checkout devel # git checkout the devel branch + forge checkout master # git checkout the master branch ` } + +// prints help to STDERR +func (args) doBashHelp() { + name := "forge" + if argv.BashAuto[1] != "''" { + // if this is not blank, then the user has typed something + return + } + if argv.BashAuto[0] != name { + // if this is not the name of the command, the user already started doing something + return + } + fmt.Fprintln(os.Stderr, "") + fmt.Fprintln(os.Stderr, "hello world") + var more string + p0 := "0" + argv.BashAuto[0] + p1 := "1" + argv.BashAuto[1] + p2 := "2" + argv.BashAuto[2] + if len(argv.BashAuto[1]) >= 0 { + more = "more" + } else { + more = "less" + } + p1a := fmt.Sprintf("1a.%s.%+v.\n", argv.BashAuto[1], len(argv.BashAuto[1])) + fmt.Fprintln(os.Stderr, "pull something else", argv.BashAuto, len(argv.BashAuto), p0, p1, p2, p1a, "end", more) + fmt.Fprintln(os.Stderr, "") +} + +func (args) doBashAuto() { + name := "forge" + argv.doBashHelp() + switch argv.BashAuto[0] { + case "dirty": + fmt.Println("") + case "list": + fmt.Println("--all --mine --favorites --private") + case "user": + case "devel": + fmt.Println("reset --mine") + case "checkout": + fmt.Println("user devel master") + case "patches": + fmt.Println("--list --submit --show") + default: + if argv.BashAuto[0] == name { + // list the subcommands here + fmt.Println("--bash patches checkout list dirty pull user devel master") + } + } + os.Exit(0) +} + +// complete -F forge --bash forge +func (args) doBashNotes() { + fmt.Println("#/usr/bin/env bash") + fmt.Println("") + fmt.Println("# if we add a 'hidden' go-arg option --bash") + fmt.Println("#") + fmt.Println("# then this is all we have to output:") + fmt.Println("# complete -C forge --bash go") + fmt.Println("") + fmt.Println("_forge_complete()") + fmt.Println("{") + fmt.Println(" # sets local to this func vars") + fmt.Println(" local cur prev all") + fmt.Println(" cur=${COMP_WORDS[COMP_CWORD]}") + fmt.Println(" prev=${COMP_WORDS[COMP_CWORD-1]}") + fmt.Println(" all=${COMP_WORDS[@]}") + fmt.Println("") + fmt.Println(" # this is where we generate the go-arg output") + fmt.Println(" FORGE=$(forge --bash-auto -- $prev \\'$cur\\' $all)") + fmt.Println("") + fmt.Println(" # this compares the command line input from the user") + fmt.Println(" # to whatever strings we output") + fmt.Println(" COMPREPLY=( $(compgen -W \"$FORGE\" -- $cur) ) # THIS WORKS") + fmt.Println(" return 0") + fmt.Println("}") + os.Exit(0) +} + +// complete -F forge --bash forge +func (args) doBash() { + name := "forge" + fmt.Println("# add this in your bashrc:") + fmt.Println("") + fmt.Println("# if we add a 'hidden' go-arg option --bash") + fmt.Println("#") + fmt.Println("# then this is all we have to output:") + fmt.Println("# complete -C " + name + " --bash go") + fmt.Println("") + fmt.Println("_" + name + "_complete()") + fmt.Println("{") + fmt.Println(" # sets local to this func vars") + fmt.Println(" local cur prev all") + fmt.Println(" cur=${COMP_WORDS[COMP_CWORD]}") + fmt.Println(" prev=${COMP_WORDS[COMP_CWORD-1]}") + fmt.Println(" all=${COMP_WORDS[@]}") + fmt.Println("") + fmt.Println(" # this is where we generate the go-arg output") + fmt.Println(" GOARGS=$(" + name + " --bash-auto $prev \\'$cur\\' $all)") + fmt.Println("") + fmt.Println(" # this compares the command line input from the user") + fmt.Println(" # to whatever strings we output") + fmt.Println(" COMPREPLY=( $(compgen -W \"$GOARGS\" -- $cur) ) # THIS WORKS") + fmt.Println(" return 0") + fmt.Println("}") + fmt.Println("complete -F _" + name + "_complete " + name) + os.Exit(0) +} diff --git a/main.go b/main.go index 4cc6181..05e72a6 100644 --- a/main.go +++ b/main.go @@ -3,6 +3,7 @@ package main // An app to submit patches for the 30 GO GUI repos import ( + "os" "strings" "go.wit.com/dev/alexflint/arg" @@ -31,6 +32,15 @@ func getVersion(repo *gitpb.Repo, name string) string { func main() { me = new(mainType) me.pp = arg.MustParse(&argv) + + if argv.Bash { + argv.doBash() + os.Exit(0) + } + if len(argv.BashAuto) != 0 { + argv.doBashAuto() + os.Exit(0) + } me.urlbase = argv.URL if me.urlbase == "" { me.urlbase = "https://go.wit.com/"