// Copyright 2017-2025 WIT.COM Inc. All rights reserved. // Use of this source code is governed by the GPL 3.0 package main import ( "fmt" "os" ) /* this parses the command line arguements using alex flint's go-arg */ var argv args type args struct { Help *EmptyCmd `arg:"subcommand:help" help:"New to forge? This is for you.'"` Checkout *CheckoutCmd `arg:"subcommand:checkout" help:"switch branches using 'git checkout'"` Clean *CleanCmd `arg:"subcommand:clean" help:"start over at the beginning"` Commit *CommitCmd `arg:"subcommand:commit" help:"'git commit' but errors out if on wrong branch"` Config *ConfigCmd `arg:"subcommand:config" help:"show your .config/forge/ settings"` Debug *EmptyCmd `arg:"subcommand:debug" help:"debug forge"` Dirty *DirtyCmd `arg:"subcommand:dirty" help:"show dirty git repos"` GitFetch *FindCmd `arg:"subcommand:fetch" help:"run 'git fetch master'"` Gui *EmptyCmd `arg:"subcommand:gui" help:"open the gui"` List *FindCmd `arg:"subcommand:list" help:"print a table of the current repos"` Merge *MergeCmd `arg:"subcommand:merge" help:"merge branches"` Normal *NormalCmd `arg:"subcommand:normal" help:"set every repo to the default state for software development"` Patch *PatchCmd `arg:"subcommand:patch" help:"make patchsets"` Pull *PullCmd `arg:"subcommand:pull" help:"run 'git pull'"` URL string `arg:"--connect" help:"forge url"` All bool `arg:"--all" help:"git commit --all"` Build string `arg:"--build" help:"build a repo"` Install string `arg:"--install" help:"install a repo"` BuildForge bool `arg:"--forge-rebuild" help:"download and rebuild forge"` Force bool `arg:"--force" help:"try to strong arm things"` Verbose bool `arg:"--verbose" help:"show more output"` } type EmptyCmd struct { } type NormalCmd struct { On *EmptyCmd `arg:"subcommand:on" help:"turn normal mode on"` Off *EmptyCmd `arg:"subcommand:off" help:"turn normal mode off"` } type CommitCmd struct { Submit bool `arg:"--submit" default:"true" help:"submit the patches to forge"` } type testCmd string type CleanCmd struct { Delete *EmptyCmd `arg:"subcommand:delete" help:"rescan repo"` Devel *CleanDevelCmd `arg:"subcommand:devel" help:"clean and verify the devel branches"` Force *EmptyCmd `arg:"subcommand:force" help:"do destructive stuff"` GitReset *EmptyCmd `arg:"subcommand:git-reset" help:"git reset --hard"` Pub *EmptyCmd `arg:"subcommand:pub" help:"clean target version numbers"` User *EmptyCmd `arg:"subcommand:user" help:"clean the user branches"` Repo string `arg:"--repo" help:"which repo to look at"` } type CleanDevelCmd struct { Force bool `arg:"--force" help:"try to strong arm things"` } type PatchCmd struct { Check *EmptyCmd `arg:"subcommand:check" help:"check the state of the patches"` List *EmptyCmd `arg:"subcommand:list" help:"your downloaded patchsets"` Get *EmptyCmd `arg:"subcommand:get" help:"get the new patchsets"` Show *EmptyCmd `arg:"subcommand:show" help:"your pending commits to your code"` Submit *SubmitCmd `arg:"subcommand:submit" help:"submit your commits"` Repos *SubmitCmd `arg:"subcommand:repos" help:"show repos with patches"` } type SubmitCmd struct { Match string `arg:"positional"` } type PullCmd struct { Check *EmptyCmd `arg:"subcommand:check" help:"check repo versions"` Dirty *EmptyCmd `arg:"subcommand:dirty" help:"only check dirty repos"` Patches *EmptyCmd `arg:"subcommand:patches" help:"only check repos with patches"` } type ConfigAddCmd struct { Path string `arg:"--path" help:"absolute path of the git repo"` GoPath string `arg:"--gopath" help:"GO path of the git repo"` Directory bool `arg:"--directory" default:"false" help:"repo is a directory to match against"` ReadOnly bool `arg:"--readonly" default:"false" help:"repo is readonly"` Writable bool `arg:"--writable" default:"false" help:"repo is writable"` Favorite bool `arg:"--favorite" default:"false" help:"forge will always go-clone or git clone this"` Private bool `arg:"--private" default:"false" help:"repo can not be published"` Interesting bool `arg:"--interesting" default:"false" help:"something you decided was cool"` DebName string `arg:"--debname" help:"the name of the debian package (or rpm, etc)"` Master string `arg:"--master" help:"the git 'master' or 'main' branch name"` Devel string `arg:"--devel" help:"the git devel branch name"` User string `arg:"--user" help:"the git user branch name"` } type ConfigCmd struct { Add *ConfigAddCmd `arg:"subcommand:add" help:"add a config setting"` Fix *EmptyCmd `arg:"subcommand:fix" help:"fix .config/forge/ and/or repos.pb protobuf file"` List *EmptyCmd `arg:"subcommand:list" help:"list your config settings"` Delete string `arg:"--delete" help:"delete this repo"` Register string `arg:"--register" help:"register your git URL (foo.com/mystuff) or (github.com/foo/bar)"` } 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 MergeCmd struct { Devel *FindCmd `arg:"subcommand:devel" help:"merge user to devel"` Master *FindCmd `arg:"subcommand:master" help:"merge devel to master"` Publish *EmptyCmd `arg:"subcommand:publish" help:"increment versions and publish master branch"` } type DirtyCmd struct { } 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"` Favorites bool `arg:"--favorites" help:"your repos configured as favorites"` Private bool `arg:"--private" help:"your private repos from your .config/forge/"` Dirty bool `arg:"--dirty" help:"only use dirty git repos"` User bool `arg:"--user" help:"show repos on the user branch"` Full bool `arg:"--full" help:"show full repo names"` // ReadOnly bool `arg:"--readonly" help:"include read-only repos"` } func (args) Version() string { return ARGNAME + " " + VERSION + " Built on " + BUILDTIME } func (a args) Description() string { return ` forge -- a tool to manage lots of git repos. forge includes a GUI and TUI. forge only executes the 'git' command. Everything it does, you can run by hand with 'git'. ` } // // handles shell autocomplete // func DoAutoComplete(argv []string) { // fmt.Fprintln(os.Stderr, "") // these are for debugging // fmt.Fprintln(os.Stderr, "in autocomplete:", argv) // these are for debugging switch argv[0] { case "checkout": fmt.Println("devel master user") case "clean": // me.pp.WriteHelp(os.Stderr) // me.pp.WriteUsageForSubcommand(os.Stderr, me.pp.SubcommandNames()...) // me.pp.WriteHelpForSubcommand(os.Stderr, me.pp.SubcommandNames()...) // me.pp.WriteHelpForSubcommand(os.Stderr, "clean") fmt.Println("--force") case "commit": fmt.Println("--all") case "config": fmt.Println("add fix list debug") case "dirty": fmt.Println("") case "gui": if ifBlank(argv[1]) { fmt.Fprintln(os.Stderr, "") fmt.Fprintln(os.Stderr, "CUI: terminal interface using 'gocui'") fmt.Fprintln(os.Stderr, "GUI: linux and macos GUI using GTK") } else { fmt.Println("CUI GUI") } case "list": fmt.Println("--full") case "merge": fmt.Println("devel master") case "normal": fmt.Println("on off") case "pull": fmt.Println("--force check") case "patch": fmt.Println("check get list repos submit show") case "user": fmt.Println("--force") case "devel": fmt.Println("--force") case "master": fmt.Println("") case "verify": fmt.Println("user devel master") default: if argv[0] == ARGNAME { // list the subcommands here fmt.Println("help list checkout clean commit dirty debug fetch gui normal merge patch pull") } } os.Exit(0) } func ifBlank(arg string) bool { if arg == "''" { // if empty, the user has not typed something return true } return false } func (a args) DoAutoComplete(argv []string) { DoAutoComplete(argv) }