From f98179971e574de202c582576e59a8e3da68530f Mon Sep 17 00:00:00 2001 From: Jeff Carr Date: Wed, 4 Dec 2024 15:36:49 -0600 Subject: this .proto might allow generic marshal recovery --- Makefile | 5 +- configLookup.go | 229 +++++++++++++++++++++++++++++++++++++++++++++++++++++ finalGoSumCheck.go | 4 +- forgeConfig.proto | 3 +- human.go | 4 +- repoClone.go | 65 --------------- repoSettings.go | 209 ------------------------------------------------ uuid.proto | 10 +++ 8 files changed, 249 insertions(+), 280 deletions(-) create mode 100644 configLookup.go delete mode 100644 repoSettings.go create mode 100644 uuid.proto diff --git a/Makefile b/Makefile index ee2b4ed..42d1a03 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ # go install -all: forgeConfig.pb.go vet +all: goimports forgeConfig.pb.go uuid.pb.go vet vet: @GO111MODULE=off go vet @@ -27,3 +27,6 @@ clean: forgeConfig.pb.go: forgeConfig.proto autogenpb --proto forgeConfig.proto + +uuid.pb.go: uuid.proto + autogenpb --proto uuid.proto diff --git a/configLookup.go b/configLookup.go new file mode 100644 index 0000000..cda036e --- /dev/null +++ b/configLookup.go @@ -0,0 +1,229 @@ +package forgepb + +/* + lookup settings for a particular *gitpb.Repo or gopath string + + user settings are configured in ~/.config/forge/forge.text + + // searchs by string + Configs.IsReadOnly(path) // user can't push commits + Configs.IsWritable(path) // the opposite, but maybe different so I put both here + + IsPrivate(repo) // repo can't be published to the pkg.go.dev system + DebName() // for 'zookeeper' returns 'zookeeper-go' +*/ + +import ( + "path/filepath" + "strings" +) + +/* +func (all *ForgeConfigs) UpdateGoPath(name string, gopath string) bool { + oldr := all.DeleteByGoPath(name) + if oldr == nil { + // nothing to update + return false + } + + // update gopath and append it back to the list + oldr.GoPath = gopath + return all.Append(oldr) +} +*/ + +// returns true if gopath is readonly() +// will attempt to match IsWritable("foo") against anything ending in "foo" +func (fc *ForgeConfigs) IsReadOnly(gopath string) bool { + var match *ForgeConfig + + loop := fc.SortByGoPath() // get the list of repos + for loop.Scan() { + r := loop.Next() + if r.GoPath == gopath { + // exact gopath match + if r.Writable { + return false + } + if r.ReadOnly { + return true + } + // private is assumed to be r/w unless above is specifically set + if r.Private { + return false + } + } + // if gopath == "foo" will return false if "go.wit.com/apps/foo" is Writable + base := filepath.Base(r.GoPath) + if base == gopath { + if r.Writable { + return false + } + } + // search for potential dir matches + if r.Directory { + // test the dir + if strings.HasPrefix(gopath, r.GoPath) { + match = r + } + } + } + + if match == nil { + // log.Info("did not match in IsReadOnly()", gopath) + return true + } + + // take the settings from the directory match + if match.Writable { + return false + } + if match.ReadOnly { + return true + } + // private is assumed to be r/w unless above is specifically set + if match.Private { + return false + } + + // always assume readonly + return true +} + +// returns the deb package name +// this let's you check a git tag version against a package .deb version +// allows gopath's to not need to match the .deb name +// this is important in lots of cases! It is normal and happens often enough. +func (fc *ForgeConfigs) DebName(gopath string) string { + // get "zookeeper" from "go.wit.com/apps/zookeeper" + normalBase := filepath.Base(gopath) + + loop := fc.SortByGoPath() + for loop.Scan() { + r := loop.Next() + if r.GoPath == gopath { + // returns "zookeeper-go" for "go.wit.com/apps/zookeeper" + if r.DebName != "" { + // log.Info("FOUND DebName", r.DebName) + return r.DebName + } else { + return normalBase + } + } + } + return normalBase +} + +// is this a non-publishable repo? +// matches package names from apt +// +// IsPrivate("foo") will match anything in the config file ending in "foo" +// +// IsPrivate("go.foo.com/jcarr/foo") returns true if private +// IsPrivate("foo") also returns true if "go.bar.com/jcarr/foo" is private +func (fc *ForgeConfigs) IsPrivate(thing string) bool { + var match *ForgeConfig + + // sort by path means the simple 'match' logic + // here works in the sense the last directory match + // is the one that is used + loop := fc.SortByGoPath() // get the list of repos + for loop.Scan() { + r := loop.Next() + if r.GoPath == thing { + // if private is set here, then ok, otherwise + // still check if a Directory match exists + if r.Private { + return true + } + } + base := filepath.Base(r.GoPath) + if base == thing { + if r.Private { + return true + } + } + // check to see if IsPrivate("foo") + // search for potential dir matches + if r.Directory { + // test the dir + if strings.HasPrefix(thing, r.GoPath) { + match = r + } + } + } + if match == nil { + // log.Info("did not match in IsPrivate()", thing) + return false + } + + // otherwise, assume not private + return match.Private +} + +// IsFavorite() -- fun option for the config +// file that lets you set things as favorites +// so you can just go-clone a bunch of common things +// on a new box or after you reset/delete your ~/go/src dir +func (fc *ForgeConfigs) IsFavorite(thing string) bool { + var match *ForgeConfig + + loop := fc.SortByGoPath() // get the list of repos + for loop.Scan() { + r := loop.Next() + if r.GoPath == thing { + if r.Favorite { + return true + } + } + base := filepath.Base(r.GoPath) + if base == thing { + if r.Favorite { + return true + } + } + if r.Directory { + if strings.HasPrefix(thing, r.GoPath) { + match = r + } + } + } + if match == nil { + return false + } + + return match.Favorite +} + +// IsWritable() checks your .config/forge/ settings +// looks for an exact match, then +// looks for a directory match +func (fc *ForgeConfigs) IsWritable(thing string) bool { + var match *ForgeConfig + + loop := fc.SortByGoPath() // get the list of repos + for loop.Scan() { + r := loop.Next() + if r.GoPath == thing { + if r.Writable { + return true + } + } + base := filepath.Base(r.GoPath) + if base == thing { + if r.Writable { + return true + } + } + if r.Directory { + if strings.HasPrefix(thing, r.GoPath) { + match = r + } + } + } + if match == nil { + return false + } + + return match.Writable +} diff --git a/finalGoSumCheck.go b/finalGoSumCheck.go index b905c78..22618eb 100644 --- a/finalGoSumCheck.go +++ b/finalGoSumCheck.go @@ -20,7 +20,7 @@ func (f *Forge) FinalGoDepsCheckOk(check *gitpb.Repo) bool { log.Info("boo, check == nil") return false } - if ! check.Exists("go.mod") { + if !check.Exists("go.mod") { log.Info("go.mod is missing in", check.GoPath) return false } @@ -58,7 +58,7 @@ func (f *Forge) FinalGoDepsCheckOk(check *gitpb.Repo) bool { // log.Info("found dep", depRepo.GetGoPath()) if depRepo.GetVersion() != found.GetTargetVersion() { check := f.Repos.FindByGoPath(depRepo.GoPath) - if f.IsReadOnly(check) { + if f.Config.IsReadOnly(check.GoPath) { log.Printf("%-48s ok error .%s. vs .%s. (ignoring read-only repo)", depRepo.GetGoPath(), depRepo.GetVersion(), found.GetTargetVersion()) } else { if f.checkOverride(depRepo.GetGoPath()) { diff --git a/forgeConfig.proto b/forgeConfig.proto index 36230a5..de60159 100644 --- a/forgeConfig.proto +++ b/forgeConfig.proto @@ -4,6 +4,8 @@ package forgepb; import "google/protobuf/timestamp.proto"; // Import the well-known type for Timestamp +// `autogenpb:uuid:7267f5d5-954b-44b7-9f67-2eb808791355` // todo: add file support + // define 3 branches. that is all that is supported // the term 'master' is used in the code because 'main' is a reserved word in golang already // allow 'read only' and 'private' flags @@ -31,7 +33,6 @@ message ForgeConfig { google.protobuf.Timestamp verstamp = 12; // the git commit timestamp of the version } -// TODO: autogen 'sort', 'marshal' message ForgeConfigs { // `autogenpb:marshal` string uuid = 1; // could be useful for /usr/share/file/magic someday? string version = 2; // could be used for protobuf schema change violations? diff --git a/human.go b/human.go index 6685b48..82ad766 100644 --- a/human.go +++ b/human.go @@ -23,10 +23,10 @@ func standardHeader() string { func (f *Forge) standardHeader(r *ForgeConfig) string { var flags string var readonly string - if f.IsPrivate(r.GoPath) { + if f.Config.IsPrivate(r.GoPath) { flags += "(private) " } - if f.IsFavorite(r.GoPath) { + if f.Config.IsFavorite(r.GoPath) { flags += "(favorite) " } if f.Config.IsReadOnly(r.GoPath) { diff --git a/repoClone.go b/repoClone.go index 1c1ffa0..2afc6fa 100644 --- a/repoClone.go +++ b/repoClone.go @@ -13,71 +13,6 @@ import ( "go.wit.com/log" ) -/* -// guess the paths. returns - -// realpath : the actual path on the filesystem -// goSrcPath : this could be ~/go/src, or where the go.work file is - -// goPath : go.wit.com/lib/gui/repostatus (for example) -// true/false if the repo is a golang repo -func (f *Forge) guessPaths(path string) (string, string, string, bool, error) { - var realpath, goSrcDir string - var isGoLang bool = false - - homeDir, err := os.UserHomeDir() - if err != nil { - log.Log(FORGEPBWARN, "Error getting home directory:", err) - return path, realpath, goSrcDir, false, err - } - goSrcDir = filepath.Join(homeDir, "go/src") - - // allow arbitrary paths, otherwise, assume the repo is in ~/go/src - // unless REPO_WORK_PATH was set. to over-ride ~/go/src - // todo, look for go.work - if os.Getenv("REPO_WORK_PATH") == "" { - os.Setenv("REPO_WORK_PATH", goSrcDir) - } else { - goSrcDir = os.Getenv("REPO_WORK_PATH") - } - - // todo: this is dumb - if strings.HasPrefix(path, "/") { - realpath = path - } else if strings.HasPrefix(path, "~") { - tmp := strings.TrimPrefix(path, "~") - realpath = filepath.Join(homeDir, tmp) - } else { - realpath = filepath.Join(goSrcDir, path) - isGoLang = true - } - - if os.Getenv("REPO_AUTO_CLONE") == "true" { - err := f.Clone(goSrcDir, path) - if err != nil { - // directory doesn't exist. exit with nil and error nil - return path, realpath, goSrcDir, false, errors.New("git clone") - } - } - - if !IsDirectory(realpath) { - log.Log(FORGEPBWARN, "directory doesn't exist", realpath) - // directory doesn't exist. exit with nil and error nil - return path, realpath, goSrcDir, false, errors.New(realpath + " does not exist") - } - - filename := filepath.Join(realpath, ".git/config") - - _, err = os.Open(filename) - if err != nil { - // log.Log(WARN, "Error reading .git/config:", filename, err) - // log.Log(WARN, "TODO: find .git/config in parent directory") - return path, realpath, goSrcDir, false, err - } - return path, realpath, goSrcDir, isGoLang, nil -} -*/ - // TODO: make some config file for things like this // can be used to work around temporary problems func clonePathHack(dirname string, basedir string, gopath string) (string, error) { diff --git a/repoSettings.go b/repoSettings.go deleted file mode 100644 index 128d1a1..0000000 --- a/repoSettings.go +++ /dev/null @@ -1,209 +0,0 @@ -package forgepb - -/* - check settings for a particular gopath - this provides checks for: - - IsReadOnly() // user can't push commits - IsPrivate() // repo can't be published to the pkg.go.dev system - DebName() // for 'zookeeper' returns 'zookeeper-go' -*/ - -import ( - "path/filepath" - "strings" - - "go.wit.com/lib/protobuf/gitpb" -) - -/* -func (f *Forge) SortByGoPath() *ForgeConfigIterator { - return f.Config.SortByPath() -} -*/ - -/* -func (all *ForgeConfigs) UpdateGoPath(name string, gopath string) bool { - oldr := all.DeleteByGoPath(name) - if oldr == nil { - // nothing to update - return false - } - - // update gopath and append it back to the list - oldr.GoPath = gopath - return all.Append(oldr) -} -*/ - -// returns true if gopath is readonly() -// will attempt to match IsWritable("foo") against anything ending in "foo" -func (f *Forge) IsReadOnly(repo *gitpb.Repo) bool { - // var match *ForgeConfig - - return f.Config.IsReadOnly(repo.GoPath) -} - -// returns true if gopath is readonly() -// will attempt to match IsWritable("foo") against anything ending in "foo" -func (f *ForgeConfigs) IsReadOnly(gopath string) bool { - var match *ForgeConfig - - - loop := f.SortByGoPath() // get the list of repos - for loop.Scan() { - r := loop.Next() - if r.GoPath == gopath { - // exact gopath match - if r.Writable { - return false - } - if r.ReadOnly { - return true - } - // private is assumed to be r/w unless above is specifically set - if r.Private { - return false - } - } - // if gopath == "foo" will return false if "go.wit.com/apps/foo" is Writable - base := filepath.Base(r.GoPath) - if base == gopath { - if r.Writable { - return false - } - } - // search for potential dir matches - if r.Directory { - // test the dir - if strings.HasPrefix(gopath, r.GoPath) { - match = r - } - } - } - - if match == nil { - // log.Info("did not match in IsReadOnly()", gopath) - return true - } - - // take the settings from the directory match - if match.Writable { - return false - } - if match.ReadOnly { - return true - } - // private is assumed to be r/w unless above is specifically set - if match.Private { - return false - } - - // always assume readonly - return true -} - -// returns the deb package name -// this let's you check a git tag version against a package .deb version -// allows gopath's to not need to match the .deb name -// this is important in lots of cases! It is normal and happens often enough. -func (f *Forge) DebName(gopath string) string { - // get "zookeeper" from "go.wit.com/apps/zookeeper" - normalBase := filepath.Base(gopath) - - loop := f.Config.SortByGoPath() - for loop.Scan() { - r := loop.Next() - if r.GoPath == gopath { - // returns "zookeeper-go" for "go.wit.com/apps/zookeeper" - if r.DebName != "" { - // log.Info("FOUND DebName", r.DebName) - return r.DebName - } else { - return normalBase - } - } - } - return normalBase -} - -// is this a non-publishable repo? -// matches package names from apt -// -// IsPrivate("foo") will match anything in the config file ending in "foo" -// -// IsPrivate("go.foo.com/jcarr/foo") returns true if private -// IsPrivate("foo") also returns true if "go.bar.com/jcarr/foo" is private -func (f *Forge) IsPrivate(thing string) bool { - var match *ForgeConfig - - // sort by path means the simple 'match' logic - // here works in the sense the last directory match - // is the one that is used - loop := f.Config.SortByGoPath() // get the list of repos - for loop.Scan() { - r := loop.Next() - if r.GoPath == thing { - // if private is set here, then ok, otherwise - // still check if a Directory match exists - if r.Private { - return true - } - } - base := filepath.Base(r.GoPath) - if base == thing { - if r.Private { - return true - } - } - // check to see if IsPrivate("foo") - // search for potential dir matches - if r.Directory { - // test the dir - if strings.HasPrefix(thing, r.GoPath) { - match = r - } - } - } - if match == nil { - // log.Info("did not match in IsPrivate()", thing) - return false - } - - // otherwise, assume not private - return match.Private -} - -// IsFavorite() -- fun option for the config -// file that lets you set things as favorites -// so you can just go-clone a bunch of common things -// on a new box or after you reset/delete your ~/go/src dir -func (f *Forge) IsFavorite(thing string) bool { - var match *ForgeConfig - - loop := f.Config.SortByGoPath() // get the list of repos - for loop.Scan() { - r := loop.Next() - if r.GoPath == thing { - if r.Favorite { - return true - } - } - base := filepath.Base(r.GoPath) - if base == thing { - if r.Favorite { - return true - } - } - if r.Directory { - if strings.HasPrefix(thing, r.GoPath) { - match = r - } - } - } - if match == nil { - return false - } - - return match.Favorite -} diff --git a/uuid.proto b/uuid.proto new file mode 100644 index 0000000..e58ca12 --- /dev/null +++ b/uuid.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + +// experiment to identify .pb files incase things go sideways +package forgepb; + +// autogenpb:no-sort +message UuidConfigs { // `autogenpb:marshal` + string uuid = 1; // could be useful for /usr/share/file/magic someday? + string version = 2; // could be used for protobuf schema change violations? +} -- cgit v1.2.3