1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
  | 
// 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"
	"path/filepath"
	"strings"
	"go.wit.com/dev/alexflint/arg"
	"go.wit.com/gui"
	"go.wit.com/lib/config"
	"go.wit.com/lib/debugger"
	"go.wit.com/lib/env"
	"go.wit.com/lib/fhelp"
	"go.wit.com/lib/protobuf/argvpb"
	"go.wit.com/log"
)
// sent via -ldflags // is there a better way?
var VERSION string
var BUILDTIME string
// used for shell auto completion
var APPNAME string = "forge"
func (args) InitGui() error {
	// panic("got here")
	arg.Register(&gui.ArgvGui)
	// me.gui = gui.PreInit()
	me.myGui = fhelp.Gui()
	return nil
}
func (args) Exit() {
	gui.UnloadToolkits()
	if env.Verbose() {
		log.Info("argv.Exit() called", APPNAME+".Exit() because env.Verbose() == true")
	}
	// remove this from the template for your app (or make one for youself if you need it)
	forgeExit() // custom forge shutdown function
}
func (args) MustParse() error {
	me.pp = arg.MustParse(&argv)
	return nil
}
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
`
}
// 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) DoAutoComplete() error {
	var err error
	if me.pp == nil {
		me.pp, err = arg.ParseFlagsArgv(&argv)
		if err != nil {
			fmt.Fprintf(argvpb.Stddbg, "returned from parseFlagsArgv(%v)\n", err)
		}
	}
	if argvpb.PB.HelpCounter > 3 {
		argvpb.SetDebug(true)
		argvpb.PB.HelpCounter = 0
		if argvpb.Len() == 0 {
			fmt.Fprintf(argvpb.Stddbg, "len(PB.Real)=(%d)\n", len(argvpb.PB.Real))
			me.pp.WriteHelp(argvpb.Stderr)
			fmt.Fprintf(argvpb.Stddbg, "WriteHelp() (%v)\n", "fricking got here")
			fmt.Fprintf(argvpb.Stddbg, "WriteHelp() (%v)\n", "fricking got here")
			fmt.Fprintf(argvpb.Stddbg, "WriteHelp() (%v)\n", "fricking got here")
			return nil
		} else {
			fmt.Fprintf(argvpb.Stddbg, "WriteHelp() damnit len(%v) (%v)\n", len(argvpb.PB.Real), argvpb.PB.Real)
			fmt.Fprintf(argvpb.Stddbg, "WriteHelp() damnit len(%v) (%v)\n", len(argvpb.PB.Real), argvpb.PB.Real)
			fmt.Fprintf(argvpb.Stddbg, "WriteHelp() damnit len(%v) (%v)\n", len(argvpb.PB.Real), argvpb.PB.Real)
		}
		err = me.pp.WriteHelpForAutocomplete("", argvpb.PB.Real...)
		if err != nil {
			fmt.Fprintf(argvpb.Stddbg, "returned from WriteHelpForAutocomplete() pb.Real(%v)\n", argvpb.PB.Real)
			fmt.Fprintf(argvpb.Stddbg, "returned from WriteHelpForAutocomplete(%v)\n", err)
		}
		return nil
	}
	if argvpb.PB.IsMatch("cache") {
		matches, _ := matchCacheFiles()
		fmt.Fprintf(argvpb.Stdout, "%s", matches)
		return nil
	}
	if argvpb.PB.IsMatch("mode.--config") {
		matches, _ := matchModeDirs()
		fmt.Fprintf(argvpb.Stdout, "%s", matches)
		return nil
	}
	if argvpb.PB.IsMatch("mode") {
		err = me.pp.WriteHelpForAutocomplete("", "mode")
		matches := []string{"jwc", "false"}
		fmt.Fprintf(argvpb.Stdout, "%s", " "+strings.Join(matches, " "))
		return nil
	}
	if argvpb.PB.GetCmd() == "" {
		// these are base autocomplete strings
		matches := []string{"clean", "commit", "merge", "patch", "normal", "pull", "rebuild", "generate", "config", "cache"}
		matches = append(matches, "show", "add", "fixer", "dev", "verify", "mode", "gui", "whatchanged")
		matches = append(matches, "--version", "--force", "--all", "--verbose")
		fmt.Fprintf(argvpb.Stdout, "%s", strings.Join(matches, " "))
		return nil
	}
	err = me.pp.WriteHelpForAutocomplete(argvpb.PB.Partial, argvpb.PB.Real...)
	if err != nil {
		fmt.Fprintf(argvpb.Stddbg, "returned from WriteHelpForAutocomplete() pb.Real(%v)\n", argvpb.PB.Real)
		fmt.Fprintf(argvpb.Stddbg, "returned from WriteHelpForAutocomplete(%v)\n", err)
	}
	return err
}
func matchModeDirs() (string, error) {
	configDir, _ := os.UserConfigDir()
	globPattern := filepath.Join(configDir, "forge", "*")
	files, err := filepath.Glob(globPattern)
	var match string
	for _, file := range files {
		if config.IsDir(file) {
			_, base := filepath.Split(file)
			match += base + " "
		}
	}
	// log.Info("glob:", globPattern, "matchdirs:", match)
	return match, err
}
func matchCacheFiles() (string, error) {
	configDir, _ := os.UserCacheDir()
	globPattern := filepath.Join(configDir, "forge", "repos*.pb")
	files, err := filepath.Glob(globPattern)
	match := "all golang homedir"
	for _, file := range files {
		if config.IsDir(file) {
			_, base := filepath.Split(file)
			match += base + " "
		}
	}
	// log.Info("glob:", globPattern, "matchdirs:", match)
	return match, err
}
  |