diff --git a/config.go b/config.go index fe70446..2fe52f6 100644 --- a/config.go +++ b/config.go @@ -139,6 +139,16 @@ func configWrite(filename string, data []byte) error { log.Warn("open config file :", err) return err } + if filename == "forge.text" { + // add header + cfgfile.Write([]byte("# this file is automatically re-generated from forge.pb, however,\n")) + cfgfile.Write([]byte("# if you want to edit it by hand, you can:\n")) + cfgfile.Write([]byte("# stop forge; remove forge.pb; edit forge.text; start forge\n")) + cfgfile.Write([]byte("# this will cause the default behavior to fallback to parsing this file for the config\n")) + cfgfile.Write([]byte("\n")) + cfgfile.Write([]byte("# this file is intended to be used to customize settings on what\n")) + cfgfile.Write([]byte("# git repos you have write access to. That is, where you can run 'git push'\n")) + } cfgfile.Write(data) return nil } diff --git a/forgeConfig/Makefile b/forgeConfig/Makefile index 942ee78..ddf8079 100644 --- a/forgeConfig/Makefile +++ b/forgeConfig/Makefile @@ -7,6 +7,15 @@ build: ./forgeConfig FORGE_HOME=/tmp/forge ./forgeConfig +test: + ./forgeConfig --list + ./forgeConfig --add --gopath 'go.wit.com/apps/foo' + ./forgeConfig --add --gopath 'go.wit.com/apps/foowrite' --writable + ./forgeConfig --add --gopath 'gitea.wit.com' --directory + ./forgeConfig --add --gopath 'git.wit.org' --directory + ./forgeConfig --delete --gopath 'go.wit.com/apps/helloworld' + ./forgeConfig --list + list: ./forgeConfig --list diff --git a/forgeConfig/argv.go b/forgeConfig/argv.go index 9081e9e..6493284 100644 --- a/forgeConfig/argv.go +++ b/forgeConfig/argv.go @@ -12,8 +12,11 @@ type args struct { ConfigDir string `arg:"env:FORGE_HOME" help:"defaults to ~/.config/forge/"` List bool `arg:"--list" default:"false" help:"list repos in your config"` Add bool `arg:"--add" default:"false" help:"add a new repo"` + Delete bool `arg:"--delete" default:"false" help:"delete a repo"` Update bool `arg:"--update" default:"false" help:"update a repo"` - Name string `arg:"--name" help:"name of the repo"` + Directory bool `arg:"--directory" default:"false" help:"repo is a directory to match against"` + ReadOnly bool `arg:"--readonly" default:"false" help:"repo is readonly"` + Writable bool `arg:"--writable" default:"false" help:"repo is writable"` GoPath string `arg:"--gopath" help:"gopath of the repo"` } diff --git a/forgeConfig/main.go b/forgeConfig/main.go index 434f222..237698c 100644 --- a/forgeConfig/main.go +++ b/forgeConfig/main.go @@ -26,6 +26,19 @@ func main() { } os.Exit(0) } + + // try to delete, then save config and exit + if argv.Delete { + if oldr := repos.DeleteByPath(argv.GoPath); oldr == nil { + log.Info("deleted", argv.GoPath, "did not exist. did nothing") + os.Exit(0) + } + log.Info("deleted", argv.GoPath, "ok") + repos.ConfigSave() + os.Exit(0) + } + + // try to update, then save config and exit if argv.Update { /* if repos.UpdateGoPath(argv.Name, argv.GoPath) { @@ -35,10 +48,15 @@ func main() { */ os.Exit(0) } + + // try to add, then save config and exit if argv.Add { log.Info("going to add a new repo", argv.GoPath) new1 := new(forgepb.Repo) new1.GoPath = argv.GoPath + new1.Writable = argv.Writable + new1.ReadOnly = argv.ReadOnly + new1.Directory = argv.Directory if repos.Append(new1) { log.Info("added", new1.GoPath, "ok") } else { diff --git a/update.go b/update.go index 8dce1a0..8743ee1 100644 --- a/update.go +++ b/update.go @@ -1,5 +1,7 @@ package forgepb +import "strings" + func (all *Repos) UpdateGoPath(name string, gopath string) bool { oldr := all.DeleteByPath(name) if oldr == nil { @@ -11,3 +13,79 @@ func (all *Repos) UpdateGoPath(name string, gopath string) bool { oldr.GoPath = gopath return all.Append(oldr) } + +// returns true if gopath is readonly() +func (all *Repos) ReadOnly(gopath string) bool { + var match *Repo + + loop := all.SortByPath() // get the list of repos + for loop.Scan() { + r := loop.Repo() + 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 + } + } + // search for potential dir matches + if r.Directory { + // test the dir + if strings.HasPrefix(gopath, r.GoPath) { + match = r + } + } + } + + // 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 +} + +// is this a non-publishable repo? +func (all *Repos) Private(gopath string) bool { + var match *Repo + + loop := all.SortByPath() // get the list of repos + for loop.Scan() { + r := loop.Repo() + if r.GoPath == gopath { + // if private is set here, then ok, otherwise + // still check if a Directory match exists + if r.Private { + return true + } + } + // search for potential dir matches + if r.Directory { + // test the dir + if strings.HasPrefix(gopath, r.GoPath) { + match = r + } + } + } + + if match.Private { + return true + } + + // otherwise, assume not private + return true +}