Compare commits

..

60 Commits
v0.5 ... master

Author SHA1 Message Date
Jeff Carr 8b199273e8 api change 2025-09-13 01:07:34 -05:00
Jeff Carr 67df8f90f9 rm GoSrc() 2025-09-11 22:21:13 -05:00
Jeff Carr bb1df07910 common forge.Init() 2025-09-11 04:46:26 -05:00
Jeff Carr d19f4a8911 new forge init() 2025-09-11 03:27:49 -05:00
Jeff Carr 54811a5bc1 work on lookup/ 2025-07-07 18:51:38 -05:00
Jeff Carr 529eb104d5 allow cloning http(s) URL's 2025-06-29 17:49:52 -05:00
Jeff Carr 21dd714514 go-mod-clean syntax change 2025-06-04 07:41:47 -05:00
Jeff Carr 4ab621a7f2 notes about 'git bug' 2025-05-23 03:27:53 -05:00
Jeff Carr 0c5183edf9 works more often now 2025-02-22 09:43:22 -06:00
Jeff Carr f078399929 tinkering 2025-02-22 08:15:29 -06:00
Jeff Carr c521620b04 fix build and cleanup old code 2025-02-22 06:52:50 -06:00
Jeff Carr cc19c8ac8e minor 2025-02-15 07:27:43 -06:00
Jeff Carr 52f41adba2 fixed up some names 2025-01-30 01:47:34 -06:00
Jeff Carr 9561e45610 more cleanups 2024-12-18 23:05:31 -06:00
Jeff Carr 163484be1f attempting to clean go.* handling again 2024-12-18 20:08:14 -06:00
Jeff Carr d473f80919 fixes to clone 2024-12-18 17:58:25 -06:00
Jeff Carr b80b7baa2d wrong lookup 2024-12-18 03:34:43 -06:00
Jeff Carr d3f8613bd8 fixes for new gitpb 2024-12-17 07:02:45 -06:00
Jeff Carr e8de69e5a9 IsValid() became IsValidDir() 2024-12-17 01:55:09 -06:00
Jeff Carr 232477808f attempt to pull down git notes 2024-12-15 21:10:25 -06:00
Jeff Carr 41671d1298 hmm. 2024-12-15 17:03:41 -06:00
Jeff Carr 882c448b85 add --ignore for edge cases to see what happens 2024-12-15 15:51:27 -06:00
Jeff Carr bab2506d34 trying to fix clone 2024-12-15 12:14:22 -06:00
Jeff Carr b3bfa8915c lots more code cleanups 2024-12-15 08:45:44 -06:00
Jeff Carr 7cade75da8 all sorts of updates. it didn't work before! 2024-12-15 08:31:42 -06:00
Jeff Carr 5f1f19d9ca use go-mod-clean 2024-12-13 12:34:31 -06:00
Jeff Carr e69a078b75 minor 2024-12-11 23:11:39 -06:00
Jeff Carr c543052492 minor 2024-12-11 01:18:56 -06:00
Jeff Carr 8ba815f12e testing automation 2024-12-10 01:47:13 -06:00
Jeff Carr 2b21ee65d7 attempting complete automated testing 2024-12-07 16:46:59 -06:00
Jeff Carr a3a54501f6 rill is fantastic 2024-12-03 13:23:35 -06:00
Jeff Carr 8e29098aa8 hmm. macos build doesn't work 2024-12-02 11:22:24 -06:00
Jeff Carr 5155f8038e add --build and --install 2024-12-01 22:21:34 -06:00
Jeff Carr 106f1403c6 fixing branch names 2024-12-01 12:51:38 -06:00
Jeff Carr 3532a553e4 fixes to marshal 2024-12-01 10:42:32 -06:00
Jeff Carr a483e69d12 misc cleanups 2024-12-01 00:47:04 -06:00
Jeff Carr 58a05460c7 fix for autogen'd protobuf stuff 2024-11-30 15:32:42 -06:00
Jeff Carr fa98d97dfb prepare to use go-clone to build 2024-11-30 12:44:29 -06:00
Jeff Carr dd258155df remove old versions 2024-11-30 02:02:04 -06:00
Jeff Carr 6e5fbd4c33 refactor to use forgepb 2024-11-30 01:35:56 -06:00
Jeff Carr fbab336c03 golang 1.20 is old enough most macs should work 2024-11-29 21:49:57 -06:00
Jeff Carr bff6eb093e move FindGitSrc to forgepb package
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-11-23 17:24:45 -06:00
Jeff Carr 3a6226ea53 work towards an override file 2024-11-22 22:29:52 -06:00
Jeff Carr fc9f8d89c0 crapnuts 2024-11-22 21:44:16 -06:00
Jeff Carr 7c75a266f4 try to rev release to 0.6 2024-11-22 20:50:55 -06:00
Jeff Carr b5d3072729 fix recursive logic 2024-11-17 16:04:08 -06:00
Jeff Carr c23cc60000 fix build 2024-11-16 00:07:22 -06:00
Jeff Carr 91356cd753 minor cleanups 2024-11-15 18:09:39 -06:00
Jeff Carr 2d84244036 argv logic handling was bungled
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-11-15 13:25:52 -06:00
Jeff Carr 28bf6a27f9 maybe right ldflags 2024-11-15 10:52:00 -06:00
Jeff Carr afb478c8c7 add build date. backup go.work file 2024-11-15 09:44:54 -06:00
Jeff Carr f8bef3081c add --auto-work option to generate go.work files 2024-11-15 09:29:49 -06:00
Jeff Carr bef6d6c911 realtime git clone. go.work paths work again 2024-11-15 09:11:11 -06:00
Jeff Carr dcf9f72264 migrate to the awesome go-cmd/cmd 2024-11-08 07:17:27 -06:00
Jeff Carr 9878b8fe6c use go-cmd/cmd 2024-11-08 06:45:25 -06:00
Jeff Carr 4cee81ca2d better wording 2024-11-07 16:53:53 -06:00
Jeff Carr 5abf602bf7 rename to 'argv'; use standard -ldflags 2024-11-07 07:03:51 -06:00
Jeff Carr d576aa8a25 better notes
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-11-07 04:59:54 -06:00
Jeff Carr e3aeae59e0 update docs
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-11-07 04:57:07 -06:00
Jeff Carr d7284f55c1 stdout message on success 2024-11-06 18:27:00 -06:00
12 changed files with 512 additions and 259 deletions

2
.gitignore vendored
View File

@ -3,4 +3,4 @@ go.mod
go.sum
/files/*
/work/*
go-clone
go-clone*

View File

@ -1,63 +1,81 @@
VERSION = $(shell git describe --tags)
BUILDTIME = $(shell date +%Y.%m.%d_%H%M)
run: build
@#./go-clone --work github.com/rclone/rclone
@# ./go-clone --work go.wit.com/apps/basicwindow
./go-clone --version
# test using --no-work against ~/go/src
homeGoSrc: build
-rm ~/go/src/go.work*
go clean -cache -modcache
-rm -rf ../basicwindow/
./go-clone --no-work go.wit.com/apps/basicwindow
modernc: build
./go-clone --no-work --recursive modernc.org/sqlite
run: install
go-clone --version
vet:
@GO111MODULE=off go vet
@echo this go library package builds okay
@echo this go binary package builds okay
no-gui: build
no-gui: install build-darwin build-windows
./go-clone --no-gui
build:
GO111MODULE=off go build -v -ldflags "-X main.Version=${VERSION} -X gui.GUIVERSION=${VERSION}"
build: goimports
GO111MODULE=off go build -v \
-ldflags "-X main.VERSION=${VERSION} -X main.BUILDTIME=${BUILDTIME} -X gui.GUIVERSION=${VERSION}"
build-go-1.21:
@#GO111MODULE=off /usr/lib/go-1.21/bin/go build -v -ldflags "-X main.VERSION=${VERSION}"
@# GO111MODULE=off /usr/lib/go-1.21/bin/go build -v -ldflags "-X main.Version=${VERSION} -X gui.GUIVERSION=${VERSION}"
@# GO111MODULE=off go build -v -ldflags "-X main.GUIVERSION=${VERSION}"
build-darwin:
GOOS=darwin GOARCH=amd64 GO111MODULE=off go build -v -o go-clone-darwin.x86 \
-ldflags "-X main.VERSION=${VERSION} -X main.BUILDTIME=${BUILDTIME} -X gui.GUIVERSION=${VERSION}"
install:
GO111MODULE="off" go install -v
build-darwin-arm64:
GOOS=darwin GOARCH=arm64 GO111MODULE=off go build -v -o go-clone-darwin.arm \
-ldflags "-X main.VERSION=${VERSION} -X main.BUILDTIME=${BUILDTIME} -X gui.GUIVERSION=${VERSION}"
build-windows:
GOOS=windows GOARCH=amd64 GO111MODULE=off go build -v -o go-clone.exe \
-ldflags "-X main.VERSION=v0.7.46 -X main.BUILDTIME=2025.02.22_0643 -X gui.GUIVERSION=v0.7.46"
install: goimports
GO111MODULE=off go install \
-ldflags "-X main.VERSION=${VERSION} -X main.BUILDTIME=${BUILDTIME} -X gui.GUIVERSION=${VERSION}"
goimports:
reset
goimports -w *.go
# // to globally reset paths:
# // gofmt -w -r "go.wit.com/gui -> go.wit.com/gui/gui" .
redomod:
rm -f go.*
GO111MODULE= go mod init
GO111MODULE= go mod tidy
go mod edit -go=1.20
reset:
# clear your terminal
reset
gocui: build
reset
gui-gocui: build
./go-clone --gui gocui >/tmp/witgui.log.stderr 2>&1
nocui: reset build
nocui: build
./go-clone --gui nocui
clean:
-rm go-clone
rm -f go.*
-rm go-clone*
go-mod-clean purge
# this will test the golang.org/x -> googlesource override
git-clone:
./go-clone --recursive --go-src --no-work go.wit.com/lib/daemons/virtigod
test-build: build
./go-clone --build go.wit.com/apps/guireleaser
test-install: build
./go-clone --install go.wit.com/apps/guireleaser
debian:
go-deb --no-gui --repo go.wit.com/apps/go-clone
pull: build
./go-clone --dry-run --pull
pullreal: build
./go-clone --pull
fetch: build
./go-clone --dry-run --fetch
modernc: build
./go-clone --no-work --recursive modernc.org/sqlite

View File

@ -1,9 +1,38 @@
# go-clone
5 years earlier, [gohack](https://github.com/rogpeppe/gohack) was written for the same reasons
this tool was written. gohack has a good justification for this kind of tool so here it is:
In 2018, [gohack](https://github.com/rogpeppe/gohack) was written for the same reasons
this tool was written. gohack has a good justification for this kind of tool.
## Install go-glone
## Gohack: mutable checkouts of Go module dependencies
go install go.wit.com/apps/go-clone@latest
## go-glone itself
This will download the sources for go-clone:
go-clone go.wit.com/apps/go-clone
go-clone works in ~/go/src unless it finds a go.work file in a parent dir
If you are using a go.work file, this will autocreate one. The old
one is saved as go.work.last
go-clone --auto-work go.wit.com/apps/go-clone
Or to recursively clone all the build dependancies:
go-clone --recursive go.wit.com/apps/go-clone
## debian packages
Debian packages are at mirrors.wit.com
## TODO:
* use protobuf
* move edge case mappings to a config file
* figure out how to detect gooogle.golang.org mapping with 'go list'
## these are notes from Gohack: mutable checkouts of Go module dependencies
The new Go module system is awesome. It ensures repeatable, deterministic
builds of Go code. External module code is cached locally in a read-only
@ -23,14 +52,3 @@ Luckily the modules system provides a way around this: you can add a
`replace` statement to the `go.mod` file which substitutes the contents
of a directory holding a module for the readonly cached copy. You can of
course do this manually, but gohack aims to make this process pain-free.
## Install go-glone
go install go.wit.com/apps/go-clone@latest
## go-glone itself
This will make a work directory and download everything needs to compile
go-clone.
go-clone --work go.wit.com/apps/go-clone

45
argv.go
View File

@ -1,32 +1,53 @@
package main
import (
"fmt"
"os"
)
/*
this parses the command line arguements
this enables command line options from other packages like 'gui' and 'log'
*/
var argv args
type args struct {
Repo string `arg:"positional" help:"go import path"`
NoWork bool `arg:"--no-work" default:"true" help:"do not make or modify the go.work file"`
GoSrc bool `arg:"--go-src" default:"true" help:"only work in ~/go/src"`
AutoWork bool `arg:"--work" default:"false" help:"recreate the go.work file"`
DryRun bool `arg:"--dry-run" help:"show what would be run"`
Recursive bool `arg:"--recursive" default:"false" help:"resursively clone all dependencies"`
Recursive bool `arg:"--recursive" default:"true" help:"recursively clone all dependencies"`
Build bool `arg:"--build" help:"try to build it after clone"`
Install bool `arg:"--install" help:"try to install it after clone"`
Ignore bool `arg:"--ignore" default:"false" help:"ignore weird clone errors from non-standard repos"`
// Fetch bool `arg:"--git-fetch" default:"false" help:"run 'git fetch' on all your repos"`
}
func (args) Version() string {
return "go-clone " + VERSION + " Built on " + BUILDTIME
}
func (a args) Description() string {
return `
By default, go-clone will find your go.work file and work from there.
Otherwise, it will create a work/ directory.
git clone go repositories recursively
This will clone the sources into ~/go/src/ for go-clone:
go-clone go.wit.com/apps/go-clone
This will recursively clone the app and all the build requirements:
go-clone --recursive go.wit.com/apps/go-clone
Examples:
go-clone go.wit.com/apps/go-clone # 'git clone' go-clone
`
}
func (args) Version() string {
return "go-clone " + Version
func (a args) DoAutoComplete(argv []string) {
switch argv[0] {
case "checkout":
fmt.Println("user devel master ")
case "--recursive":
fmt.Println("true false")
default:
if argv[0] == ARGNAME {
// list the subcommands here
fmt.Println("--dry-run --recursive --work")
}
}
os.Exit(0)
}

24
build.go Normal file
View File

@ -0,0 +1,24 @@
package main
import (
"os"
"go.wit.com/lib/gui/shell"
"go.wit.com/log"
)
func build() error {
err := forge.Build(workingRepo, nil)
pwd, _ := os.Getwd()
if err == nil {
log.Info("this totally worked", pwd)
shell.RunEcho([]string{"ls", "-l"})
log.Info("ran ls")
} else {
log.Info("this totally did not work", pwd)
shell.RunEcho([]string{"ls", "-l"})
log.Info("ran ls")
badExit(err)
}
return err
}

196
clone.go Normal file
View File

@ -0,0 +1,196 @@
package main
import (
"errors"
"fmt"
"os"
"path/filepath"
"strings"
"go.wit.com/lib/protobuf/gitpb"
"go.wit.com/log"
)
/*
# to support distributed 'git bug'
# create a new user:
git bug user new -e "jcarr@wit.com" -n "Jeff Carr"
git pull origin +refs/bugs/\*:refs/bugs/\*
git pull origin +refs/identities/\*:refs/identities/\*
git show-ref | grep refs/bugs/
git log refs/bugs/<some-id>
git config --add remote.origin.fetch '+refs/bugs/*:refs/bugs/*'
git config --add remote.origin.fetch '+refs/identities/*:refs/identities/*'
git config --get-all remote.origin.fetch
[remote "origin"]
url = ...
fetch = +refs/heads/*:refs/remotes/origin/*
fetch = +refs/bugs/*:refs/bugs/*
fetch = +refs/identities/*:refs/identities/*
# remove the caches
rm -rf .git/git-bug
# rebuild the cache with any command
git bug user
*/
// CleanRepoURL removes http://, https://, and .git suffix from the given URL if present.
func CleanRepoURL(url string) string {
// Trim protocol prefix
if strings.HasPrefix(url, "http://") {
url = strings.TrimPrefix(url, "http://")
} else if strings.HasPrefix(url, "https://") {
url = strings.TrimPrefix(url, "https://")
}
// Trim trailing .git
url = strings.TrimSuffix(url, ".git")
return url
}
func clone(gopath string) (*gitpb.Repo, error) {
// if the user defined a repo, attempt to download it now
if gopath == "" {
// nothing to clone
// user probably wants to --recursive on current working dir
return nil, errors.New("gopath was blank")
}
gopath = CleanRepoURL(gopath)
os.Setenv("REPO_AUTO_CLONE", "true")
// pb, _ := forge.NewGoPath(gopath)
check := forge.FindAnyPath(filepath.Join(forge.Config.ReposDir, gopath))
if check != nil {
if check.IsValidDir() {
// repo already exists and is valid
return check, nil
}
}
pb, err := forge.GoClone(gopath)
if err != nil {
log.Info("clone() could not download err:", err)
return nil, err
}
autoWork()
if err := makeValidGoSum(pb); err != nil {
return nil, err
}
log.Info("go-clone clone() onward and upward")
return pb, nil
}
// really only does go.sum things
// so not 'really' recursive
// but that is because go.sum is supposed
// to have everything required in it
func recursiveClone(check *gitpb.Repo) error {
var good int
var bad int
badmap := make(map[string]error)
if check == nil {
return errors.New("repo was nil")
}
log.Info("STARTING RECURSIVE CLONE", check.Namespace)
log.Info("STARTING RECURSIVE CLONE", check.Namespace)
// if just cloned, parse the go.sum file for deps
if check.ParseGoSum() {
} else {
makeValidGoSum(check)
}
check.ReloadForce()
if check.GoDeps == nil {
log.Info("repo godeps == nil", check.Namespace)
return errors.New("no go deps?")
}
// probably this should never be 0 because GoPrimitive should have been true otherwise
if check.GoDeps.Len() == 0 {
log.Info("repo len(godeps) == 0", check.Namespace)
return errors.New("go.sum never parsed?")
}
log.Info("deps for", check.Namespace, "len()", check.GoDeps.Len())
deps := check.GoDeps.SortByGoPath()
for deps.Scan() {
depRepo := deps.Next()
log.Info("download:", depRepo.GetGoPath())
_, err := clone(depRepo.GetGoPath())
if err != nil {
log.Info("recursiveClone() could not download", depRepo.GetGoPath())
log.Info("err:", err)
bad += 1
badmap[depRepo.GetGoPath()] = err
} else {
log.Info("downloaded", depRepo.GetGoPath())
good += 1
}
}
log.Info("got", good, "repos", "failed on", bad, "repos")
if bad != 0 {
log.Info("clone() ERROR len(badmap)", len(badmap))
for gopath, err := range badmap {
log.Info("clone() ERROR", gopath, err)
}
if !argv.Ignore {
return errors.New("clone failed on some repos")
}
}
return nil
}
func makeValidGoSum(check *gitpb.Repo) error {
// attempt to grab the notes
check.RunQuiet([]string{"git", "fetch", "origin", "refs/notes/*:refs/notes/*"})
if err := check.RunVerbose([]string{"forge", "list"}); err != nil {
log.Info("")
log.Info("Do you have go-mod-clean? Otherwise:")
log.Info(" go install go.wit.com/apps/go-mod-clean@latest")
log.Info("")
}
log.Info("try running go-mod-clean")
// update go.sum and go.mod
if err := check.RunVerbose([]string{"go-mod-clean", "lax"}); err != nil {
log.Info("")
log.Info("Do you have go-mod-clean? Otherwise:")
log.Info(" go install go.wit.com/apps/go-mod-clean@latest")
log.Info("")
}
if check.ParseGoSum() {
return nil
}
// if this fails, just use go mod
if err := check.ValidGoSum(); err != nil {
cmd := []string{"go", "mod", "init", check.Namespace}
log.Info("try running", cmd)
if _, err := check.RunQuiet(cmd); err != nil {
log.Info("go mod init failed", err)
}
if _, err := check.RunQuiet([]string{"go", "mod", "tidy"}); err != nil {
log.Info("go mod tidy failed", err)
}
}
if check.ParseGoSum() {
return nil
}
return fmt.Errorf("could not make a valid go.mod")
}

View File

@ -1,10 +1,8 @@
Source: go-clone
Build-Depends: golang
Build-Depends: golang, protoc-gen-go, autogenpb
Package: go-clone
Maintainer: Jeff Carr <jcarr@wit.com>
Architecture: amd64
Depends:
Recommends: go-clone
Description: git clones a go package and it's dependancies
does GO111MODULE=auto go get -v (more or less) only works on git
repositories. This is an experiment. GO should be used instead.
Description: 'git clone' the sources for a go project

208
main.go
View File

@ -1,171 +1,91 @@
package main
import (
"fmt"
"os"
"path/filepath"
"strings"
"go.wit.com/dev/alexflint/arg"
"go.wit.com/gui"
"go.wit.com/lib/gui/repolist"
"go.wit.com/lib/gui/repostatus"
"go.wit.com/lib/gui/shell"
"go.wit.com/lib/gui/prep"
"go.wit.com/lib/protobuf/forgepb"
"go.wit.com/lib/protobuf/gitpb"
"go.wit.com/log"
)
var Version string
// sent via -ldflags
var VERSION string
var BUILDTIME string
var rv *repolist.RepoList
var myargs args
var ARGNAME string = "go-clone"
var pp *arg.Parser
var forge *forgepb.Forge
var workingRepo *gitpb.Repo
func main() {
pp := arg.MustParse(&myargs)
log.Info("go-clone version", VERSION, "built on", BUILDTIME)
// command line parsing & handling
prep.Bash(ARGNAME, argv.DoAutoComplete) // todo: make this: prep.Bash(argv)
if myargs.Repo == "" {
pp.WriteHelp(os.Stdout)
os.Exit(0)
}
pp = arg.MustParse(&argv)
if myargs.Repo == "version" {
log.Info(Version)
os.Exit(0)
}
forge = forgepb.Init()
if myargs.Repo == "version" || myargs.Repo == "help" || myargs.Repo == "?" {
pp.WriteHelp(os.Stdout)
os.Exit(0)
}
// figures out where you're go.work file is
wdir, err := findWorkFile()
var err error
// attempt to clone, returns *gitpb.Repo
workingRepo, err = clone(argv.Repo)
if err != nil {
log.Info(err)
os.Exit(-1)
badExit(err)
}
log.Info("scanning directory:", wdir)
os.Setenv("REPO_WORK_PATH", wdir)
// readControlFile()
b := gui.RawBox()
rv = repolist.AutotypistView(b)
os.Setenv("REPO_AUTO_CLONE", "true")
newr, err := rv.NewRepo(myargs.Repo)
if err != nil {
log.Info("could not download:", err)
os.Exit(-1)
}
newr.Status.MakeRedomod()
// rv.NewRepo("go.wit.com/apps/helloworld")
for _, path := range repostatus.ScanGitDirectories(wdir) {
gopath := strings.TrimPrefix(path, wdir)
gopath = strings.Trim(gopath, "/")
// log.Info("Also should add:", gopath)
rv.NewRepo(gopath)
}
godep := newr.Status.GetGoDeps()
if myargs.Recursive {
for gopath, version := range godep {
repo, err := rv.NewRepo(gopath)
if err != nil {
log.Info("git clone failed for", gopath, version)
continue
}
repo.Status.MakeRedomod()
if argv.Recursive {
log.Info("STARTING RECURSIVE CLONE", workingRepo.GetGoPath())
if err := recursiveClone(workingRepo); err != nil {
badExit(err)
}
}
var count int
for _, repo := range rv.AllRepos() {
count += 1
if !repo.Status.Exists("go.mod") {
repo.Status.MakeRedomod()
}
}
log.Info("Total repositories:", count)
if !myargs.NoWork {
log.Info("Creating", wdir+"/go.work")
rv.MakeGoWork()
shell.RunPath(wdir, []string{"go", "work", "use"})
}
autoWork()
if argv.Build {
log.Info("STARTING BUILD", workingRepo.GetGoPath())
/*
for _, repo := range rv.AllRepos() {
log.Info("found repo", repo.GoPath(), repo.Status.Path())
if err := makeValidGoSum(workingRepo); err != nil {
badExit(err)
}
if err := build(); err != nil {
badExit(err)
}
*/
if workingRepo.GetRepoType() == "binary" || workingRepo.GetRepoType() == "plugin" {
log.Info("build will probably fail", workingRepo.GetGoPath(), "is", workingRepo.GetRepoType())
}
if err := forge.Build(workingRepo, nil); err != nil {
log.Warn("BUILD FAILED", workingRepo.GetGoPath(), err)
badExit(err)
}
}
if argv.Install {
log.Info("STARTING INSTALL", workingRepo.GetGoPath())
// can only install binary or plugin go packages
if workingRepo.GetRepoType() == "binary" || workingRepo.GetRepoType() == "plugin" {
log.Info("install will probably fail", workingRepo.GetGoPath(), "is", workingRepo.GetRepoType())
}
if err := forge.Install(workingRepo, nil); err != nil {
log.Warn("INSTALL FAILED", workingRepo.GetGoPath(), err)
badExit(err)
}
}
okExit("")
}
// look for or make a go.work file
// otherwise use ~/go/src
func findWorkFile() (string, error) {
if myargs.GoSrc {
// user put --go-src on the command line so use ~/go/src
return useGoSrc()
func okExit(thing string) {
if thing != "" {
log.Info(thing, "ok")
}
log.Info("Finished clone on", workingRepo.GetGoPath(), "ok")
forge.ConfigSave()
os.Exit(0)
}
pwd, err := os.Getwd()
if err == nil {
// Check for go.work in the current directory and then move up until root
if pwd, err := digup(pwd); err == nil {
// found an existing go.work file
os.Chdir(pwd)
return pwd, nil
}
// if the user added '--work' on the cmdline, make a work directory and init the go.work file
if ! myargs.NoWork {
pwd, err = os.Getwd()
newpwd := filepath.Join(pwd, "work")
shell.Mkdir(newpwd)
os.Chdir(newpwd)
if _, err := os.Stat("go.work"); err == nil {
return newpwd, nil
}
shell.RunPath(newpwd, []string{"go", "work", "init"})
if shell.Exists("go.work") {
return newpwd, nil
}
}
}
// there are no go.work files, resume the ~/go/src behavior from prior to golang 1.22
return useGoSrc()
}
// this is the 'old way" and works fine for me. I use it because I like the ~/go/src directory
// because I know exactly what is in it: GO stuff & nothing else
func useGoSrc() (string, error) {
homeDir, err := os.UserHomeDir()
if err != nil {
return "", err
}
pwd := filepath.Join(homeDir, "go/src")
shell.Mkdir(pwd)
os.Chdir(pwd)
return pwd, nil
}
func digup(path string) (string, error) {
for {
workFilePath := filepath.Join(path, "go.work")
if _, err := os.Stat(workFilePath); err == nil {
return path, nil // Found the go.work file
} else if !os.IsNotExist(err) {
return "", err // An error other than not existing
}
parentPath := filepath.Dir(path)
if parentPath == path {
break // Reached the filesystem root
}
path = parentPath
}
return "", fmt.Errorf("no go.work file found")
func badExit(err error) {
log.Info("Total repositories:", forge.Repos.Len())
log.Info("Finished go-clone with error", err, forge.Config.ReposDir)
os.Exit(-1)
}

View File

@ -1,49 +0,0 @@
package main
import (
"bufio"
"os"
"path/filepath"
"strings"
"go.wit.com/lib/gui/shell"
"go.wit.com/log"
)
func addDir(d string) {
if shell.IsDir(d) {
rv.NewRepo(d)
}
}
func readControlFile(path string) error {
fullname := filepath.Join(path, "go.work")
file, err := os.Open(fullname)
if err != nil {
return err
}
defer file.Close()
// pairs := make(map[string]string)
// var key string
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text()
line = strings.TrimSpace(line)
partsNew := strings.SplitN(line, ":", 2)
if len(partsNew) > 1 {
continue
}
log.Info(line)
addDir(line)
}
if err := scanner.Err(); err != nil {
return err
}
return nil
}

30
resources/overrides Normal file
View File

@ -0,0 +1,30 @@
# sometimes things go wrong temporarily. work around those here
case "golang.org/x/crypto":
return cloneActual(dirname, basedir, "https://" + "go.googlesource.com/crypto")
case "golang.org/x/mod":
return cloneActual(dirname, basedir, "https://" + "go.googlesource.com/mod")
case "golang.org/x/net":
return cloneActual(dirname, basedir, "https://" + "go.googlesource.com/net")
case "golang.org/x/sys":
return cloneActual(dirname, basedir, "https://" + "go.googlesource.com/sys")
case "golang.org/x/sync":
return cloneActual(dirname, basedir, "https://" + "go.googlesource.com/sync")
case "golang.org/x/term":
return cloneActual(dirname, basedir, "https://" + "go.googlesource.com/term")
case "golang.org/x/text":
return cloneActual(dirname, basedir, "https://" + "go.googlesource.com/text")
case "golang.org/x/tools":
return cloneActual(dirname, basedir, "https://" + "go.googlesource.com/tools")
case "golang.org/x/xerrors":
return cloneActual(dirname, basedir, "https://" + "go.googlesource.com/xerrors")
case "google.golang.org/protobuf":
return cloneActual(dirname, basedir, "https://" + "go.googlesource.com/protobuf")
case "google.golang.org/genproto":
return cloneActual(dirname, basedir, "https://" + "go.googlesource.com/genproto")
case "google.golang.org/api":
return cloneActual(dirname, basedir, "https://" + "go.googlesource.com/api")
case "google.golang.org/grpc":
return cloneActual(dirname, basedir, "https://" + "go.googlesource.com/grpc")
case "google.golang.org/appengine":
return cloneActual(dirname, basedir, "https://" + "go.googlesource.com/appengine")

57
stdin.go Normal file
View File

@ -0,0 +1,57 @@
package main
import (
"bufio"
"errors"
"fmt"
"os"
"strings"
"go.wit.com/log"
)
func showOptions(b bool, s []string) {
fmt.Println("")
for _, line := range s {
fmt.Println(line)
}
fmt.Println("")
if b {
fmt.Println("Enter (Y/n)")
} else {
fmt.Println("Enter (y/N)")
}
}
// if b == true, default is to continue with 'Y'
func simpleStdin(b bool, s []string) {
/*
if argv.Auto {
return
}
*/
err := errors.New("user cancelled via stdin")
showOptions(b, s)
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
s := scanner.Text()
s = strings.TrimSpace(s)
s = strings.ToLower(s)
switch s {
case "y":
log.Info("got y")
return
case "n":
log.Info("got n")
badExit(err)
case "":
if b {
return
} else {
badExit(err)
}
default:
badExit(err)
}
}
}

20
work.go Normal file
View File

@ -0,0 +1,20 @@
package main
import (
"go.wit.com/lib/gui/shell"
"go.wit.com/log"
)
func autoWork() {
// remake the go.work file
if !argv.AutoWork {
return
}
log.Info("About to re-create", forge.Config.ReposDir+"/go.work")
shell.PathRun(forge.Config.ReposDir, []string{"mv", "go.work", "go.work.last"})
forge.MakeGoWork()
shell.PathRun(forge.Config.ReposDir, []string{"go", "work", "use"})
log.Info("")
log.Info("original go.work file saved as go.work.last")
log.Info("")
}