adding bash completion handling

This commit is contained in:
Jeff Carr 2025-01-06 15:44:56 -06:00
parent bc5994b84e
commit 362ea63b97
3 changed files with 165 additions and 24 deletions

View File

@ -50,7 +50,7 @@ readonly: install
forge --list list --readonly forge --list list --readonly
config: install config: install
forge --config forge config
scan: install scan: install
forge do --scan forge do --scan

177
argv.go
View File

@ -1,5 +1,10 @@
package main package main
import (
"fmt"
"os"
)
/* /*
this parses the command line arguements this parses the command line arguements
*/ */
@ -9,6 +14,17 @@ var argv args
type EmptyCmd struct { 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 { type FindCmd struct {
All bool `arg:"--all" help:"select every repo (the default)"` All bool `arg:"--all" help:"select every repo (the default)"`
Mine bool `arg:"--mine" help:"your repos as defined in the forge config"` Mine bool `arg:"--mine" help:"your repos as defined in the forge config"`
@ -19,24 +35,28 @@ type FindCmd struct {
} }
type args struct { type args struct {
List *FindCmd `arg:"subcommand:list" help:"just show a table of the current state"` 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"` Dirty *EmptyCmd `arg:"subcommand:dirty" help:"check if your git repos are dirty"`
User *FindCmd `arg:"subcommand:user" help:"git checkout user"` User *FindCmd `arg:"subcommand:user" help:"git checkout user"`
Devel *FindCmd `arg:"subcommand:devel" help:"git checkout devel"` Devel *FindCmd `arg:"subcommand:devel" help:"git checkout devel"`
Master *FindCmd `arg:"subcommand:master" help:"git checkout master"` Master *FindCmd `arg:"subcommand:master" help:"git checkout master"`
GitPull *FindCmd `arg:"subcommand:pull" help:"run 'git pull'"` Checkout *CheckoutCmd `arg:"subcommand:checkout" help:"switch git branches"`
Config *FindCmd `arg:"subcommand:config" help:"show your .config/forge/ settings"` Pathc *PatchCmd `arg:"subcommand:patch" help:"examine and make patch sets"`
ListPatchSet bool `arg:"--list-patchset" help:"list patch sets"` GitPull *FindCmd `arg:"subcommand:pull" help:"run 'git pull'"`
DryRun bool `arg:"--dry-run" help:"show what would be run"` Config *FindCmd `arg:"subcommand:config" help:"show your .config/forge/ settings"`
Fix bool `arg:"--fix" help:"fix config, save config & exit"` ListPatchSet bool `arg:"--list-patchset" help:"list patch sets"`
Delete string `arg:"--delete" help:"delete this repo"` DryRun bool `arg:"--dry-run" help:"show what would be run"`
URL string `arg:"--connect" help:"gowebd url"` Fix bool `arg:"--fix" help:"fix config, save config & exit"`
Register string `arg:"--register" help:"register your git URL (foo.com/mystuff) or (github.com/foo/bar)"` Delete string `arg:"--delete" help:"delete this repo"`
GitReset bool `arg:"--git-reset" help:"run 'git reset --hard'"` URL string `arg:"--connect" help:"gowebd url"`
Scan bool `arg:"--scan" help:"reload protobuf from .git/"` Register string `arg:"--register" help:"register your git URL (foo.com/mystuff) or (github.com/foo/bar)"`
Force bool `arg:"--force" help:"force redo things"` GitReset bool `arg:"--git-reset" help:"run 'git reset --hard'"`
PatchSet string `arg:"--patchset" help:"make patch set"` Scan bool `arg:"--scan" help:"reload protobuf from .git/"`
Apply string `arg:"--apply" help:"apply a patch set"` 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 { func (args) Version() string {
@ -48,11 +68,122 @@ func (a args) Description() string {
forge -- in the spirit of things like sourceforge forge -- in the spirit of things like sourceforge
Examples: Examples:
forge --config # shows your forge config (~/.config/forge/) forge config # shows your forge config (~/.config/forge/)
forge find --all --pull # run 'git pull' in every repo forge list # show every repo state
forge find --mine --user # checkout the user branch forge dirty # show only dirty repos
forge find --all --devel # checkout the devel branch forge pull # run 'git pull' in every repo
forge find --all --master # checkout the master branch 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)
}

10
main.go
View File

@ -3,6 +3,7 @@ package main
// An app to submit patches for the 30 GO GUI repos // An app to submit patches for the 30 GO GUI repos
import ( import (
"os"
"strings" "strings"
"go.wit.com/dev/alexflint/arg" "go.wit.com/dev/alexflint/arg"
@ -31,6 +32,15 @@ func getVersion(repo *gitpb.Repo, name string) string {
func main() { func main() {
me = new(mainType) me = new(mainType)
me.pp = arg.MustParse(&argv) 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 me.urlbase = argv.URL
if me.urlbase == "" { if me.urlbase == "" {
me.urlbase = "https://go.wit.com/" me.urlbase = "https://go.wit.com/"