diff options
| -rw-r--r-- | cgit-clone/Makefile | 80 | ||||
| -rw-r--r-- | cgit-clone/argv.go | 213 | ||||
| -rw-r--r-- | cgit-clone/exit.go | 22 | ||||
| -rw-r--r-- | cgit-clone/main.go | 52 | ||||
| -rw-r--r-- | cgit-clone/structs.go | 51 | 
5 files changed, 418 insertions, 0 deletions
diff --git a/cgit-clone/Makefile b/cgit-clone/Makefile new file mode 100644 index 0000000..117e8c4 --- /dev/null +++ b/cgit-clone/Makefile @@ -0,0 +1,80 @@ +VERSION = $(shell git describe --tags) +BUILDTIME = $(shell date +%Y.%m.%d_%H%M) + +# make build     # go build   using your git cloned repos (GO111MODULE=off) +# make install   # go install using your git cloned repos (GO111MODULE=off) +# make gocui     # try the ncurses gui plugin +# make andlabs   # try the andlabs gui plugin (uses GTK) + +default: install-verbose +	cgit-clone + +vet: +	@GO111MODULE=off go vet +	@echo this go binary package builds okay + +build: goimports vet +	GO111MODULE=off go build \ +		-ldflags "-X main.VERSION=${VERSION} -X main.BUILDTIME=${BUILDTIME} -X gui.GUIVERSION=${VERSION}" + +install: goimports +	GO111MODULE=off go install \ +		-ldflags "-X main.VERSION=${VERSION} -X main.BUILDTIME=${BUILDTIME} -X gui.GUIVERSION=${VERSION}" +	cp -f ~/go/bin/forge ~/go/bin/last.forge # this is a hack so that go-deb can build a .deb file for forge # TODO: remove this + +install-verbose: goimports vet +	GO111MODULE=off go install -v -x \ +		-ldflags "-X main.VERSION=${VERSION} -X main.BUILDTIME=${BUILDTIME} -X gui.GUIVERSION=${VERSION}" + +install-raw: goimports vet +	go install \ +		-ldflags "-X main.VERSION=${VERSION} -X main.BUILDTIME=${BUILDTIME} -X gui.GUIVERSION=${VERSION}" + +GTK: clean install +	forge --gui andlabs + +GTK-verbose: clean install +	forge --gui andlabs --gui-verbose + +CUI: install +	forge --gui gocui + +CUI-verbose: install +	forge --gui gocui --gui-verbose >/tmp/forge.log 2>&1 + +goimports: +	reset +	goimports -w *.go +	@# // to globally reset paths: +	@# // gofmt -w -r '"go.wit.com/gui/gadgets" -> "go.wit.com/lib/gadgets"' *.go + +clean: +	-rm -f cgit-clone go.* +	# -rm -f ~/go/src/repos.pb +	go-mod-clean purge + +identify-protobuf: +	autogenpb --identify ~/go/src/repos.pb + +devel: +	forge clean devel --force --verbose + +pull: install +	FORGE_URL="https://forge.grid.wit.com/" forge pull check + +# cloudflare blocks POST due to captcha checks / human detection? +# POST must be direct socket. probably for the best anyway +submit: +	FORGE_URL="https://forge.grid.wit.com/" forge patch submit "forge auto commit" + +commit: +	FORGE_URL="https://forge.grid.wit.com/" forge commit --all + +check: install +	FORGE_URL="https://forge.grid.wit.com/" forge patch check + +doc: +	echo "/*" > doc.go +	forge -h >> doc.go +	echo "*/" >> doc.go +	echo "package main" >> doc.go diff --git a/cgit-clone/argv.go b/cgit-clone/argv.go new file mode 100644 index 0000000..524c91f --- /dev/null +++ b/cgit-clone/argv.go @@ -0,0 +1,213 @@ +// 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/lib/gui/prep" +	"go.wit.com/log" +) + +/* +	this parses the command line arguements using alex flint's go-arg +*/ + +var argv args + +type args struct { +	Checkout *CheckoutCmd `arg:"subcommand:checkout"                  help:"switch branches using 'git checkout'"` +	Clean    *CleanCmd    `arg:"subcommand:reset"                     help:"reset all git repos to the original state"` +	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"` +	Gui      *EmptyCmd    `arg:"subcommand:gui"                       help:"open the gui"` +	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'"` +	Show     *ShowCmd     `arg:"subcommand:show"                      help:"print out things"` +	Dev      *DevCmd      `arg:"subcommand:dev"                       help:"features under development"` +	All      bool         `arg:"--all"                                help:"git commit --all"` +	Force    bool         `arg:"--force"                              help:"try to strong-arm things"` +	Verbose  bool         `arg:"--verbose"                            help:"show more output"` +} + +func (args) Examples() string { +	var out string +	out += "forge pull --force    # 'git pull' on all repos\n" +	out += "forge merge --all     # merge all patches to devel & master\n" +	out += "forge normal fix      # the defaults for 'normal' forge distributed development (makes local user branches)\n" +	out += "forge reset fix       # smartly restore all git repos to the upstream state (removes changes forge might have made)\n" +	return out +} + +type EmptyCmd struct { +} + +type testCmd string + +type ShowCmd struct { +	Dirty *EmptyCmd `arg:"subcommand:dirty"                     help:"show dirty git repos"` +	Repo  *RepoCmd  `arg:"subcommand:repos"                     help:"print a table of the current repos"` +	Tag   *TagCmd   `arg:"subcommand:tag"                       help:"show git tags"` +} + +func (ShowCmd) Examples() string { +	return "forge show dirty\nforge show repos --all" +} + +type RepoCmd 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/"` +	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"` +} + +type NormalCmd struct { +	Fix *EmptyCmd `arg:"subcommand:fix"              help:"try to fix problems"` +	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"                    help:"submit the patches to forge"` +	All bool `arg:"--all"                             help:"git commit in all dirty repos"` +} + +type DevCmd struct { +	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"` +	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 { +	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 { +	Force bool      `arg:"--force"                    help:"try to strong-arm things"` +	List  *EmptyCmd `arg:"subcommand:list"            help:"list repo versions"` +	Check *EmptyCmd `arg:"subcommand:check"           help:"check for repo changes"` +} + +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"` +} + +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 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"                       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 { +	return ARGNAME + " " + VERSION + "    Built on " + BUILDTIME +} + +// keep this small +func doHelp() { +	log.Info("") +	log.Info("forge -h       : to see the available options") +	log.Info("forge --bash   : will create a bash autocomplete file") +	log.Info("forge          : with no arguements, forge tries to load a GO GUI plugin") +	log.Info("               : there are two GUI plugins. terminal & GTK") +	log.Info("") +	log.Info("forge list     : shows a table of all your repos") +	log.Info("forge checkout : checks out all your repos to the same branch") +	log.Info("               : the default is your user branch") +	log.Info("forge clean    : reverts all repos to the master branch") +	log.Info("forge dirty    : show all repos git reports as dirty") +	log.Info("") +} + +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'. +` +} + +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 +} + +func (a args) DoAutoComplete(pb *prep.Auto) { +	if pb.Cmd == "" { +		pb.Autocomplete3([]string{"checkout", "reset", "commit", "config", "gui", "merge", "normal", "patch", "pull", "show"}) +	} else { +		pb.SubCommand(pb.Argv...) +	} +	os.Exit(0) +} diff --git a/cgit-clone/exit.go b/cgit-clone/exit.go new file mode 100644 index 0000000..507686d --- /dev/null +++ b/cgit-clone/exit.go @@ -0,0 +1,22 @@ +// 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/log" +) + +func okExit(thing string) { +	if thing != "" { +		log.Info("cgit-clone exit:", thing, "ok") +	} +	me.forge.Exit() +} + +func badExit(err error) { +	log.Info("cgit-clone failed: ", err) +	os.Exit(-1) +} diff --git a/cgit-clone/main.go b/cgit-clone/main.go new file mode 100644 index 0000000..dd48ad7 --- /dev/null +++ b/cgit-clone/main.go @@ -0,0 +1,52 @@ +// Copyright 2017-2025 WIT.COM Inc. All rights reserved. +// Use of this source code is governed by the GPL 3.0 + +package main + +// An app to submit patches for the 30 GO GUI repos + +import ( +	"os" +	"path/filepath" + +	"go.wit.com/lib/gui/prep" +	"go.wit.com/lib/gui/shell" +	"go.wit.com/lib/protobuf/forgepb" +	"go.wit.com/log" +) + +// sent via -ldflags +var VERSION string +var BUILDTIME string + +// used for shell auto completion +var ARGNAME string = "cgit-clone" + +func main() { +	me = new(mainType) +	me.auto = prep.Bash(&argv) // adds auto complete to go-args + +	// the current forge init process +	me.forge = forgepb.Init() // init forge.pb + +	homedir := "/var/lib/git" +	if err := os.Chdir(homedir); err != nil { +		badExit(err) +	} + +	for repo := range me.forge.Repos.IterAll() { +		fulldir := filepath.Join(repo.FullPath, ".git") +		cgitdir := repo.Namespace + ".git" +		if shell.IsDir(filepath.Join(homedir, cgitdir)) { +			// log.Info("already have", filepath.Join(homedir, cgitdir)) +			continue +		} else { +			// log.Info("need", filepath.Join(homedir, cgitdir)) +		} + +		cmd := []string{"git", "clone", "--bare", fulldir, cgitdir} +		log.Info(cmd) +		shell.RunVerbose(cmd) +	} +	okExit("") +} diff --git a/cgit-clone/structs.go b/cgit-clone/structs.go new file mode 100644 index 0000000..15b17bc --- /dev/null +++ b/cgit-clone/structs.go @@ -0,0 +1,51 @@ +// Copyright 2017-2025 WIT.COM Inc. All rights reserved. +// Use of this source code is governed by the GPL 3.0 + +package main + +import ( +	"go.wit.com/gui" +	"go.wit.com/lib/gadgets" +	"go.wit.com/lib/gui/prep" +	"go.wit.com/lib/protobuf/forgepb" +) + +var me *mainType + +func (b *mainType) Disable() { +	b.mainbox.Disable() +} + +func (b *mainType) Enable() { +	b.mainbox.Enable() +} + +// returns the server to connect to +func myServer() string { +	return me.forge.GetForgeURL() +} + +// this app's variables +type mainType struct { +	// pp         *arg.Parser    // for parsing the command line args.  Yay to alexflint! +	auto       *prep.Auto     // more experiments for bash handling +	forge      *forgepb.Forge // for holding the forge protobuf files +	myGui      *prep.GuiPrep  // for initializing the GUI toolkits +	foundPaths []string       // stores gopaths to act on (when doing go-clone) +	configSave bool           // if the config file should be saved after finishing +	urlbase    string         // base URL + +	mainWindow *gadgets.BasicWindow +	mainbox    *gui.Node           // the main box. enable/disable this +	autoDryRun *gui.Node           // checkbox for --dry-run +	goSrcPwd   *gadgets.OneLiner   // what is being used as primary directory for your work +	goSrcEdit  *gadgets.BasicEntry // what is being used as primary directory for your work +	gitAuthor  *gadgets.OneLiner   // ENV GIT_AUTHOR NAME and EMAIL + +	// these hold the branches that the user can switch all the repositories to them +	reposWinB       *gui.Node // button that opens the repos window +	repoAllB        *gui.Node // "all" repos button +	repoDirtyB      *gui.Node // "dirty" repos button +	repoDevelMergeB *gui.Node // "merge to devel" repos button +	repoWritableB   *gui.Node // "what repos are writable" repos button +}  | 
