From 411226cf9df0814ff8e714958da87c853b519bc6 Mon Sep 17 00:00:00 2001 From: Jeff Carr Date: Thu, 16 Oct 2025 13:58:28 -0500 Subject: A new life awaits you in the Off-world colonies! --- Makefile | 6 ++--- argv.LoadSafe.go | 28 ++++++++++++++++++++ argv.Print.go | 60 +++++++++++++++++++++++++++++++++++++++++++ argv.proto | 35 +++++++++++++++++++++++++ auto.Print.go | 60 ------------------------------------------- auto.proto | 35 ------------------------- debugger.go | 2 +- dryrun.go | 2 +- errors.go | 2 +- exit.go | 6 ++--- generate.go | 2 +- gui.go | 2 +- interface.go | 6 ++--- makeAutocompleteFiles.bash.go | 6 ++--- makeAutocompleteFiles.go | 2 +- makeAutocompleteFiles.zsh.go | 2 +- parseArgv.go | 14 +++++----- sendStrings.go | 14 +++++----- structs.go | 14 +++++----- theMagicOfAutocomplete.go | 16 ++++++------ version.go | 8 +++--- 21 files changed, 175 insertions(+), 147 deletions(-) create mode 100644 argv.LoadSafe.go create mode 100644 argv.Print.go create mode 100644 argv.proto delete mode 100644 auto.Print.go delete mode 100644 auto.proto diff --git a/Makefile b/Makefile index a91c8be..2d5b734 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ -all: proto vet +all: goimports proto vet @echo This GO code passes the compile checks proto: - autogenpb --proto auto.proto + autogenpb --proto argv.proto generate: clean go mod init @@ -28,5 +28,5 @@ clean: # To work around that breaking, you must change the version # also, all the wrapping code must support this. which it doesn't proto-renumber: clean - autogenpb --renumber --proto auto.proto + autogenpb --renumber --proto argv.proto make goimports vet diff --git a/argv.LoadSafe.go b/argv.LoadSafe.go new file mode 100644 index 0000000..a66758c --- /dev/null +++ b/argv.LoadSafe.go @@ -0,0 +1,28 @@ +// Code generated by go.wit.com/apps/autogenpb DO NOT EDIT. +// go install go.wit.com/apps/autogenpb@latest +// +// This file was autogenerated with autogenpb: +// autogenpb v0.5.27 Built on 2025/10/16 17:13:05 ( 50 m) +// Theese sort.pb.go and marshal.pb.go files are autogenerated +// The autogenpb sources have example .proto files with instructions +// + +package argvpb + +import ( + "errors" + + "go.wit.com/lib/config" +) + +// deletes and remakes the PB file when .proto versions change +func (pb *Argvs) LoadSafe() error { + err := config.LoadPB(pb) + if errors.Is(err, config.VersionMismatch) { + panic("fixme in autopb") + // TODO: erase and recreate the PB file + } else if err != nil { + panic("still fixme in") + } + return err +} diff --git a/argv.Print.go b/argv.Print.go new file mode 100644 index 0000000..d0a4447 --- /dev/null +++ b/argv.Print.go @@ -0,0 +1,60 @@ +package argvpb + +// debug argv protobuf functions +// enable with --autodebug or Setenv( "AUTOCOMPLETE_VERBOSE" ) + +import ( + "fmt" + "os" + "strings" + + "go.wit.com/lib/cobol" +) + +// decides here to print to STDERR or not +func (pb *Argv) Debugf(fmts string, parts ...any) { + fmts = strings.TrimSpace(fmts) + fmts += "\n" + // NOTE: env doesn't work probably most (all?) the time because bash + // doesn't send all the ENV to autocomplete. so, trap on a "--autodebug" command line arg + if os.Getenv("AUTOCOMPLETE_VERBOSE") == "true" || pb.Debug { + if !pb.Newline { + fmt.Fprintf(os.Stderr, "\n") + pb.Newline = true + } + fmt.Fprintf(os.Stderr, fmts, parts...) + } else { + // fmt.Fprintf(os.Stderr, "NOT DOING ANYTHING\n") + } +} + +// print out auto complete debugging info +func (pb *Argv) PrintDebug() { + pb.PrintDebugNew("ARGV") +} + +func (pb *Argv) PrintDebugNew(msg string) { + cmd := fmt.Sprintf("cmd='%s'", pb.Cmd) + arglast := fmt.Sprintf("last='%s'", pb.Last) + partial := fmt.Sprintf("p='%s'", pb.Partial) + dur := cobol.Duration(pb.Ctime) + var fast string + if pb.Fast { + fast = "fast=1," + pb.Fastcmd + } else { + fast = "fast=0," + pb.Fastcmd + } + sargv := fmt.Sprintf("argv(%v)", pb.Real) + pb.Debugf("%s: age=(%s) %-12.12s %-12.12s %-12.12s %s %s goargs='%v'", msg, dur, cmd, arglast, partial, fast, sargv, pb.Goargs) +} + +func (all *Argvs) PrintHistory() { + for pb := range all.IterAll() { + pb.PrintDebugNew("HIST") + } +} + +// todo: fix this +func (pb *Argv) WriteHelp() { + me.pp.WriteHelp(os.Stdout) +} diff --git a/argv.proto b/argv.proto new file mode 100644 index 0000000..c5f26b9 --- /dev/null +++ b/argv.proto @@ -0,0 +1,35 @@ +// Copyright 2025 WIT.COM Inc Licensed GPL 3.0 + +syntax = "proto3"; + +package argvpb; + +import "google/protobuf/timestamp.proto"; // Import the well-known type for Timestamp +import "google/protobuf/duration.proto"; // for duration + +message Argv { // `autogenpb:marshal` `autogenpb:sort` `autogenpb:nomutex` + google.protobuf.Timestamp ctime = 1; // when the user tried this autocomplete + google.protobuf.Duration duration = 2; // time since the last autocomplete + string argname = 3; // what the shell thinks the name of the executable is + string arg0 = 4; // what os.Exec() has as os.Argv[0] // not interesting + string arg1 = 5; // should always be "--auto-complete" // not interesting + string arg3 = 6; // usually argv3 == argv0 + repeated string real = 7; // what is really sent to the application + string cmd = 8; // the cmd being processed. For "git pull ", cmd would be "pull" + string partial = 9; // set to the partial string trying to be matched + bool isAuto = 10; // is true if '--auto-complete' is set + bool setupAuto = 11; // is true if '--bash' is set // setup bash autocomplete here + bool debug = 12; // print debugging info if true + bool newline = 13; // was a newline was sent to STDERR? + string last = 14; // the last arg + repeated string goargs = 15; // what to send to alex flint's go-args for help + bool fast = 16; // was the user fast last time? + string fastcmd = 17; // what subcommand was the user fast on? +} + +message Argvs { // `autogenpb:marshal` `autogenpb:sort` `autogenpb:nomutex` + string uuid = 1; // `autogenpb:uuid:1e6e765c-0c77-4c81-a622-0d819bfcce9a` + string version = 2; // `autogenpb:version:v0.0.3` + repeated Argv argvs = 3; + string filename = 4; // `autogenpb:save` -- this enables autogenerated pb.Load() and pb.Save() +} diff --git a/auto.Print.go b/auto.Print.go deleted file mode 100644 index 377d921..0000000 --- a/auto.Print.go +++ /dev/null @@ -1,60 +0,0 @@ -package prep - -// debug argv protobuf functions -// enable with --autodebug or Setenv( "AUTOCOMPLETE_VERBOSE" ) - -import ( - "fmt" - "os" - "strings" - - "go.wit.com/lib/cobol" -) - -// decides here to print to STDERR or not -func (pb *Auto) Debugf(fmts string, parts ...any) { - fmts = strings.TrimSpace(fmts) - fmts += "\n" - // NOTE: env doesn't work probably most (all?) the time because bash - // doesn't send all the ENV to autocomplete. so, trap on a "--autodebug" command line arg - if os.Getenv("AUTOCOMPLETE_VERBOSE") == "true" || pb.Debug { - if !pb.Newline { - fmt.Fprintf(os.Stderr, "\n") - pb.Newline = true - } - fmt.Fprintf(os.Stderr, fmts, parts...) - } else { - // fmt.Fprintf(os.Stderr, "NOT DOING ANYTHING\n") - } -} - -// print out auto complete debugging info -func (pb *Auto) PrintDebug() { - pb.PrintDebugNew("ARGV") -} - -func (pb *Auto) PrintDebugNew(msg string) { - cmd := fmt.Sprintf("cmd='%s'", pb.Cmd) - arglast := fmt.Sprintf("last='%s'", pb.Last) - partial := fmt.Sprintf("p='%s'", pb.Partial) - dur := cobol.Duration(pb.Ctime) - var fast string - if pb.Fast { - fast = "fast=1," + pb.Fastcmd - } else { - fast = "fast=0," + pb.Fastcmd - } - sargv := fmt.Sprintf("argv(%v)", pb.Argv) - pb.Debugf("%s: age=(%s) %-12.12s %-12.12s %-12.12s %s %s goargs='%v'", msg, dur, cmd, arglast, partial, fast, sargv, pb.Goargs) -} - -func (all *Autos) PrintHistory() { - for pb := range all.IterAll() { - pb.PrintDebugNew("HIST") - } -} - -// todo: fix this -func (pb *Auto) WriteHelp() { - me.pp.WriteHelp(os.Stdout) -} diff --git a/auto.proto b/auto.proto deleted file mode 100644 index 6ec39c7..0000000 --- a/auto.proto +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2025 WIT.COM Inc Licensed GPL 3.0 - -syntax = "proto3"; - -package httppb; - -import "google/protobuf/timestamp.proto"; // Import the well-known type for Timestamp -import "google/protobuf/duration.proto"; // for duration - -message Auto { // `autogenpb:marshal` `autogenpb:sort` `autogenpb:nomutex` - google.protobuf.Timestamp ctime = 1; // when the user tried this autocomplete - google.protobuf.Duration duration = 2; // time since the last autocomplete - string argname = 3; // what the shell thinks the name of the executable is - string arg0 = 4; // what os.Exec() has as os.Argv[0] // not interesting - string arg1 = 5; // should always be "--auto-complete" // not interesting - string arg3 = 6; // usually argv3 == argv0 - repeated string argv = 7; // use this to store whatever you want while the whole POST happens - string cmd = 8; // the cmd being processed. For "git pull ", cmd would be "pull" - string partial = 9; // set to the partial string trying to be matched - bool isAuto = 10; // is true if '--auto-complete' is set - bool setupAuto = 11; // is true if '--bash' is set // setup bash autocomplete here - bool debug = 12; // print debugging info if true - bool newline = 13; // was a newline was sent to STDERR? - string last = 14; // the last arg - repeated string goargs = 15; // what to send to alex flint's go-args for help - bool fast = 16; // was the user fast last time? - string fastcmd = 17; // what subcommand was the user fast on? -} - -message Autos { // `autogenpb:marshal` `autogenpb:sort` `autogenpb:nomutex` - string uuid = 1; // `autogenpb:uuid:94210ebf-a534-4b33-aadd-2f5e1f56ae38` - string version = 2; // `autogenpb:version:v0.0.1` - repeated Auto autos = 3; - string filename = 4; // `autogenpb:save` -- this enables autogenerated pb.Load() and pb.Save() -} diff --git a/debugger.go b/debugger.go index 5d1298a..0fbce7d 100644 --- a/debugger.go +++ b/debugger.go @@ -1,4 +1,4 @@ -package prep +package argvpb // initializes logging and command line options diff --git a/dryrun.go b/dryrun.go index 037f0a9..b9f4447 100644 --- a/dryrun.go +++ b/dryrun.go @@ -1,4 +1,4 @@ -package prep +package argvpb // think about using something like this diff --git a/errors.go b/errors.go index 7da8395..68db4ea 100644 --- a/errors.go +++ b/errors.go @@ -1,4 +1,4 @@ -package prep +package argvpb // Gemini's excellent at this sorta research. Not much else though diff --git a/exit.go b/exit.go index aeab59c..1419ae2 100644 --- a/exit.go +++ b/exit.go @@ -1,4 +1,4 @@ -package prep +package argvpb import ( "fmt" @@ -15,7 +15,7 @@ import ( // also, it supports a custom Exit() back to your application -func (pb *Auto) GoodExit(msg string) { +func (pb *Argv) GoodExit(msg string) { go ExitWatchdog() if me.appExit != nil { me.appExit() @@ -25,7 +25,7 @@ func (pb *Auto) GoodExit(msg string) { os.Exit(0) } -func (pb *Auto) BadExit(msg string, err error) { +func (pb *Argv) BadExit(msg string, err error) { go ExitWatchdog() if me.appExit != nil { me.appExit() diff --git a/generate.go b/generate.go index 362d2a5..7ff9ba1 100644 --- a/generate.go +++ b/generate.go @@ -1,4 +1,4 @@ -package prep +package argvpb // 'make generate' will call this // diff --git a/gui.go b/gui.go index 551eaab..1146e52 100644 --- a/gui.go +++ b/gui.go @@ -1,4 +1,4 @@ -package prep +package argvpb import ( "os" diff --git a/interface.go b/interface.go index 0a8b784..02541a6 100644 --- a/interface.go +++ b/interface.go @@ -1,4 +1,4 @@ -package prep +package argvpb // this is a work in progress @@ -14,13 +14,13 @@ type appnameI interface { type autoFuncI interface { // Version returns the version string that will be printed on a line by itself // at the top of the help message. - DoAutoComplete(*Auto) + DoAutoComplete(*Argv) } type sendCompletionStringsI interface { // Version returns the version string that will be printed on a line by itself // at the top of the help message. - SendCompletionStrings(*Auto) + SendCompletionStrings(*Argv) } type buildtimeI interface { diff --git a/makeAutocompleteFiles.bash.go b/makeAutocompleteFiles.bash.go index d66bf90..1a4158c 100644 --- a/makeAutocompleteFiles.bash.go +++ b/makeAutocompleteFiles.bash.go @@ -1,4 +1,4 @@ -package prep +package argvpb // makes the needed bash completion in the bash standard paths @@ -40,12 +40,12 @@ func MakeBashCompleteFiles(argname string) { } // deprecate this -func Bash3(dest any) *Auto { +func Bash3(dest any) *Argv { return Autocomplete(dest) } // deprecate this -func Bash(dest any) *Auto { +func Bash(dest any) *Argv { return Autocomplete(dest) } diff --git a/makeAutocompleteFiles.go b/makeAutocompleteFiles.go index 2a5f972..19a541b 100644 --- a/makeAutocompleteFiles.go +++ b/makeAutocompleteFiles.go @@ -1,4 +1,4 @@ -package prep +package argvpb import ( "os" diff --git a/makeAutocompleteFiles.zsh.go b/makeAutocompleteFiles.zsh.go index 7b4a3f0..98e4647 100644 --- a/makeAutocompleteFiles.zsh.go +++ b/makeAutocompleteFiles.zsh.go @@ -1,4 +1,4 @@ -package prep +package argvpb import "go.wit.com/log" diff --git a/parseArgv.go b/parseArgv.go index f0103f0..c91c1e5 100644 --- a/parseArgv.go +++ b/parseArgv.go @@ -1,4 +1,4 @@ -package prep +package argvpb // initializes logging and command line options @@ -10,8 +10,8 @@ import ( "go.wit.com/log" ) -func parseArgv(argname string) *Auto { - pb := new(Auto) +func parseArgv(argname string) *Argv { + pb := new(Argv) pb.Argname = argname // this shouldn't really happen. OS/POSIX error? @@ -101,7 +101,7 @@ func parseArgv(argname string) *Auto { // the user is doing autocomplete on the command itself pb.Partial = "" pb.Cmd = "" - pb.Argv = []string{""} + pb.Real = []string{""} return pb } if pb.Partial == "''" { @@ -117,10 +117,10 @@ func parseArgv(argname string) *Auto { // don't put pb.Partial into Argv continue } - pb.Argv = append(pb.Argv, s) + pb.Real = append(pb.Real, s) } // set pb.Cmd to the first thing that doesn't have a '-' arg - for _, s := range pb.Argv { + for _, s := range pb.Real { if strings.HasPrefix(s, "-") { continue } @@ -132,7 +132,7 @@ func parseArgv(argname string) *Auto { pb.Cmd = "" } // try to figure out what the last argv is - for _, s := range pb.Argv { + for _, s := range pb.Real { p := fmt.Sprintf("'%s'", s) if pb.Partial == p { pb.Debugf("DEBUG: Last argv MATCHES Partial %s %s", s, p) diff --git a/sendStrings.go b/sendStrings.go index 98ab7fa..546746d 100644 --- a/sendStrings.go +++ b/sendStrings.go @@ -1,4 +1,4 @@ -package prep +package argvpb // sends the autocomplete strings to the shell // also where custom strings are pulled in from the application @@ -13,22 +13,22 @@ import ( ) // deprecate -func (pb *Auto) Autocomplete3(sendthis []string) { +func (pb *Argv) Autocomplete3(sendthis []string) { pb.SendStrings(sendthis) } // deprecate -func (pb *Auto) Autocomplete2(sendthis string) { +func (pb *Argv) Autocomplete2(sendthis string) { pb.SendStrings(strings.Split(sendthis, " ")) } // the application must send a string "help run list" -func (pb *Auto) SendString(sendthis string) { +func (pb *Argv) SendString(sendthis string) { pb.SendStrings(strings.Split(sendthis, " ")) } // the application must send an array []string{"help", "run", "list"} -func (pb *Auto) SendStrings(parts []string) { +func (pb *Argv) SendStrings(parts []string) { /* dur := pb.Duration.AsDuration() if dur < time.Millisecond*200 { @@ -79,11 +79,11 @@ func (pb *Auto) SendStrings(parts []string) { } // try out a new name. also, this whole thing is dumb and needs to be redone -func (pb *Auto) GenerateSubCommandStrings(cmd ...string) { +func (pb *Argv) GenerateSubCommandStrings(cmd ...string) { pb.SubCommand(cmd...) } -func (pb *Auto) SubCommand(cmd ...string) { +func (pb *Argv) SubCommand(cmd ...string) { partial := strings.Trim(pb.Partial, "'") if pb.Debug { if me.examples == nil { diff --git a/structs.go b/structs.go index 2594094..bfbe429 100644 --- a/structs.go +++ b/structs.go @@ -1,4 +1,4 @@ -package prep +package argvpb // initializes logging and command line options @@ -28,17 +28,17 @@ var me *AutoArgs // this is a work in progress type AutoArgs struct { - id int // should be unique - // hidden bool // don't update the toolkits when it's hidden - Auto func([]string) // the function for shell autocomplete + id int // should be unique + hidden bool // don't update the toolkits when it's hidden + Argv func([]string) // the function for shell autocomplete examples func() string // some examples appExit func() // app Exit() buildtime func() (string, string) // some examples - autoFunc func(*Auto) // also a function for autocomplete + pp *arg.Parser // for parsing the command line args. Yay to alexf lint! + autoFunc func(*Argv) // also a function for autocomplete guiFunc func() error // enables Gui functions err error // store any errors from argv - pp *arg.Parser // for parsing the command line args. Yay to alexf lint! - pb *Auto + pb *Argv ARGNAME string // a good way to track the name of the binary ? VERSION string diff --git a/theMagicOfAutocomplete.go b/theMagicOfAutocomplete.go index ae0888d..2b345a4 100644 --- a/theMagicOfAutocomplete.go +++ b/theMagicOfAutocomplete.go @@ -1,4 +1,4 @@ -package prep +package argvpb // This is where the actual autocomplete happens // lots of the fun magic is in here @@ -15,7 +15,7 @@ import ( timestamppb "google.golang.org/protobuf/types/known/timestamppb" ) -func Autocomplete(dest any) *Auto { +func Autocomplete(dest any) *Argv { me = new(AutoArgs) // todo: redo this findAppInfo(dest) // parses back to main() for argv info @@ -32,10 +32,10 @@ func Autocomplete(dest any) *Auto { me.pb = parseArgv(me.ARGNAME) // the argv history - all := NewAutos() + all := NewArgvs() // initializes the application config file - config.Init(me.ARGNAME, me.VERSION, me.BUILDTIME, me.pb.Argv) + config.Init(me.ARGNAME, me.VERSION, me.BUILDTIME, me.pb.Real) // loads the autocomplete history file err := config.LoadCache(all, "argv", me.ARGNAME) // @@ -78,7 +78,7 @@ func Autocomplete(dest any) *Auto { // set the duration since the last auto complete // find the last entry. this is dumb way to do it - last := new(Auto) + last := new(Argv) last.Ctime = timestamppb.New(time.Now().Add(-time.Second)) for found := range all.IterAll() { last = found @@ -95,7 +95,7 @@ func Autocomplete(dest any) *Auto { // roll the autocomplete file if all.Len() > 15 { me.pb.Debugf("DEBUG: trim() history is over 100 len=%d vs new=%d", all.Len(), all.Len()-90) - all.Autos = all.Autos[all.Len()-10:] + all.Argvs = all.Argvs[all.Len()-10:] // newall.Autos = all.Autos[0:10] // for _, found := range all.Autos[0:10] { // newall.Append(found) @@ -118,7 +118,7 @@ func Autocomplete(dest any) *Auto { } flags := []string{} - for _, s := range me.pb.Argv { + for _, s := range me.pb.Real { if s == "--autodebug" { continue } @@ -174,7 +174,7 @@ func Autocomplete(dest any) *Auto { } if me.autoFunc == nil { - me.pb.SubCommand(me.pb.Argv...) + me.pb.SubCommand(me.pb.Real...) } else { me.autoFunc(me.pb) // run the autocomplete function the user made for their application } diff --git a/version.go b/version.go index b4f26fe..0aaa75d 100644 --- a/version.go +++ b/version.go @@ -1,4 +1,4 @@ -package prep +package argvpb // initializes logging and command line options @@ -10,16 +10,16 @@ import ( "go.wit.com/log" ) -func (pb *Auto) Version() string { +func (pb *Argv) Version() string { return pb.getVersion() } -func doVersion(pb *Auto) { +func doVersion(pb *Argv) { log.Info(pb.getVersion()) os.Exit(0) } -func (pb *Auto) getVersion() string { +func (pb *Argv) getVersion() string { if me.buildtime == nil { return "app doesn't have argv.BuildVersion()" } -- cgit v1.2.3