// Copyright 2017-2025 WIT.COM Inc. All rights reserved. // Use of this source code is governed by the GPL 3.0 package main import ( "os" "go.wit.com/gui" "go.wit.com/lib/debugger" "go.wit.com/lib/fhelp" "go.wit.com/lib/gui/prep" ) /* this parses the command line arguements using alex flint's go-arg */ var argv args type args struct { Checkout *CheckoutCmd `arg:"subcommand:checkout" help:"'git checkout'"` Clean *CleanCmd `arg:"subcommand:clean" help:"'git clean' + reset repos to original state"` Commit *CommitCmd `arg:"subcommand:commit" help:"'git commit'"` Gui *EmptyCmd `arg:"subcommand:gui" help:"open the gui"` Merge *MergeCmd `arg:"subcommand:merge" help:"merge branches"` Normal *ModeCmd `arg:"subcommand:normal" help:"shortcut to 'forge mode normal'"` Mode *ModeCmd `arg:"subcommand:mode" help:"sets the mode (hacking, merging, publishing)"` Patch *PatchCmd `arg:"subcommand:patch" help:"work with patchsets"` Pull *PullCmd `arg:"subcommand:pull" help:"'git pull'"` Show *ShowCmd `arg:"subcommand:show" help:"print out things"` Dev *DevCmd `arg:"subcommand:dev" help:"features under development"` Add *EmptyCmd `arg:"subcommand:add" help:"Scan directores for git repos"` Fixer *FixCmd `arg:"subcommand:fixer" help:"like in the movie"` All bool `arg:"--all" help:"whatever you are doing, do it all over"` Force bool `arg:"--force" help:"try to strong-arm things"` Verbose bool `arg:"--verbose" help:"show more output than usual"` Fix bool `arg:"--fix" help:"try to make repairs"` } type EmptyCmd struct { } type testCmd string type ShowCmd struct { Dirty *EmptyCmd `arg:"subcommand:dirty" help:"show dirty git repos"` DirtySave *EmptyCmd `arg:"subcommand:dirtysave" help:"check dirty then save"` MasterDefault *EmptyCmd `arg:"subcommand:masterdefault" help:"run the default behavior for master branches"` Mtime *EmptyCmd `arg:"subcommand:mtime" help:"show mtime changes"` Repo *RepoCmd `arg:"subcommand:repos" help:"print a table of the current repos"` Tag *TagCmd `arg:"subcommand:tag" help:"show git tags"` } type FixCmd struct { Porcelain *EmptyCmd `arg:"subcommand:porcelain" help:"git status --porcelain"` Urls bool `arg:"--urls" help:"check for changes in repo urls"` Untracked bool `arg:"--untracked" help:"git untracked file list"` DeleteUser bool `arg:"--delete-user" help:"delete all user branches (checks for safety)"` Prune bool `arg:"--prune" help:"'git fetch --prune' everywhere"` } func (ShowCmd) Examples() string { return "forge show dirty\nforge show repos --all" } type RepoCmd struct { Urls *EmptyCmd `arg:"subcommand:urls" help:"show repo urls"` 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/"` User bool `arg:"--user" help:"show repos on the user branch"` Full bool `arg:"--full" help:"show full repo names"` } type ModeCmd struct { Master *EmptyCmd `arg:"subcommand:master" help:"keep all repos on the master branch"` Devel *EmptyCmd `arg:"subcommand:devel" help:"use user branches"` User *EmptyCmd `arg:"subcommand:user" help:"use user branches"` Normal *EmptyCmd `arg:"subcommand:normal" help:"use the 'normal' forge development mode"` } type CommitCmd struct { All bool `arg:"--all" help:"git commit in all dirty repos"` } type DevCmd struct { Config *ConfigCmd `arg:"subcommand:config" help:"show your .config/forge/ settings"` Build *EmptyCmd `arg:"subcommand:build" help:"build this repo"` Install *EmptyCmd `arg:"subcommand:install" help:"build & install this repo"` Generate string `arg:"--generate" help:"run go generate"` BuildForge bool `arg:"--forge-rebuild" help:"download all the forge sources and rebuild forge"` URL string `arg:"--connect" help:"forge url"` } type CleanCmd struct { Fix *EmptyCmd `arg:"subcommand:fix" help:"try to fix problems"` Repo string `arg:"--repo" help:"work on one specific git repository"` } // matches func (c CleanCmd) Match(partial string) []string { // return repos here return []string{"go.wit.com/apps/forge", "go.wit.com/apps/virtigo"} } type CleanDevelCmd struct { Force bool `arg:"--force" help:"try to strong arm things"` } type PatchCmd struct { Apply bool `arg:"--apply" help:"attempt to apply any new patches"` Show bool `arg:"--show" help:"show the current patches"` Submit bool `arg:"--resubmit" help:"resubmit your git commits"` } type PullCmd struct { Force bool `arg:"--force" help:"try to strong-arm things"` List *EmptyCmd `arg:"subcommand:list" help:"list repo versions"` Check *RepoCmd `arg:"subcommand:check" help:"check for repo changes"` Update *EmptyCmd `arg:"subcommand:update" help:"report updates"` } type TagCmd struct { List *EmptyCmd `arg:"subcommand:list" help:"list the tags"` Clean *EmptyCmd `arg:"subcommand:clean" help:"clean out old and duplicate tags"` Delete string `arg:"--delete" help:"delete a tag"` } type CheckoutCmd struct { User *EmptyCmd `arg:"subcommand:user" help:"git checkout user"` Devel *EmptyCmd `arg:"subcommand:devel" help:"git checkout devel"` Master *EmptyCmd `arg:"subcommand:master" help:"git checkout master"` } type MergeCmd struct { All bool `arg:"--all" help:"merge all"` Devel *EmptyCmd `arg:"subcommand:devel" help:"merge user to devel"` Master *EmptyCmd `arg:"subcommand:master" help:"merge devel to master"` Publish *EmptyCmd `arg:"subcommand:publish" help:"increment versions and publish master branch"` Check *EmptyCmd `arg:"subcommand:check" help:"check if merge is complete and ready to publish"` } type ConfigCmd struct { Add *ConfigAddCmd `arg:"subcommand:add" help:"add a config setting"` 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 ConfigAddCmd struct { Path string `arg:"--path" help:"absolute path of the git repo"` Namespace string `arg:"--namespace" help:"namespace of the git repo"` Directory bool `arg:"--directory" help:"repo is a directory to match against"` ReadOnly bool `arg:"--readonly" help:"repo is readonly"` Writable bool `arg:"--writable" help:"repo is writable"` Favorite bool `arg:"--favorite" help:"forge will always go-clone or git clone this" default:"false"` 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"` } func (args) Version() string { // log.Info(me.sh.Version()) // return ARGNAME + " " + VERSION + " Built on " + BUILDTIME return prep.StandardVersion(ARGNAME, VERSION, BUILDTIME) } func (args) Buildtime() (string, string) { return BUILDTIME, VERSION } func (a args) Description() string { // doHelp() 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'. Orginally written to maintain the +50 GO git repositories for the WIT Private Cloud ` } func ifBlank(arg string) bool { if arg == "''" { // if empty, the user has not typed something return true } return false } func (args) Appname() string { return ARGNAME } // arg.Register(&argGui) // log.Info("ArgvGui() started") func (args) ArgvGui() error { me.myGui = fhelp.Gui() // adds the GUI package argv support me.origGui = gui.New() return nil } func (args) ArgvDebugger() bool { debugger.InitDebugger() // me.myGui = gui.Init() return true } func (args) Examples() string { var out string out += "forge show # show the state of all your repos\n" out += "forge normal # the defaults for 'normal' forge distributed development\n" out += " # it will makes a user branch in every git repo\n" out += "forge clean # removes changes forge might have made\n" out += " # purges all untracked git files, etc\n" out += "forge pull --force # 'git pull' on all repos\n" out += "forge commit --al # 'git commit' in every dirty repo\n" out += "forge merge --all # 'git merge' all patches to devel & master\n" out += "forge add # scan your current directory for all git repos\n" return out } // sends the strings to bash or zsh that will be your options func (a args) SendCompletionStrings(pb *prep.Auto) { if pb.Cmd == "" { // these are base autocomplete strings pb.SendStrings([]string{"checkout", "clean", "commit", "gui", "merge", "mode", "patch", "pull", "show", "add", "fixer", "--version", "--force", "dev", "normal", "--all"}) } else { // autogenerate the strings for the subcommand using github.com/alexflint/go-arg pb.GenerateSubCommandStrings(pb.Goargs...) } os.Exit(0) }