Compare commits
No commits in common. "master" and "v0.0.63" have entirely different histories.
|
@ -1,5 +1,4 @@
|
||||||
*.swp
|
*.swp
|
||||||
*.patch
|
|
||||||
|
|
||||||
go.*
|
go.*
|
||||||
*.pb.go
|
*.pb.go
|
||||||
|
|
35
Makefile
35
Makefile
|
@ -19,10 +19,10 @@ vet:
|
||||||
goimports:
|
goimports:
|
||||||
goimports -w *.go
|
goimports -w *.go
|
||||||
|
|
||||||
# dump autogenerated files and potential patches
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.pb.go go.* *.patch
|
rm -f *.pb.go
|
||||||
go-mod-clean purge
|
-rm -f go.*
|
||||||
|
go-mod-clean --purge
|
||||||
|
|
||||||
#refs.pb.go: refs.proto
|
#refs.pb.go: refs.proto
|
||||||
# cd ~/go/src && protoc --go_out=. --proto_path=go.wit.com/lib/protobuf/gitpb \
|
# cd ~/go/src && protoc --go_out=. --proto_path=go.wit.com/lib/protobuf/gitpb \
|
||||||
|
@ -37,32 +37,3 @@ goDep.pb.go: goDep.proto
|
||||||
|
|
||||||
repo.pb.go: repo.proto
|
repo.pb.go: repo.proto
|
||||||
autogenpb --proto repo.proto
|
autogenpb --proto repo.proto
|
||||||
|
|
||||||
protoc-bad:
|
|
||||||
cd ~/go/src && protoc \
|
|
||||||
--proto_path=. \
|
|
||||||
--proto_path=go.wit.com/lib/protobuf/gitpb \
|
|
||||||
--go_out=. \
|
|
||||||
--go_opt=Mgo.wit.com/lib/protobuf/gitpb/repo.proto=go.wit.com/lib/protobuf/gitpb \
|
|
||||||
--go_opt=MgitTag.proto=go.wit.com/lib/protobuf/gitpb \
|
|
||||||
--go_opt=MgoDep.proto=go.wit.com/lib/protobuf/gitpb \
|
|
||||||
go.wit.com/lib/protobuf/gitpb/repo.proto
|
|
||||||
|
|
||||||
protoc-good:
|
|
||||||
cd ~/go/src && protoc \
|
|
||||||
--proto_path=. \
|
|
||||||
--go_out=go.wit.com/lib/protobuf/gitpb \
|
|
||||||
--go_opt=Mrepo.proto=go.wit.com/lib/protobuf/gitpb \
|
|
||||||
--go_opt=MgitTag.proto=go.wit.com/lib/protobuf/gitpb \
|
|
||||||
--go_opt=MgoDep.proto=go.wit.com/lib/protobuf/gitpb \
|
|
||||||
go.wit.com/lib/protobuf/gitpb/repo.proto
|
|
||||||
|
|
||||||
protoc-todo-move-to-this:
|
|
||||||
# I think I should seperate these dirs. ONLY ONE .proto FILE PER DIRECTORY
|
|
||||||
# - httppb.HttpRequest httpRequest = 4; // correct syntax
|
|
||||||
protoc \
|
|
||||||
--proto_path=. \
|
|
||||||
--go_out=. \
|
|
||||||
--go_opt=Mgo.wit.com/lib/protobuf/forgepb/patchset.proto=go.wit.com/lib/protobuf/forgepb \
|
|
||||||
--go_opt=Mgo.wit.com/lib/protobuf/httppb/httpRequest.proto=go.wit.com/lib/protobuf/httppb \
|
|
||||||
go.wit.com/lib/protobuf/forgepb/patchset.proto
|
|
||||||
|
|
10
autogen.go
10
autogen.go
|
@ -19,11 +19,11 @@ import (
|
||||||
func (repo *Repo) AutogenSave(files []string, refname string, del bool) error {
|
func (repo *Repo) AutogenSave(files []string, refname string, del bool) error {
|
||||||
if del {
|
if del {
|
||||||
cmd := []string{"git", "notes", "show", refname}
|
cmd := []string{"git", "notes", "show", refname}
|
||||||
if _, err := repo.RunQuiet(cmd); err != nil {
|
if err := repo.StrictRun(cmd); err != nil {
|
||||||
// if there are not any notes, no need to remove them
|
// if there are not any notes, no need to remove them
|
||||||
} else {
|
} else {
|
||||||
cmd := []string{"git", "notes", "remove", refname}
|
cmd := []string{"git", "notes", "remove", refname}
|
||||||
if _, err := repo.RunQuiet(cmd); err != nil {
|
if err := repo.StrictRun(cmd); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,18 +31,18 @@ func (repo *Repo) AutogenSave(files []string, refname string, del bool) error {
|
||||||
for _, fname := range files {
|
for _, fname := range files {
|
||||||
autotag := "// `autogen:" + fname + "`"
|
autotag := "// `autogen:" + fname + "`"
|
||||||
cmd := []string{"git", "notes", "append", "-m", autotag, refname}
|
cmd := []string{"git", "notes", "append", "-m", autotag, refname}
|
||||||
if _, err := repo.RunQuiet(cmd); err != nil {
|
if err := repo.StrictRun(cmd); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
cmd = []string{"git", "notes", "append", "-F", fname, refname}
|
cmd = []string{"git", "notes", "append", "-F", fname, refname}
|
||||||
if _, err := repo.RunQuiet(cmd); err != nil {
|
if err := repo.StrictRun(cmd); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// a tag with a blank name indicates the end of the autogen file or files
|
// a tag with a blank name indicates the end of the autogen file or files
|
||||||
autotag := "// `autogen:`"
|
autotag := "// `autogen:`"
|
||||||
cmd := []string{"git", "notes", "append", "-m", autotag, refname}
|
cmd := []string{"git", "notes", "append", "-m", autotag, refname}
|
||||||
if _, err := repo.RunQuiet(cmd); err != nil {
|
if err := repo.StrictRun(cmd); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
123
branches.go
123
branches.go
|
@ -1,123 +0,0 @@
|
||||||
package gitpb
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/go-cmd/cmd"
|
|
||||||
)
|
|
||||||
|
|
||||||
// returns true if 'git pull' will work
|
|
||||||
func (repo *Repo) ExistsUserBranchRemote() bool {
|
|
||||||
branchname := repo.GetUserBranchName()
|
|
||||||
if repo.IsBranchRemote(branchname) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func readRefHash(filename string) string {
|
|
||||||
data, _ := os.ReadFile(filename)
|
|
||||||
return string(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (repo *Repo) GetLocalBranches() []string {
|
|
||||||
return ListFiles(filepath.Join(repo.GetFullPath(), "/.git/refs/heads"))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (repo *Repo) GetRemoteBranches() []string {
|
|
||||||
remotes := ListFiles(filepath.Join(repo.GetFullPath(), "/.git/refs/remotes"))
|
|
||||||
return remotes
|
|
||||||
}
|
|
||||||
|
|
||||||
// git describe --tags e548b0fb6d0d14cdfb693850d592419f247dc2b1
|
|
||||||
// v0.22.61-15-gbab84d7
|
|
||||||
func (repo *Repo) GetHashName(h string) (string, error) {
|
|
||||||
h = strings.TrimSpace(h)
|
|
||||||
// log.Info("GetHashName() is looking for", repo.GetGoPath(), h)
|
|
||||||
cmd := []string{"git", "describe", "--tags", h}
|
|
||||||
r, err := repo.RunQuiet(cmd)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
if len(r.Stdout) == 0 {
|
|
||||||
return "", errors.New("git describe was empty")
|
|
||||||
}
|
|
||||||
return r.Stdout[0], nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// lookup a hash from a tag with 'git rev-list'
|
|
||||||
func (repo *Repo) GetTagHash(t string) string {
|
|
||||||
// git rev-list -n 1 v0.0.66
|
|
||||||
cmd := []string{"git", "rev-list", "-n", "1", t}
|
|
||||||
result, _ := repo.RunStrict(cmd)
|
|
||||||
// log.Info("getLastTagVersion()", result.Stdout)
|
|
||||||
|
|
||||||
if len(result.Stdout) == 0 {
|
|
||||||
// log.Log(WARN, "no gitpb.LastTag() repo is broken. ignore this.", repo.GetGoPath())
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
return result.Stdout[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
// lookup a hash from a tag with 'git rev-list'
|
|
||||||
func (repo *Repo) GetBranchDifferences(to string, from string) []string {
|
|
||||||
// git rev-list -n 1 v0.0.66
|
|
||||||
cmd := []string{"git", "rev-list", to + "..." + from}
|
|
||||||
result, _ := repo.RunStrict(cmd)
|
|
||||||
// log.Info("getLastTagVersion()", result.Stdout)
|
|
||||||
|
|
||||||
// tmp := strings.TrimSpace(strings.Join(result.Stdout, "\n"))
|
|
||||||
// return shell.SplitNewLines(tmp)
|
|
||||||
return result.Stdout
|
|
||||||
}
|
|
||||||
|
|
||||||
// deletes the devel local branch if it is a subset of the remote devel branch
|
|
||||||
func (repo *Repo) DeleteLocalDevelBranch() error {
|
|
||||||
branch := repo.GetDevelBranchName()
|
|
||||||
remote := filepath.Join("origin", branch)
|
|
||||||
|
|
||||||
if !repo.IsDevelRemote() {
|
|
||||||
return fmt.Errorf("no remote branch")
|
|
||||||
}
|
|
||||||
|
|
||||||
b1 := repo.CountDiffObjects(branch, remote) // should be zero
|
|
||||||
if b1 == 0 {
|
|
||||||
cmd := []string{"git", "branch", "-D", repo.GetDevelBranchName()}
|
|
||||||
_, err := repo.RunVerboseOnError(cmd)
|
|
||||||
return err
|
|
||||||
} else {
|
|
||||||
return fmt.Errorf("local branch has patches not in remote")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// makes a local branch based off of the master branch
|
|
||||||
// (unless a remote devel branch exists. then it uses that)
|
|
||||||
func (repo *Repo) MakeLocalDevelBranch() (*cmd.Status, error) {
|
|
||||||
branch := repo.GetDevelBranchName()
|
|
||||||
if branch == "" {
|
|
||||||
// hard coded default
|
|
||||||
branch = "devel"
|
|
||||||
}
|
|
||||||
|
|
||||||
if repo.Exists(filepath.Join(".git/refs/heads", branch)) {
|
|
||||||
// local devel branch already exists
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if repo.Exists(filepath.Join(".git/refs/remotes/origin", branch)) {
|
|
||||||
// remote devel branch exists, but local does not
|
|
||||||
cmd := []string{"git", "checkout", branch}
|
|
||||||
return repo.RunVerboseOnError(cmd)
|
|
||||||
}
|
|
||||||
|
|
||||||
master := repo.GetMasterBranchName()
|
|
||||||
cmd := []string{"git", "branch", branch, master}
|
|
||||||
repo.RunVerboseOnError(cmd)
|
|
||||||
cmd = []string{"git", "checkout", branch}
|
|
||||||
return repo.RunVerboseOnError(cmd)
|
|
||||||
}
|
|
55
checkout.go
55
checkout.go
|
@ -2,8 +2,6 @@ package gitpb
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
"os/user"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"go.wit.com/log"
|
"go.wit.com/log"
|
||||||
|
@ -11,20 +9,6 @@ import (
|
||||||
|
|
||||||
func (repo *Repo) CheckoutMaster() bool {
|
func (repo *Repo) CheckoutMaster() bool {
|
||||||
bName := repo.GetMasterBranchName()
|
bName := repo.GetMasterBranchName()
|
||||||
if bName == "giterr" {
|
|
||||||
cmd := []string{"git", "checkout", "main"} // todo: figure out main
|
|
||||||
repo.RunVerboseOnError(cmd)
|
|
||||||
os.Exit(-1)
|
|
||||||
// TODO: try to fix this
|
|
||||||
if repo.checkoutBranch("main") {
|
|
||||||
repo.MasterBranchName = "main"
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
cmd := []string{"git", "checkout", "main"} // todo: figure out main
|
|
||||||
repo.RunVerboseOnError(cmd)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if repo.checkoutBranch(bName) {
|
if repo.checkoutBranch(bName) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -43,20 +27,12 @@ func (repo *Repo) CheckoutDevel() bool {
|
||||||
|
|
||||||
func (repo *Repo) CheckoutUser() error {
|
func (repo *Repo) CheckoutUser() error {
|
||||||
bName := repo.GetUserBranchName()
|
bName := repo.GetUserBranchName()
|
||||||
if bName == "uerr" {
|
// log.Info("attempting checkout user", repo.GetGoPath(), bName)
|
||||||
usr, _ := user.Current()
|
err := repo.checkoutBranchNew(bName)
|
||||||
repo.SetUserBranchName(usr.Username)
|
if err != nil {
|
||||||
bName = usr.Username
|
log.Info("attempting checkout user error", repo.GetGoPath(), bName, err)
|
||||||
log.Info("gitpb CheckoutUser() somehow got user 'uerr'")
|
|
||||||
}
|
}
|
||||||
|
return err
|
||||||
return repo.createUserBranch(bName)
|
|
||||||
/*
|
|
||||||
if err != nil {
|
|
||||||
log.Info("attempting checkout user error", repo.GetGoPath(), bName, err)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *Repo) BranchExists(bName string) bool {
|
func (repo *Repo) BranchExists(bName string) bool {
|
||||||
|
@ -92,16 +68,16 @@ func (repo *Repo) checkoutBranch(bName string) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// actually creates a local user branch
|
func (repo *Repo) checkoutBranchNew(branch string) error {
|
||||||
func (repo *Repo) createUserBranch(branch string) error {
|
if branch == "" || branch == "uerr" {
|
||||||
if branch == "" {
|
log.Info("forge.gitpb logic err. branch name was:", branch)
|
||||||
// get the username here?
|
return nil
|
||||||
return fmt.Errorf("gitpb createuserBranch() logic err. git branch name can not be blank")
|
|
||||||
}
|
}
|
||||||
if repo.IsDirty() {
|
if repo.IsDirty() {
|
||||||
// never change repos on dirty branches
|
// never change repos on dirty branches
|
||||||
return fmt.Errorf("repo is dirty")
|
return nil
|
||||||
}
|
}
|
||||||
|
// log.Info("forge.gitpb look for branch name was:", branch, repo.GetGoPath())
|
||||||
|
|
||||||
if repo.Exists(filepath.Join(".git/refs/heads", branch)) {
|
if repo.Exists(filepath.Join(".git/refs/heads", branch)) {
|
||||||
var err error
|
var err error
|
||||||
|
@ -125,15 +101,10 @@ func (repo *Repo) createUserBranch(branch string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if repo.GetCurrentBranchName() != repo.GetDevelBranchName() {
|
if repo.GetCurrentBranchName() != repo.GetDevelBranchName() {
|
||||||
repo.CheckoutDevel()
|
return fmt.Errorf("repo must be on devel branch %s", repo.GetGoPath())
|
||||||
}
|
}
|
||||||
repo.Reload()
|
|
||||||
|
|
||||||
if repo.GetCurrentBranchName() != repo.GetDevelBranchName() {
|
// log.Info("forge.gitpb try to create", branch, repo.GetGoPath())
|
||||||
log.Info("create user branch will probably fail", repo.GetGoPath())
|
|
||||||
// TODO: FIX THIS
|
|
||||||
// return fmt.Errorf("repo must be on devel branch %s", repo.GetGoPath())
|
|
||||||
}
|
|
||||||
|
|
||||||
// create the branch from devel
|
// create the branch from devel
|
||||||
cmd := []string{"git", "branch", branch}
|
cmd := []string{"git", "branch", branch}
|
||||||
|
|
126
config.go
126
config.go
|
@ -8,115 +8,44 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"go.wit.com/lib/protobuf/bugpb"
|
|
||||||
"go.wit.com/log"
|
"go.wit.com/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
// write to ~/.config/forge/ unless ENV{FORGE_REPOSDIR} is set
|
// write to ~/.config/forge/ unless ENV{FORGE_GOSRC} is set
|
||||||
func (all *Repos) ConfigSave(fname string) error {
|
func (all *Repos) ConfigSave() error {
|
||||||
|
if os.Getenv("FORGE_GOSRC") == "" {
|
||||||
|
homeDir, _ := os.UserHomeDir()
|
||||||
|
fullpath := filepath.Join(homeDir, ".config/forge")
|
||||||
|
os.Setenv("FORGE_GOSRC", fullpath)
|
||||||
|
}
|
||||||
if all == nil {
|
if all == nil {
|
||||||
log.Warn("gitpb repos == nil")
|
log.Warn("gitpb all == nil")
|
||||||
return errors.New("gitpb.ConfigSave() repos == nil")
|
return errors.New("gitpb.ConfigSave() all == nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
data, err := all.Marshal()
|
data, err := all.Marshal()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Info("gitpb proto.Marshal() failed len", len(data), err)
|
log.Info("gitpb proto.Marshal() failed len", len(data), err)
|
||||||
// often this is because strings have invalid UTF-8. This should probably be fixed in the protobuf code
|
|
||||||
// this might be fixed in the create code, but it can't hurt to try this as a last ditch effort here
|
|
||||||
log.Info("gitpb.ConfigSave() ATTEMPTING TO VALIDATE UTF-8 strings in the protobuf file")
|
|
||||||
if err := all.tryValidate(); err != nil {
|
|
||||||
log.Info("gitpb.ConfigSave() STILL FAILEd", err)
|
|
||||||
return err
|
|
||||||
} else {
|
|
||||||
// re-attempt Marshal() here
|
|
||||||
data, err = all.Marshal()
|
|
||||||
if err == nil {
|
|
||||||
// validate & sanitize strings worked
|
|
||||||
configWrite(fname, data)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
log.Info("gitpb.ConfigSave() STILL FAILEd", err)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
configWrite(fname, data)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// todo: move this to Marshal() functions automatically in autogenpb?
|
|
||||||
func (repo *Repo) ValidateUTF8() error {
|
|
||||||
if _, err := repo.Marshal(); err == nil {
|
|
||||||
// exit if Marshal() works
|
|
||||||
return nil
|
|
||||||
} else {
|
|
||||||
// log.Printf("%s repo.Marshal() failed: %v\n", repo.GetFullPath(), err)
|
|
||||||
}
|
|
||||||
// you only need to do this if Marshal() fails
|
|
||||||
err := bugpb.ValidateProtoUTF8(repo)
|
|
||||||
if err != nil {
|
|
||||||
// log.Printf("Protobuf UTF-8 validation failed: %v\n", err)
|
|
||||||
}
|
|
||||||
if err := bugpb.SanitizeProtoUTF8(repo); err != nil {
|
|
||||||
log.Warn("gitpb.ValidateUTF8()( failed:", err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (all *Repos) tryValidate() error {
|
|
||||||
err := bugpb.ValidateProtoUTF8(all)
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("Protobuf UTF-8 validation failed: %v\n", err)
|
|
||||||
}
|
|
||||||
if err := bugpb.SanitizeProtoUTF8(all); err != nil {
|
|
||||||
log.Warn("Sanitation failed:", err)
|
|
||||||
// log.Fatalf("Sanitization failed: %v", err)
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
log.Info("gitpb.ConfigSave() repos.Marshal() worked len", len(all.Repos), "repos")
|
||||||
|
configWrite("repos.pb", data)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// load the repos.pb file. I shouldn't really matter if this
|
// load the repos.pb file. I shouldn't really matter if this
|
||||||
// fails. the file should be autogenerated. This is used
|
// fails. the file should be autogenerated. This is used
|
||||||
// locally just for speed
|
// locally just for speed
|
||||||
func (all *Repos) ConfigLoadOld() error {
|
func (all *Repos) ConfigLoad() error {
|
||||||
if os.Getenv("FORGE_REPOSDIR") == "" {
|
if os.Getenv("FORGE_GOSRC") == "" {
|
||||||
homeDir, _ := os.UserHomeDir()
|
homeDir, _ := os.UserHomeDir()
|
||||||
fullpath := filepath.Join(homeDir, ".config/forge")
|
fullpath := filepath.Join(homeDir, ".config/forge")
|
||||||
os.Setenv("FORGE_REPOSDIR", fullpath)
|
os.Setenv("FORGE_GOSRC", fullpath)
|
||||||
}
|
}
|
||||||
var data []byte
|
var data []byte
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
cfgname := filepath.Join(os.Getenv("FORGE_REPOSDIR"), "repos.pb")
|
cfgname := filepath.Join(os.Getenv("FORGE_GOSRC"), "repos.pb")
|
||||||
if data, err = loadFile(cfgname); err != nil {
|
|
||||||
// something went wrong loading the file
|
|
||||||
// all.sampleConfig() // causes nil panic
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// this means the forge.pb file exists and was read
|
|
||||||
if len(data) == 0 {
|
|
||||||
return errors.New("gitpb.ConfigLoad() repos.pb is empty")
|
|
||||||
}
|
|
||||||
err = all.Unmarshal(data)
|
|
||||||
test := NewRepos()
|
|
||||||
if test.Uuid != all.Uuid {
|
|
||||||
log.Log(WARN, "uuids do not match", test.Uuid, all.Uuid)
|
|
||||||
deleteProtobufFile(cfgname)
|
|
||||||
}
|
|
||||||
if test.Version != all.Version {
|
|
||||||
log.Log(WARN, "versions do not match", test.Version, all.Version)
|
|
||||||
deleteProtobufFile(cfgname)
|
|
||||||
}
|
|
||||||
log.Log(INFO, cfgname, "protobuf versions and uuid match", all.Uuid, all.Version)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (all *Repos) ConfigLoad(cfgname string) error {
|
|
||||||
var data []byte
|
|
||||||
var err error
|
|
||||||
|
|
||||||
if data, err = loadFile(cfgname); err != nil {
|
if data, err = loadFile(cfgname); err != nil {
|
||||||
// something went wrong loading the file
|
// something went wrong loading the file
|
||||||
// all.sampleConfig() // causes nil panic
|
// all.sampleConfig() // causes nil panic
|
||||||
|
@ -124,6 +53,7 @@ func (all *Repos) ConfigLoad(cfgname string) error {
|
||||||
}
|
}
|
||||||
// this means the forge.pb file exists and was read
|
// this means the forge.pb file exists and was read
|
||||||
if len(data) == 0 {
|
if len(data) == 0 {
|
||||||
|
all.sampleConfig() // causes nil panic
|
||||||
return errors.New("gitpb.ConfigLoad() repos.pb is empty")
|
return errors.New("gitpb.ConfigLoad() repos.pb is empty")
|
||||||
}
|
}
|
||||||
err = all.Unmarshal(data)
|
err = all.Unmarshal(data)
|
||||||
|
@ -142,12 +72,9 @@ func (all *Repos) ConfigLoad(cfgname string) error {
|
||||||
|
|
||||||
func deleteProtobufFile(filename string) {
|
func deleteProtobufFile(filename string) {
|
||||||
log.Log(WARN, "The protobuf file format has changed for", filename)
|
log.Log(WARN, "The protobuf file format has changed for", filename)
|
||||||
log.Log(WARN, "Deleting old file:", filename)
|
log.Log(WARN, "You must delete", filename)
|
||||||
log.Log(WARN, "This file will be recreated on the next run.")
|
log.Log(WARN, "This file will be recreated")
|
||||||
err := os.Remove(filename)
|
os.Exit(-1)
|
||||||
if err != nil {
|
|
||||||
log.Log(WARN, "failed to remove old protobuf file", "err", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (all *Repos) sampleConfig() {
|
func (all *Repos) sampleConfig() {
|
||||||
|
@ -171,14 +98,25 @@ func loadFile(fullname string) ([]byte, error) {
|
||||||
return data, nil
|
return data, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func configWrite(fullname string, data []byte) error {
|
func configWrite(filename string, data []byte) error {
|
||||||
log.Infof("%s your repos have changed state. cached state. (%d) bytes\n", fullname, len(data))
|
fullname := filepath.Join(os.Getenv("FORGE_GOSRC"), filename)
|
||||||
|
|
||||||
cfgfile, err := os.OpenFile(fullname, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
|
cfgfile, err := os.OpenFile(fullname, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
|
||||||
defer cfgfile.Close()
|
defer cfgfile.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn("open config file :", err)
|
log.Warn("open config file :", err)
|
||||||
return 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)
|
cfgfile.Write(data)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,7 @@ func (repo *Repo) setDevelVersion() {
|
||||||
repo.DevelVersion = v
|
repo.DevelVersion = v
|
||||||
} else {
|
} else {
|
||||||
// log.Log(WARN, "gitpb.GitDevelVersion() error:", err)
|
// log.Log(WARN, "gitpb.GitDevelVersion() error:", err)
|
||||||
repo.DevelVersion = ""
|
repo.DevelVersion = "deverr"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,6 +69,19 @@ func (repo *Repo) setUserVersion() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
now tracked in repo.Reload()
|
||||||
|
func (repo *Repo) GetCurrentBranchName() string {
|
||||||
|
r := repo.RunQuiet([]string{"git", "branch", "--show-current"})
|
||||||
|
output := strings.Join(r.Stdout, "\n")
|
||||||
|
if r.Error != nil {
|
||||||
|
log.Log(WARN, "GetCurrentBranchName() not in a git repo?", r.Error, repo.GetGoPath())
|
||||||
|
log.Log(WARN, "GetCurrentBranchName() output might have worked anyway:", output)
|
||||||
|
}
|
||||||
|
return strings.TrimSpace(output)
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// this is used often. probably move everything to this
|
// this is used often. probably move everything to this
|
||||||
// returns things like
|
// returns things like
|
||||||
// v0.2.2
|
// v0.2.2
|
||||||
|
@ -90,13 +103,13 @@ func (repo *Repo) gitDescribeByHash(hash string) (string, error) {
|
||||||
if hash == "" {
|
if hash == "" {
|
||||||
return "", errors.New("hash was blank")
|
return "", errors.New("hash was blank")
|
||||||
}
|
}
|
||||||
r, err := repo.RunQuiet([]string{"git", "describe", "--tags", hash})
|
r := repo.RunQuiet([]string{"git", "describe", "--tags", "--always", hash})
|
||||||
out := strings.Join(r.Stdout, "\n")
|
out := strings.Join(r.Stdout, "\n")
|
||||||
if err != nil {
|
if r.Error != nil {
|
||||||
// log.Warn("not in a git repo or bad hash?", err, repo.GetGoPath())
|
log.Warn("not in a git repo or bad hash?", r.Error, repo.GetGoPath())
|
||||||
return "gitpb err", err
|
return out, r.Error
|
||||||
}
|
}
|
||||||
return out, err
|
return out, r.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
// this should get the most recent tag
|
// this should get the most recent tag
|
||||||
|
@ -134,33 +147,84 @@ func (repo *Repo) gitVersionByName(name string) (string, error) {
|
||||||
|
|
||||||
if name == "" {
|
if name == "" {
|
||||||
// git will return the current tag
|
// git will return the current tag
|
||||||
r, err := repo.RunQuiet([]string{"git", "describe", "--tags"})
|
r := repo.RunQuiet([]string{"git", "describe", "--tags", "--always"})
|
||||||
output := strings.Join(r.Stdout, "\n")
|
output := strings.Join(r.Stdout, "\n")
|
||||||
if err != nil {
|
if r.Error != nil {
|
||||||
log.Log(WARN, "gitDescribeByName() output might have worked anyway:", output)
|
log.Log(WARN, "gitDescribeByName() output might have worked anyway:", output)
|
||||||
log.Log(WARN, "gitDescribeByName() not in a git repo?", err, repo.GetGoPath())
|
log.Log(WARN, "gitDescribeByName() not in a git repo?", r.Error, repo.GetGoPath())
|
||||||
return "", err
|
return "", r.Error
|
||||||
}
|
}
|
||||||
return strings.TrimSpace(output), nil
|
return strings.TrimSpace(output), nil
|
||||||
}
|
}
|
||||||
if !repo.IsBranch(name) {
|
if !repo.IsBranch(name) {
|
||||||
// branch does not exist
|
// tag does not exist
|
||||||
|
log.Log(WARN, "LocalTagExists()", name, "did not exist")
|
||||||
return "", errors.New("gitDescribeByName() git fatal: Not a valid object name: " + name)
|
return "", errors.New("gitDescribeByName() git fatal: Not a valid object name: " + name)
|
||||||
}
|
}
|
||||||
cmd := []string{"git", "describe", "--tags", name}
|
cmd := []string{"git", "describe", "--tags", "--always", name}
|
||||||
result, err := repo.RunQuiet(cmd)
|
result := repo.RunQuiet(cmd)
|
||||||
output := strings.Join(result.Stdout, "\n")
|
output := strings.Join(result.Stdout, "\n")
|
||||||
if err != nil {
|
if result.Error != nil {
|
||||||
//log.Log(WARN, "cmd =", cmd)
|
log.Log(WARN, "cmd =", cmd)
|
||||||
//log.Log(WARN, "err =", err)
|
log.Log(WARN, "err =", result.Error)
|
||||||
//log.Log(WARN, "output (might have worked with error?) =", output)
|
log.Log(WARN, "output (might have worked with error?) =", output)
|
||||||
//log.Log(WARN, "not in a git repo or bad tag?", repo.GetGoPath())
|
log.Log(WARN, "not in a git repo or bad tag?", repo.GetGoPath())
|
||||||
return "", result.Error
|
return "", result.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
return strings.TrimSpace(output), nil
|
return strings.TrimSpace(output), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// find a branch name
|
||||||
|
// will find "master" or "devel"
|
||||||
|
// will also find "v0.1.1"
|
||||||
|
// or will find "patches-from-foo"
|
||||||
|
// will return *any* match on any git branch because it doesn't
|
||||||
|
// matter much here yet
|
||||||
|
// eventually this will be worked out by forge in some future code that hasn't been made yet
|
||||||
|
func (repo *Repo) IsBranch(findname string) bool {
|
||||||
|
loop := repo.Tags.All()
|
||||||
|
for loop.Scan() {
|
||||||
|
t := loop.Next()
|
||||||
|
// log.Info("LocalTagExists() tag:", t.Refname)
|
||||||
|
|
||||||
|
tagname := t.Refname
|
||||||
|
if strings.HasPrefix(tagname, "refs/remotes") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
path, filename := filepath.Split(tagname)
|
||||||
|
log.Log(INFO, "gitpb.IsBranch() tag:", path, filename, "from", repo.GetGoPath())
|
||||||
|
if filename == findname {
|
||||||
|
log.Log(INFO, "gitpb.IsBranch() found tag:", path, filename, "from", repo.GetGoPath())
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.Log(INFO, "did not find tag:", findname, "in", repo.GetGoPath())
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo: redo this and above. both are messed up. ignore for now until things are stable
|
||||||
|
func (repo *Repo) IsLocalBranch(findname string) bool {
|
||||||
|
loop := repo.Tags.All()
|
||||||
|
for loop.Scan() {
|
||||||
|
t := loop.Next()
|
||||||
|
// log.Info("LocalTagExists() tag:", t.Refname)
|
||||||
|
|
||||||
|
tagname := t.Refname
|
||||||
|
if strings.HasPrefix(tagname, "refs/heads") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
path, filename := filepath.Split(tagname)
|
||||||
|
log.Log(INFO, "gitpb.IsBranch() tag:", path, filename, "from", repo.GetGoPath())
|
||||||
|
if filename == findname {
|
||||||
|
log.Log(INFO, "gitpb.IsBranch() found tag:", path, filename, "from", repo.GetGoPath())
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.Log(INFO, "did not find tag:", findname, "in", repo.GetGoPath())
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func trimNonNumericFromStart(s string) string {
|
func trimNonNumericFromStart(s string) string {
|
||||||
for i, r := range s {
|
for i, r := range s {
|
||||||
if unicode.IsDigit(r) {
|
if unicode.IsDigit(r) {
|
||||||
|
@ -230,25 +294,23 @@ func (repo *Repo) IncrementTargetMinor() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// changes the target revision. v0.1.3 becomes v0.1.4
|
// changes the target revision. v0.1.3 becomes v0.1.4
|
||||||
func (repo *Repo) IncrementTargetRevision() {
|
func (repo *Repo) IncrementTargetRevision() bool {
|
||||||
// first try just going from the last tag
|
// first try just going from the last tag
|
||||||
repo.incrementRevision(repo.GetLastTag())
|
repo.incrementRevision(repo.GetLastTag())
|
||||||
|
|
||||||
if !isNewerVersion(repo.GetMasterVersion(), repo.GetTargetVersion()) {
|
if !isNewerVersion(repo.GetMasterVersion(), repo.GetTargetVersion()) {
|
||||||
// log.Printf("tag error. master version() %s was higher than target version %s\n", repo.GetMasterVersion(), repo.GetTargetVersion())
|
log.Printf("master version() %s is higher than target version %s\n", repo.GetMasterVersion(), repo.GetTargetVersion())
|
||||||
repo.incrementRevision(repo.GetMasterVersion())
|
repo.incrementRevision(repo.GetMasterVersion())
|
||||||
}
|
}
|
||||||
/*
|
if !isNewerVersion(repo.GetLastTag(), repo.GetTargetVersion()) {
|
||||||
if !isNewerVersion(repo.GetLastTag(), repo.GetTargetVersion()) {
|
log.Printf("last tag versn() %s is higher than target version %s\n", repo.GetLastTag(), repo.GetTargetVersion())
|
||||||
log.Printf("last tag versn() %s is higher than target version %s\n", repo.GetLastTag(), repo.GetTargetVersion())
|
return false
|
||||||
return false
|
}
|
||||||
}
|
if !isNewerVersion(repo.GetMasterVersion(), repo.GetTargetVersion()) {
|
||||||
if !isNewerVersion(repo.GetMasterVersion(), repo.GetTargetVersion()) {
|
log.Printf("master version() %s is higher than target version %s\n", repo.GetMasterVersion(), repo.GetTargetVersion())
|
||||||
log.Printf("master version() %s is higher than target version %s\n", repo.GetMasterVersion(), repo.GetTargetVersion())
|
return false
|
||||||
return false
|
}
|
||||||
}
|
return true
|
||||||
return true
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *Repo) incrementRevision(lasttag string) {
|
func (repo *Repo) incrementRevision(lasttag string) {
|
||||||
|
|
|
@ -12,7 +12,7 @@ import (
|
||||||
// todo: probably switch to using slices. new things added in 1.23
|
// todo: probably switch to using slices. new things added in 1.23
|
||||||
// https://pkg.go.dev/slices
|
// https://pkg.go.dev/slices
|
||||||
|
|
||||||
func (all *GitTags) newSort() *GitTagScanner {
|
func (all *GitTags) newSort() *GitTagIterator {
|
||||||
slices.SortFunc(all.GitTags, func(a, b *GitTag) int {
|
slices.SortFunc(all.GitTags, func(a, b *GitTag) int {
|
||||||
if n := strings.Compare(a.Name, b.Name); n != 0 {
|
if n := strings.Compare(a.Name, b.Name); n != 0 {
|
||||||
return n
|
return n
|
||||||
|
@ -44,12 +44,12 @@ func (all *GitTags) GetAge(name string) time.Time {
|
||||||
return newest
|
return newest
|
||||||
}
|
}
|
||||||
|
|
||||||
func (all *GitTags) SortByAge() *GitTagScanner {
|
func (all *GitTags) SortByAge() *GitTagIterator {
|
||||||
packs := all.selectAllGitTags()
|
packs := all.selectAllGitTags()
|
||||||
|
|
||||||
sort.Sort(GitTagAge(packs))
|
sort.Sort(GitTagAge(packs))
|
||||||
|
|
||||||
iterator := newGitTagScanner(packs)
|
iterator := newGitTagIterator(packs)
|
||||||
return iterator
|
return iterator
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,25 +87,6 @@ func (repo *Repo) NewestAge() time.Duration {
|
||||||
return time.Since(newest)
|
return time.Since(newest)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *Repo) NewestTime() time.Time {
|
|
||||||
alltags := repo.Tags.selectAllGitTags()
|
|
||||||
|
|
||||||
var newest time.Time
|
|
||||||
|
|
||||||
for _, tag := range alltags {
|
|
||||||
// check the actual age of the patch
|
|
||||||
if newest.Before(tag.Authordate.AsTime()) {
|
|
||||||
newest = tag.Authordate.AsTime()
|
|
||||||
}
|
|
||||||
// check the age of the commit
|
|
||||||
if newest.Before(tag.Creatordate.AsTime()) {
|
|
||||||
newest = tag.Creatordate.AsTime()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return newest
|
|
||||||
}
|
|
||||||
|
|
||||||
func (repo *Repo) NewestAgeVerbose() time.Duration {
|
func (repo *Repo) NewestAgeVerbose() time.Duration {
|
||||||
alltags := repo.Tags.selectAllGitTags()
|
alltags := repo.Tags.selectAllGitTags()
|
||||||
|
|
||||||
|
|
134
gitTag.common.go
134
gitTag.common.go
|
@ -1,16 +1,11 @@
|
||||||
package gitpb
|
package gitpb
|
||||||
|
|
||||||
import (
|
func (repo *Repo) DevelHash() string {
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"go.wit.com/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (repo *Repo) ActualDevelHash() string {
|
|
||||||
brname := repo.GetDevelBranchName()
|
brname := repo.GetDevelBranchName()
|
||||||
refname := "refs/heads/" + brname
|
refname := "refs/heads/" + brname
|
||||||
for tag := range repo.Tags.IterAll() {
|
all := repo.Tags.All()
|
||||||
|
for all.Scan() {
|
||||||
|
tag := all.Next()
|
||||||
// log.Info("repo tag", tag.GetHash(), tag.GetRefname())
|
// log.Info("repo tag", tag.GetHash(), tag.GetRefname())
|
||||||
if tag.GetRefname() == refname {
|
if tag.GetRefname() == refname {
|
||||||
return tag.GetHash()
|
return tag.GetHash()
|
||||||
|
@ -18,124 +13,3 @@ func (repo *Repo) ActualDevelHash() string {
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *Repo) GetLocalHash(brname string) string {
|
|
||||||
refname := "refs/heads/" + brname
|
|
||||||
for tag := range repo.Tags.IterAll() {
|
|
||||||
// log.Info("repo tag", tag.GetHash(), tag.GetRefname())
|
|
||||||
if tag.GetRefname() == refname {
|
|
||||||
return strings.TrimSpace(tag.GetHash())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (repo *Repo) GetRemoteHash(brname string) string {
|
|
||||||
refname := "refs/remotes/origin/" + brname
|
|
||||||
for tag := range repo.Tags.IterAll() {
|
|
||||||
// log.Info("repo tag", tag.GetHash(), tag.GetRefname())
|
|
||||||
if tag.GetRefname() == refname {
|
|
||||||
return strings.TrimSpace(tag.GetHash())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// this is the correct way. uses 'git show-ref'
|
|
||||||
func (repo *Repo) IsBranchRemote(brname string) bool {
|
|
||||||
if repo.Tags == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
brname = "refs/remotes/origin/" + brname
|
|
||||||
ref := repo.Tags.FindByRefname(brname)
|
|
||||||
if ref == nil {
|
|
||||||
// log.Info("did not found refname!!!!!!!!", brname)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
// log.Info("found refname!!!!!!!!")
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// this is the correct way. uses 'git show-ref'
|
|
||||||
func (repo *Repo) IsDevelRemote() bool {
|
|
||||||
if repo.Tags == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
devname := repo.GetDevelBranchName()
|
|
||||||
refname := "refs/remotes/origin/" + devname
|
|
||||||
ref := repo.Tags.FindByRefname(refname)
|
|
||||||
if ref == nil {
|
|
||||||
// log.Info("did not found refname!!!!!!!!", refname)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
// log.Info("found refname!!!!!!!!")
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// find a branch namm
|
|
||||||
// will find "master" or "devel"
|
|
||||||
// will also find "v0.1.1"
|
|
||||||
// or will find "patches-from-foo"
|
|
||||||
// will return *any* match on any git branch because it doesn't
|
|
||||||
// matter much here yet
|
|
||||||
// eventually this will be worked out by forge in some future code that hasn't been made yet
|
|
||||||
func (repo *Repo) IsBranch(findname string) bool {
|
|
||||||
for t := range repo.Tags.IterAll() {
|
|
||||||
tagname := t.Refname
|
|
||||||
if strings.HasPrefix(tagname, "refs/remotes") {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
path, filename := filepath.Split(tagname)
|
|
||||||
log.Log(INFO, "gitpb.IsBranch() tag:", path, filename, "from", repo.GetGoPath())
|
|
||||||
if filename == findname {
|
|
||||||
log.Log(INFO, "gitpb.IsBranch() found tag:", path, filename, "from", repo.GetGoPath())
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
log.Log(INFO, "did not find tag:", findname, "in", repo.GetGoPath())
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (repo *Repo) IsLocalBranch(findname string) bool {
|
|
||||||
for t := range repo.Tags.IterAll() {
|
|
||||||
if !strings.HasPrefix(t.Refname, "refs/heads") {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
path, filename := filepath.Split(t.Refname)
|
|
||||||
log.Log(INFO, "gitpb.IsBranch() tag:", path, filename, "from", repo.GetGoPath())
|
|
||||||
if filename == findname {
|
|
||||||
log.Log(INFO, "gitpb.IsBranch() found tag:", path, filename, "from", repo.GetGoPath())
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
log.Log(INFO, "did not find tag:", findname, "in", repo.GetGoPath())
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// finds the newest tag. used for deciding if master needs to be published
|
|
||||||
func (repo *Repo) FindLastTag() string {
|
|
||||||
var newest *GitTag
|
|
||||||
for tag := range repo.Tags.IterAll() {
|
|
||||||
if !strings.HasPrefix(tag.GetRefname(), "refs/tags/") {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if newest == nil {
|
|
||||||
newest = tag
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
cur := newest.Creatordate.AsTime()
|
|
||||||
if cur.Before(tag.Creatordate.AsTime()) {
|
|
||||||
newest = tag
|
|
||||||
}
|
|
||||||
// newtag := strings.TrimPrefix(tag.GetRefname(), "refs/tags/")
|
|
||||||
// log.Info("repo tag", tag.GetHash(), tag.Creatordate.AsTime(), tag.GetRefname(), newtag)
|
|
||||||
}
|
|
||||||
if newest == nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
// log.Info("repo newest tag", newest.GetHash(), newest.Creatordate.AsTime(), newest.GetRefname())
|
|
||||||
newtag := strings.TrimPrefix(newest.GetRefname(), "refs/tags/")
|
|
||||||
return newtag
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,41 +0,0 @@
|
||||||
// Code generated by go.wit.com/apps/autogenpb DO NOT EDIT.
|
|
||||||
// This file was autogenerated with autogenpb v0.5.1 2025-09-12_15:24:32_UTC
|
|
||||||
// go install go.wit.com/apps/autogenpb@latest
|
|
||||||
//
|
|
||||||
// define which structs (messages) you want to use in the .proto file
|
|
||||||
// Then sort.pb.go and marshal.pb.go files are autogenerated
|
|
||||||
//
|
|
||||||
// autogenpb uses it and has an example .proto file with instructions
|
|
||||||
//
|
|
||||||
|
|
||||||
package gitpb
|
|
||||||
|
|
||||||
import (
|
|
||||||
"go.wit.com/lib/cobol"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (mt *GitTagsTable) PrintTable() {
|
|
||||||
// log.Info("ShowTable() SENDING TO GUI")
|
|
||||||
mt.MakeTable()
|
|
||||||
cobol.PrintTable(mt.pb)
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
func (mt *GitTagsTable) MakeTable() {
|
|
||||||
for _, name := range mt.pb.Order {
|
|
||||||
// log.Info("gitpb: looking for row name()", name)
|
|
||||||
if mt.doStringFunc(name) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if mt.doIntFunc(name) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if mt.doTimeFunc(name) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if mt.doButtonFunc(name) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
51
gitTag.proto
51
gitTag.proto
|
@ -4,37 +4,38 @@ package gitpb;
|
||||||
|
|
||||||
import "google/protobuf/timestamp.proto"; // Import the well-known type for Timestamp
|
import "google/protobuf/timestamp.proto"; // Import the well-known type for Timestamp
|
||||||
|
|
||||||
message GitRemote { // `autogenpb:nomutex`
|
message GitRemote { // `autogenpb:nomutex`
|
||||||
string url = 1;
|
string url = 1;
|
||||||
string fetch = 2;
|
string fetch = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message GitBranch { // `autogenpb:nomutex`
|
message GitBranch { // `autogenpb:nomutex`
|
||||||
string remote = 1; // the name of the remote repo
|
string remote = 1; // the name of the remote repo
|
||||||
string merge = 2; // the merge path from the config file
|
string merge = 2; // the merge path from the config file
|
||||||
string name = 3; // the branch name from the config file
|
string name = 3; // the branch name from the config file
|
||||||
}
|
}
|
||||||
|
|
||||||
message GitConfig { // `autogenpb:nomutex`
|
// readGitConfig reads and parses the .git/config file
|
||||||
map<string, string> core = 1; // map[origin] = "https:/git.wit.org/gui/gadgets"
|
message GitConfig { // `autogenpb:nomutex`
|
||||||
map<string, GitRemote> remotes = 2; // map[origin] = "https:/git.wit.org/gui/gadgets"
|
map<string, string> core = 1; // map[origin] = "https:/git.wit.org/gui/gadgets"
|
||||||
map<string, GitBranch> branches = 3; // map[guimaster] = origin guimaster
|
map<string, GitRemote> remotes = 2; // map[origin] = "https:/git.wit.org/gui/gadgets"
|
||||||
map<string, string> submodules = 4;
|
map<string, GitBranch> branches = 3; // map[guimaster] = origin guimaster
|
||||||
map<string, string> hashes = 5;
|
map<string, string> submodules = 4;
|
||||||
map<string, string> versions = 6;
|
map<string, string> hashes = 5;
|
||||||
repeated GitBranch local = 7; // move this this and away from the map<> variables
|
map<string, string> versions = 6;
|
||||||
|
repeated GitBranch local = 7; // move this this and away from the map<> variables
|
||||||
}
|
}
|
||||||
|
|
||||||
message GitTag { // `autogenpb:nomutex`
|
message GitTag { // `autogenpb:nomutex`
|
||||||
string refname = 1; // `autogenpb:unique` `autogenpb:sort` // tag name. treated as unique
|
string refname = 1; // `autogenpb:unique` `autogenpb:sort` // tag name. treated as unique
|
||||||
google.protobuf.Timestamp creatordate = 2; // git creatordate
|
google.protobuf.Timestamp creatordate = 2; // git creatordate
|
||||||
google.protobuf.Timestamp authordate = 3; // git author date
|
google.protobuf.Timestamp authordate = 3; // git author date
|
||||||
string hash = 4; // `autogenpb:unique` // git hash
|
string hash = 4; // `autogenpb:unique` // git hash
|
||||||
string subject = 5; // git tag subject
|
string subject = 5; // git tag subject
|
||||||
}
|
}
|
||||||
|
|
||||||
message GitTags { // `autogenpb:marshal` `autogenpb:nomutex` `autogenpb:gui`
|
message GitTags { // `autogenpb:marshal` `autogenpb:nomutex`
|
||||||
string uuid = 1; // `autogenpb:uuid:ffdff813-0316-4372-9e82-4c1c7d202526`
|
string uuid = 1; // `autogenpb:uuid:ffdff813-0316-4372-9e82-4c1c7d202526`
|
||||||
string version = 2; // `autogenpb:version:v0.0.47`
|
string version = 2; // `autogenpb:version:v0.0.47`
|
||||||
repeated GitTag gitTags = 3;
|
repeated GitTag gitTags = 3;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,18 +4,15 @@ package gitpb
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"go.wit.com/lib/gui/shell"
|
|
||||||
"go.wit.com/log"
|
"go.wit.com/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
// reads and parses the go.sum file into a protobuf struct
|
// reads and parses the go.sum file
|
||||||
// this function isn't supposed to change anything, just parse the existing files
|
// does not change anything
|
||||||
func (repo *Repo) ParseGoSum() bool {
|
func (repo *Repo) ParseGoSum() bool {
|
||||||
// empty out what was there before
|
// empty out what was there before
|
||||||
repo.GoDeps = nil
|
repo.GoDeps = nil
|
||||||
|
@ -24,7 +21,6 @@ func (repo *Repo) ParseGoSum() bool {
|
||||||
// that means, there is not a go.sum file
|
// that means, there is not a go.sum file
|
||||||
// because the package is completely self contained!
|
// because the package is completely self contained!
|
||||||
if err := repo.setPrimitive(); err != nil {
|
if err := repo.setPrimitive(); err != nil {
|
||||||
// temporarily enabled this. this is really noisy
|
|
||||||
// log.Info("gitpb.ParseGoSum()", err)
|
// log.Info("gitpb.ParseGoSum()", err)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -72,127 +68,3 @@ func (repo *Repo) ParseGoSum() bool {
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// attempt to parse go.* files in a directory
|
|
||||||
func GoSumParseDir(moddir string) (*GoDeps, error) {
|
|
||||||
isprim, err := computePrimitive(moddir)
|
|
||||||
if err != nil {
|
|
||||||
// "go mod init" failed
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if isprim {
|
|
||||||
// might be a GO primitive. no go.sum file
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
// go.sum exists. parse the go.sum file
|
|
||||||
return parseGoSum(moddir)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Detect a 'Primitive' package. Sets the isPrimitive flag
|
|
||||||
// will return true if the repo is truly not dependent on _anything_ else
|
|
||||||
// like spew or lib/widget
|
|
||||||
// it assumes 'go mod init' and 'go mod tidy' ran without error
|
|
||||||
func computePrimitive(moddir string) (bool, error) {
|
|
||||||
// go mod init & go mod tidy ran without errors
|
|
||||||
log.Log(INFO, "isPrimitiveGoMod()", moddir)
|
|
||||||
gomod, err := os.Open(filepath.Join(moddir, "go.mod"))
|
|
||||||
if err != nil {
|
|
||||||
log.Log(INFO, "missing go.mod", moddir)
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
defer gomod.Close()
|
|
||||||
|
|
||||||
if shell.Exists(filepath.Join(moddir, "go.sum")) {
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
scanner := bufio.NewScanner(gomod)
|
|
||||||
for scanner.Scan() {
|
|
||||||
line := strings.TrimSpace(scanner.Text())
|
|
||||||
|
|
||||||
parts := strings.Fields(line)
|
|
||||||
log.Log(INFO, " gomod:", parts)
|
|
||||||
if len(parts) >= 1 {
|
|
||||||
log.Log(INFO, " gomod: part[0] =", parts[0])
|
|
||||||
if parts[0] == "require" {
|
|
||||||
log.Log(INFO, " should return false here")
|
|
||||||
return false, errors.New("go.mod file is not primitive")
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
if parts[0] == "go" {
|
|
||||||
if parts[1] != "1.21" {
|
|
||||||
log.Log(WARN, "go not set to 1.21 for", repo.GetGoPath())
|
|
||||||
// return false, errors.New("go not set to 1.21 for " + repo.GetGoPath())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// parse the go.sum file into a protobuf
|
|
||||||
func parseGoSum(moddir string) (*GoDeps, error) {
|
|
||||||
godeps := new(GoDeps)
|
|
||||||
|
|
||||||
tmp, err := os.Open(filepath.Join(moddir, "go.sum"))
|
|
||||||
defer tmp.Close()
|
|
||||||
if err != nil {
|
|
||||||
log.Info("gitpb.ParseGoSum() missing go.sum. Some error happened with go mod init & tidy", err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
scanner := bufio.NewScanner(tmp)
|
|
||||||
for scanner.Scan() {
|
|
||||||
line := strings.TrimSpace(scanner.Text())
|
|
||||||
|
|
||||||
parts := strings.Split(line, " ")
|
|
||||||
if len(parts) == 3 {
|
|
||||||
godep := strings.TrimSpace(parts[0])
|
|
||||||
version := strings.TrimSpace(parts[1])
|
|
||||||
if strings.HasSuffix(version, "/go.mod") {
|
|
||||||
version = strings.TrimSuffix(version, "/go.mod")
|
|
||||||
}
|
|
||||||
new1 := GoDep{
|
|
||||||
GoPath: godep,
|
|
||||||
Version: version,
|
|
||||||
}
|
|
||||||
godeps.AppendByGoPath(&new1)
|
|
||||||
} else {
|
|
||||||
return nil, fmt.Errorf("gitpb.ParseGoSum() go.sum parse error invalid: %s", line)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := scanner.Err(); err != nil {
|
|
||||||
godeps = nil
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return godeps, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (repo *Repo) GoSumFromPkgDir() (*GoDeps, error) {
|
|
||||||
homedir, err := os.UserHomeDir()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
rver := repo.GetLastTag()
|
|
||||||
if rver == "" {
|
|
||||||
return nil, errors.New("could not get master version")
|
|
||||||
}
|
|
||||||
goget := repo.GetGoPath() + "@" + rver
|
|
||||||
moddir := filepath.Join(homedir, "go/pkg/mod", repo.GetGoPath()+"@"+rver)
|
|
||||||
|
|
||||||
if !shell.IsDir(moddir) {
|
|
||||||
cmd := []string{"go", "get", goget}
|
|
||||||
repo.RunVerboseOnError(cmd)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !shell.IsDir(moddir) {
|
|
||||||
return nil, errors.New("missing go/pkg/mod. Run: go get " + goget)
|
|
||||||
}
|
|
||||||
return GoSumParseDir(moddir)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (repo *Repo) GoSumFromRepo() (*GoDeps, error) {
|
|
||||||
return GoSumParseDir(repo.GetFullPath())
|
|
||||||
}
|
|
||||||
|
|
20
goDep.proto
20
goDep.proto
|
@ -8,16 +8,16 @@ import "google/protobuf/timestamp.proto"; // Import the well-known type for Time
|
||||||
|
|
||||||
// global settings for autogenpb `autogenpb:mutex`
|
// global settings for autogenpb `autogenpb:mutex`
|
||||||
|
|
||||||
message GoDep { // `autogenpb:nomutex`
|
message GoDep { // `autogenpb:nomutex`
|
||||||
string hash = 1; // `autogenpb:unique` `autogenpb:sort` // md5sum/hash value from the go.sum file
|
string hash = 1; // `autogenpb:unique` `autogenpb:sort` // md5sum/hash value from the go.sum file
|
||||||
google.protobuf.Timestamp ctime = 2; // get the go date from 'go list' ?
|
google.protobuf.Timestamp ctime = 2; // get the go date from 'go list' ?
|
||||||
string version = 3; // v1.2.2
|
string version = 3; // v1.2.2
|
||||||
string goPath = 4; // `autogenpb:unique` `autogenpb:sort` // "go.wit.com/lib/foo"
|
string goPath = 4; // `autogenpb:unique` `autogenpb:sort` // "go.wit.com/lib/foo"
|
||||||
string goVersion = 5; // version of golang the developer used to make this package version
|
string goVersion = 5; // version of golang the developer used to make this package version
|
||||||
}
|
}
|
||||||
|
|
||||||
message GoDeps { // `autogenpb:nomutex`
|
message GoDeps { // `autogenpb:nomutex`
|
||||||
string uuid = 1; // `autogenpb:uuid:7de62c09-b335-4d80-902d-08552c501b7c`
|
string uuid = 1; // `autogenpb:uuid:7de62c09-b335-4d80-902d-08552c501b7c`
|
||||||
string version = 2; // `autogenpb:version:v0.0.51`
|
string version = 2; // `autogenpb:version:v0.0.51`
|
||||||
repeated GoDep goDeps = 3; // `autogenpb:unique` `autogenpb:sort`
|
repeated GoDep goDeps = 3; // `autogenpb:unique` `autogenpb:sort`
|
||||||
}
|
}
|
||||||
|
|
81
http.go
81
http.go
|
@ -1,81 +0,0 @@
|
||||||
// Copyright 1994-2025 WIT.COM Inc Licensed GPL 3.0
|
|
||||||
|
|
||||||
package gitpb
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"os/user"
|
|
||||||
|
|
||||||
"go.wit.com/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
func httpPost(url string, data []byte) ([]byte, error) {
|
|
||||||
var err error
|
|
||||||
var req *http.Request
|
|
||||||
|
|
||||||
req, err = http.NewRequest(http.MethodPost, url, bytes.NewBuffer(data))
|
|
||||||
log.Info("httpPost() with len", len(data), "url", url)
|
|
||||||
if err != nil {
|
|
||||||
log.Error(err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
usr, _ := user.Current()
|
|
||||||
req.Header.Set("author", usr.Username)
|
|
||||||
req.Header.Set("hostname", "fixme:hostname")
|
|
||||||
|
|
||||||
client := &http.Client{}
|
|
||||||
resp, err := client.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
log.Error(err)
|
|
||||||
return []byte("client.Do(req) error"), err
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
// log.Info("httpPost() with len", len(data))
|
|
||||||
|
|
||||||
body, err := ioutil.ReadAll(resp.Body)
|
|
||||||
if err != nil {
|
|
||||||
log.Error(err)
|
|
||||||
return body, err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Info("gitpb.httpPost() worked", url)
|
|
||||||
return body, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *Repos) SubmitReposPB(url string) (*Repos, error) {
|
|
||||||
msg, err := r.Marshal()
|
|
||||||
if err != nil {
|
|
||||||
log.Info("Marshal() failed:", err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
log.Info("proto.Marshal() msg len", len(msg))
|
|
||||||
body, err := httpPost(url, msg)
|
|
||||||
if err != nil {
|
|
||||||
log.Info("httpPost() failed:", err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
log.Info("httpPost() worked with url:", url, "len(body) =", len(body))
|
|
||||||
if err := r.Unmarshal(body); err != nil {
|
|
||||||
log.Info("SubmitReposPB() Unmarshal() failed:", err)
|
|
||||||
log.Printf("%s\n", body)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return r, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *Repos) SendPB(w http.ResponseWriter) error {
|
|
||||||
data, err := r.Marshal()
|
|
||||||
if err != nil {
|
|
||||||
log.Info("Marshal() failed:", err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
log.Info("SendPB() Marshal() len(data)", len(data))
|
|
||||||
fmt.Fprintf(w, "%s", data)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -0,0 +1,112 @@
|
||||||
|
package gitpb
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"go.wit.com/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Patch struct {
|
||||||
|
GoPath string
|
||||||
|
Ref string
|
||||||
|
giturl string
|
||||||
|
comment string
|
||||||
|
}
|
||||||
|
|
||||||
|
// move all this to repolist and gowit repos
|
||||||
|
|
||||||
|
func (repo *Repo) GetPatches(oldname string, newname string) (int, []*Patch) {
|
||||||
|
var patchcount int
|
||||||
|
patches := make([]*Patch, 0, 0)
|
||||||
|
|
||||||
|
if oldname == newname {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
// log.Info("repo userv, develv", userv, develv)
|
||||||
|
gitcmd := []string{"git", "log", "--oneline", oldname + ".." + newname}
|
||||||
|
log.Info("Run:", gitcmd)
|
||||||
|
r := repo.Run(gitcmd)
|
||||||
|
if r.Error != nil {
|
||||||
|
log.Info("git failed ", repo.GetGoPath(), "err =", r.Error)
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// patches = strings.Split(output, "\n")
|
||||||
|
log.Info("Run:", r.Stdout)
|
||||||
|
for _, line := range r.Stdout {
|
||||||
|
line = strings.TrimSpace(line)
|
||||||
|
if line == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
parts := strings.Split(line, " ")
|
||||||
|
newp := new(Patch)
|
||||||
|
newp.Ref = parts[0]
|
||||||
|
newp.comment = strings.Join(parts[1:], " ")
|
||||||
|
log.Info("Patch line:", line, repo.GetGoPath())
|
||||||
|
patchcount += 1
|
||||||
|
patches = append(patches, newp)
|
||||||
|
}
|
||||||
|
return patchcount, patches
|
||||||
|
}
|
||||||
|
|
||||||
|
func (repo *Repo) GetUserPatches() (int, []*Patch) {
|
||||||
|
usern := repo.GetUserBranchName()
|
||||||
|
develn := repo.GetDevelBranchName()
|
||||||
|
userv := repo.GetUserVersion()
|
||||||
|
develv := repo.GetDevelVersion()
|
||||||
|
|
||||||
|
if userv == develv {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
c, all := repo.GetPatches(develn, usern)
|
||||||
|
log.Info("GetPatches() guireleaser", develn, usern, "count =", c)
|
||||||
|
return c, all
|
||||||
|
}
|
||||||
|
|
||||||
|
func (repo *Repo) GetMasterPatches() (int, []*Patch) {
|
||||||
|
lasttag := repo.GetLastTag()
|
||||||
|
mastern := repo.GetMasterBranchName()
|
||||||
|
masterv := repo.GetMasterVersion()
|
||||||
|
|
||||||
|
if lasttag == masterv {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
c, all := repo.GetPatches(lasttag, mastern)
|
||||||
|
log.Info("GetPatches() guireleaser", lasttag, mastern, "count =", c)
|
||||||
|
return c, all
|
||||||
|
}
|
||||||
|
|
||||||
|
func (all *Repos) MakePatchset(setdir string) bool {
|
||||||
|
loop := all.SortByFullPath()
|
||||||
|
for loop.Scan() {
|
||||||
|
repo := loop.Next()
|
||||||
|
log.Info("repo", repo.GetGoPath())
|
||||||
|
userv := repo.GetUserVersion()
|
||||||
|
develv := repo.GetDevelVersion()
|
||||||
|
usern := repo.GetUserBranchName()
|
||||||
|
develn := repo.GetDevelBranchName()
|
||||||
|
if userv == develv {
|
||||||
|
// this repo is unchanged
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
repodir := filepath.Join(setdir, repo.GetGoPath())
|
||||||
|
os.MkdirAll(repodir, os.ModeDir)
|
||||||
|
// git format-patch branch1..branch2
|
||||||
|
gitcmd := []string{"git", "format-patch", "-o", repodir, develn + ".." + usern}
|
||||||
|
log.Info("Run:", gitcmd)
|
||||||
|
r := repo.Run(gitcmd)
|
||||||
|
log.Info("output =", r.Stdout)
|
||||||
|
if r.Error == nil {
|
||||||
|
log.Info("patches made okay for:", repo.GetGoPath())
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
log.Info("patches failed for:", repo.GetGoPath())
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
75
reload.go
75
reload.go
|
@ -14,24 +14,13 @@ func (repo *Repo) ReloadCheck() error {
|
||||||
if !repo.DidRepoChange() {
|
if !repo.DidRepoChange() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
// f.configSave = true
|
||||||
err := repo.Reload()
|
err := repo.Reload()
|
||||||
if err != nil {
|
return err
|
||||||
return err
|
|
||||||
}
|
|
||||||
return log.Errorf("gitpb.ReloadCheck() detected a change in the repo")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: clean this up more, but it is working now more or less
|
// TODO: clean this up more, but it is working now more or less
|
||||||
func (repo *Repo) Reload() error {
|
func (repo *Repo) Reload() error {
|
||||||
// sometimes, on new repos, if .git/HEAD does not exist
|
|
||||||
// defective git daemons or badly configured repos, 'git clone' can fail
|
|
||||||
// if so, 'git fetch origin' can repair the state
|
|
||||||
if !repo.Exists(".git/HEAD") {
|
|
||||||
cmd := []string{"git", "fetch", "origin"}
|
|
||||||
repo.RunVerbose(cmd)
|
|
||||||
cmd = []string{"git", "checkout", "main"} // todo: figure out main
|
|
||||||
repo.RunVerbose(cmd)
|
|
||||||
}
|
|
||||||
// log.Info("in reload", repo.FullPath)
|
// log.Info("in reload", repo.FullPath)
|
||||||
repo.Tags = new(GitTags)
|
repo.Tags = new(GitTags)
|
||||||
repo.reloadGitTags()
|
repo.reloadGitTags()
|
||||||
|
@ -56,30 +45,11 @@ func (repo *Repo) Reload() error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
repo.VerifyRemoteAndLocalBranches(repo.GetDevelBranchName())
|
|
||||||
repo.VerifyRemoteAndLocalBranches(repo.GetMasterBranchName())
|
|
||||||
|
|
||||||
// LastUpdate should always be the newest time
|
// LastUpdate should always be the newest time
|
||||||
repo.Times.LastUpdate = timestamppb.New(time.Now())
|
repo.Times.LastUpdate = timestamppb.New(time.Now())
|
||||||
repo.ValidateUTF8()
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *Repo) VerifyRemoteAndLocalBranches(bname string) bool {
|
|
||||||
if !repo.IsBranchRemote(bname) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
lh := repo.GetLocalHash(bname)
|
|
||||||
rh := repo.GetRemoteHash(bname)
|
|
||||||
if lh == rh {
|
|
||||||
// log.Info(r.FullPath, "local devel == remote devel", lh, rh)
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
log.Info(lh, rh, "local != remote", repo.FullPath, bname)
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (repo *Repo) SetDevelBranchName(bname string) {
|
func (repo *Repo) SetDevelBranchName(bname string) {
|
||||||
repo.DevelBranchName = bname
|
repo.DevelBranchName = bname
|
||||||
}
|
}
|
||||||
|
@ -88,17 +58,38 @@ func (repo *Repo) SetUserBranchName(bname string) {
|
||||||
repo.UserBranchName = bname
|
repo.UserBranchName = bname
|
||||||
}
|
}
|
||||||
|
|
||||||
// updates LastTag by age
|
// updates LastTag // todo, get this from the protobuf
|
||||||
func (repo *Repo) setLastTag() {
|
func (repo *Repo) setLastTag() {
|
||||||
repo.LastTag = repo.FindLastTag()
|
cmd := []string{"git", "rev-list", "--tags", "--max-count=1"}
|
||||||
|
result := repo.RunQuiet(cmd)
|
||||||
|
// log.Info("getLastTagVersion()", result.Stdout)
|
||||||
|
|
||||||
|
if len(result.Stdout) != 1 {
|
||||||
|
// log.Log(WARN, "no gitpb.LastTag() repo is broken. ignore this.", repo.GetGoPath())
|
||||||
|
repo.LastTag = ""
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
hash := result.Stdout[0]
|
||||||
|
|
||||||
|
cmd = []string{"git", "describe", "--tags", "--always", hash}
|
||||||
|
result = repo.RunQuiet(cmd)
|
||||||
|
|
||||||
|
if len(result.Stdout) != 1 {
|
||||||
|
log.Log(WARN, "git LastTag() error:", result.Stdout, "hash =", hash)
|
||||||
|
repo.LastTag = ""
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
repo.LastTag = result.Stdout[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *Repo) setCurrentBranchName() {
|
func (repo *Repo) setCurrentBranchName() {
|
||||||
repo.CurrentBranchName = ""
|
repo.CurrentBranchName = ""
|
||||||
r, err := repo.RunQuiet([]string{"git", "branch", "--show-current"})
|
r := repo.RunQuiet([]string{"git", "branch", "--show-current"})
|
||||||
output := strings.Join(r.Stdout, "\n")
|
output := strings.Join(r.Stdout, "\n")
|
||||||
if err != nil {
|
if r.Error != nil {
|
||||||
log.Log(WARN, "GetCurrentBranchName() not in a git repo?", err, repo.GetGoPath())
|
log.Log(WARN, "GetCurrentBranchName() not in a git repo?", r.Error, repo.GetGoPath())
|
||||||
log.Log(WARN, "GetCurrentBranchName() output might have worked anyway:", output)
|
log.Log(WARN, "GetCurrentBranchName() output might have worked anyway:", output)
|
||||||
}
|
}
|
||||||
repo.CurrentBranchName = strings.TrimSpace(output)
|
repo.CurrentBranchName = strings.TrimSpace(output)
|
||||||
|
@ -111,13 +102,11 @@ func (repo *Repo) setCurrentBranchVersion() {
|
||||||
log.Info("repo.GetCurrentBranchVersion() repo == nil")
|
log.Info("repo.GetCurrentBranchVersion() repo == nil")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
r, err := repo.RunQuiet([]string{"git", "describe", "--tags"})
|
r := repo.RunQuiet([]string{"git", "describe", "--tags", "--always"})
|
||||||
output := strings.Join(r.Stdout, "\n")
|
output := strings.Join(r.Stdout, "\n")
|
||||||
if err != nil {
|
if r.Error != nil {
|
||||||
// log.Log(WARN, "GetCurrentBranchVersion() not in a git repo?", err, repo.GetGoPath())
|
log.Log(WARN, "GetCurrentBranchVersion() not in a git repo?", r.Error, repo.GetGoPath())
|
||||||
// log.Log(WARN, "GetCurrentBranchVersion() output might have worked anyway:", output)
|
log.Log(WARN, "GetCurrentBranchVersion() output might have worked anyway:", output)
|
||||||
repo.CurrentBranchVersion = "gitpb err"
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
repo.CurrentBranchVersion = strings.TrimSpace(output)
|
repo.CurrentBranchVersion = strings.TrimSpace(output)
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,7 @@ func (repo *Repo) CheckBranches() bool {
|
||||||
if hash == hashCheck {
|
if hash == hashCheck {
|
||||||
// log.Info("notsure why this git show is here", hash)
|
// log.Info("notsure why this git show is here", hash)
|
||||||
} else {
|
} else {
|
||||||
// log.Printf("UNKNOWN BRANCH %-50s %s %s %s\n", repo.GetFullPath(), r.Stdout, cmd, b)
|
log.Printf("UNKNOWN BRANCH %-50s %s %s %s\n", repo.GetFullPath(), r.Stdout, cmd, b)
|
||||||
perfect = false
|
perfect = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -170,7 +170,7 @@ func (repo *Repo) ExamineBranches() *GitTag {
|
||||||
if hash == hashCheck {
|
if hash == hashCheck {
|
||||||
// log.Info("notsure why this git show is here", hash)
|
// log.Info("notsure why this git show is here", hash)
|
||||||
} else {
|
} else {
|
||||||
// log.Printf("UNKNOWN BRANCH %-50s %s %s %s\n", repo.GetFullPath(), r.Stdout, cmd, b)
|
log.Printf("UNKNOWN BRANCH %-50s %s %s %s\n", repo.GetFullPath(), r.Stdout, cmd, b)
|
||||||
tag := new(GitTag)
|
tag := new(GitTag)
|
||||||
tag.Refname = b
|
tag.Refname = b
|
||||||
tag.Hash = hash
|
tag.Hash = hash
|
||||||
|
|
|
@ -62,4 +62,5 @@ func (repo *Repo) CheckDirty() bool {
|
||||||
repo.State = "dirty"
|
repo.State = "dirty"
|
||||||
}
|
}
|
||||||
return bad
|
return bad
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,28 +27,16 @@ func (repo *Repo) updateGitConfig() error {
|
||||||
repo.GitConfig.Submodules = make(map[string]string)
|
repo.GitConfig.Submodules = make(map[string]string)
|
||||||
repo.GitConfig.Versions = make(map[string]string)
|
repo.GitConfig.Versions = make(map[string]string)
|
||||||
repo.GitConfig.Hashes = make(map[string]string)
|
repo.GitConfig.Hashes = make(map[string]string)
|
||||||
url, err := repo.readGitConfig()
|
return repo.readGitConfig()
|
||||||
if repo.URL != "" {
|
|
||||||
log.Info("gitpb: url already set", url, repo.URL)
|
|
||||||
}
|
|
||||||
|
|
||||||
if url == "" {
|
|
||||||
log.Info(repo.FullPath, "url was blank. warn user this repo is only on the local disk")
|
|
||||||
} else {
|
|
||||||
repo.URL = url
|
|
||||||
}
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// readGitConfig reads and parses the .git/config file
|
// readGitConfig reads and parses the .git/config file
|
||||||
func (repo *Repo) readGitConfig() (string, error) {
|
func (repo *Repo) readGitConfig() error {
|
||||||
var foundURL string
|
|
||||||
filename := filepath.Join(repo.GetFullPath(), ".git/config")
|
filename := filepath.Join(repo.GetFullPath(), ".git/config")
|
||||||
file, err := os.Open(filename)
|
file, err := os.Open(filename)
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var currentSection string = ""
|
var currentSection string = ""
|
||||||
|
@ -104,13 +92,6 @@ func (repo *Repo) readGitConfig() (string, error) {
|
||||||
log.Log(INFO, "switch currentSection", currentSection, currentName)
|
log.Log(INFO, "switch currentSection", currentSection, currentName)
|
||||||
switch key {
|
switch key {
|
||||||
case "url":
|
case "url":
|
||||||
if foundURL == "" {
|
|
||||||
foundURL = value
|
|
||||||
} else {
|
|
||||||
if foundURL != value {
|
|
||||||
log.Info("TODO: gitpb: handle multiple remotes in the parser", foundURL, value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if test.Url == value {
|
if test.Url == value {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -157,36 +138,16 @@ func (repo *Repo) readGitConfig() (string, error) {
|
||||||
default:
|
default:
|
||||||
log.Log(WARN, "unknown submodule line:", line)
|
log.Log(WARN, "unknown submodule line:", line)
|
||||||
}
|
}
|
||||||
case "diff":
|
|
||||||
// test, ok := rs.gitConfig.submodules[currentName]
|
|
||||||
switch key {
|
|
||||||
case "renameLimit":
|
|
||||||
log.Log(INFO, "name:", line)
|
|
||||||
default:
|
|
||||||
log.Log(WARN, "unknown name line:", filename, line)
|
|
||||||
}
|
|
||||||
case "user":
|
|
||||||
// test, ok := rs.gitConfig.submodules[currentName]
|
|
||||||
switch key {
|
|
||||||
case "name":
|
|
||||||
log.Log(INFO, "name:", line)
|
|
||||||
case "email":
|
|
||||||
log.Log(INFO, "email:", line)
|
|
||||||
default:
|
|
||||||
log.Log(WARN, "unknown name line:", filename, line)
|
|
||||||
}
|
|
||||||
case "git-bug":
|
|
||||||
log.Log(WARN, "repo uses git-bug!", filename)
|
|
||||||
default:
|
default:
|
||||||
log.Log(WARN, filename, "unknown line:", line)
|
log.Log(WARN, "unknown line:", line)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := scanner.Err(); err != nil {
|
if err := scanner.Err(); err != nil {
|
||||||
return "", err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return foundURL, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *Repo) processBranch(branch string) {
|
func (repo *Repo) processBranch(branch string) {
|
|
@ -59,7 +59,7 @@ func (repo *Repo) RepoIgnoresGoMod() error {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if ignored {
|
if ignored {
|
||||||
// fmt.Printf("%s %s is ignored by Git.\n", repo.GetGoPath(), file)
|
fmt.Printf("%s %s is ignored by Git.\n", repo.GetGoPath(), file)
|
||||||
repo.GoInfo.GitIgnoresGoSum = true
|
repo.GoInfo.GitIgnoresGoSum = true
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,29 +23,11 @@ func (repo *Repo) setRepoState() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if repo.GetDevelVersion() != repo.GetMasterVersion() {
|
if repo.GetDevelVersion() != repo.GetMasterVersion() {
|
||||||
if !repo.IsLocalBranch(repo.GetDevelBranchName()) {
|
repo.State = "merge to main"
|
||||||
// the remote devel branch exists but is not checked out
|
|
||||||
repo.State = "no devel branch"
|
|
||||||
return
|
|
||||||
}
|
|
||||||
b1 := repo.CountDiffObjects(repo.GetMasterBranchName(), repo.GetDevelBranchName())
|
|
||||||
if b1 == 0 {
|
|
||||||
repo.State = "merge to main"
|
|
||||||
// log.Info("master vs devel count is normal b1 == 0", b1)
|
|
||||||
} else {
|
|
||||||
repo.State = "DEVEL behind MASTER"
|
|
||||||
// log.Info("master vs devel count b1 != 0", b1)
|
|
||||||
log.Infof("%s devel branch is behind master branch (missing %d commits)\n", repo.GetGoPath(), b1)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// if IsGoTagVersionGreater(oldtag string, newtag string) bool {
|
|
||||||
if !IsGoTagVersionGreater(repo.GetLastTag(), repo.GetMasterVersion()) {
|
|
||||||
repo.State = "last tag greater error"
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if repo.GetLastTag() != repo.GetMasterVersion() {
|
if repo.GetLastTag() != repo.GetMasterVersion() {
|
||||||
repo.State = "ready to release"
|
repo.State = "unchanged"
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,31 +35,8 @@ func (repo *Repo) setRepoState() {
|
||||||
repo.State = "PERFECT"
|
repo.State = "PERFECT"
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
log.Info("Branches are not Perfect", repo.GetFullPath())
|
||||||
|
log.Info("Branches are not Perfect", repo.GetFullPath())
|
||||||
|
log.Info("Branches are not Perfect", repo.GetFullPath())
|
||||||
repo.State = "unknown branches"
|
repo.State = "unknown branches"
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns true if old="v0.2.4" and new="v0.3.3"
|
|
||||||
// returns true if equal
|
|
||||||
// todo: make all of this smarter someday
|
|
||||||
func IsGoTagVersionGreater(oldtag string, newtag string) bool {
|
|
||||||
olda, oldb, oldc := splitInts(oldtag)
|
|
||||||
newa, newb, newc := splitInts(newtag)
|
|
||||||
|
|
||||||
if newa < olda {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if newb < oldb {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if newc < oldc {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// returns true for "v0.2.4" and false for "v0.2.43-asdfj"
|
|
||||||
// actually returns false for anything not perfectly versioned
|
|
||||||
func IsGoTagPublished(oldtag string, newtag string) bool {
|
|
||||||
// todo
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
|
@ -9,8 +9,6 @@ import (
|
||||||
"go.wit.com/log"
|
"go.wit.com/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: this needs to be redone in a smarter way
|
|
||||||
// to identify which repos have things to build in them
|
|
||||||
func (repo *Repo) GetRepoType() string {
|
func (repo *Repo) GetRepoType() string {
|
||||||
if repo == nil {
|
if repo == nil {
|
||||||
return "nil"
|
return "nil"
|
||||||
|
@ -26,6 +24,9 @@ func (repo *Repo) GetRepoType() string {
|
||||||
if repo.GoInfo.GoPlugin {
|
if repo.GoInfo.GoPlugin {
|
||||||
return "plugin"
|
return "plugin"
|
||||||
}
|
}
|
||||||
|
if repo.GoInfo.GoProtobuf {
|
||||||
|
return "protobuf"
|
||||||
|
}
|
||||||
if repo.GoInfo.GoBinary {
|
if repo.GoInfo.GoBinary {
|
||||||
if repo.Exists(".plugin") {
|
if repo.Exists(".plugin") {
|
||||||
log.Warn("gitpb.RepoType() plugin was not set correctly")
|
log.Warn("gitpb.RepoType() plugin was not set correctly")
|
||||||
|
@ -34,10 +35,6 @@ func (repo *Repo) GetRepoType() string {
|
||||||
}
|
}
|
||||||
return "binary"
|
return "binary"
|
||||||
}
|
}
|
||||||
// binary should always take precidence over libraries that are protobuf's
|
|
||||||
if repo.GoInfo.GoProtobuf {
|
|
||||||
return "protobuf"
|
|
||||||
}
|
|
||||||
if repo.GoInfo.GoLibrary {
|
if repo.GoInfo.GoLibrary {
|
||||||
return "library"
|
return "library"
|
||||||
}
|
}
|
||||||
|
@ -51,9 +48,11 @@ func (repo *Repo) setRepoType() {
|
||||||
}
|
}
|
||||||
if repo.Exists(".plugin") {
|
if repo.Exists(".plugin") {
|
||||||
repo.GoInfo.GoPlugin = true
|
repo.GoInfo.GoPlugin = true
|
||||||
|
return
|
||||||
}
|
}
|
||||||
if ok, _, _ := repo.IsProtobuf(); ok {
|
if ok, _, _ := repo.IsProtobuf(); ok {
|
||||||
repo.GoInfo.GoProtobuf = true
|
repo.GoInfo.GoProtobuf = true
|
||||||
|
return
|
||||||
}
|
}
|
||||||
switch repo.goListRepoType() {
|
switch repo.goListRepoType() {
|
||||||
case "binary":
|
case "binary":
|
||||||
|
@ -71,9 +70,9 @@ func (repo *Repo) goListRepoType() string {
|
||||||
// cmd := []string{"go", "list", "-f", "'{{.Name}}'"} // probably use this. this just prints out the package name
|
// cmd := []string{"go", "list", "-f", "'{{.Name}}'"} // probably use this. this just prints out the package name
|
||||||
// cmd := []string{"go", "list", "-f", "'{{.ImportPath}}'"} // returns go.wit.com/lib/protobuf/gitpb
|
// cmd := []string{"go", "list", "-f", "'{{.ImportPath}}'"} // returns go.wit.com/lib/protobuf/gitpb
|
||||||
|
|
||||||
result, err := repo.RunQuiet(cmd)
|
result := repo.RunQuiet(cmd)
|
||||||
if err != nil {
|
if result.Error != nil {
|
||||||
// log.Info("go list binary detect failed", err)
|
log.Warn("go list binary detect failed", result.Error)
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
output := strings.TrimSpace(strings.Join(result.Stdout, "\n"))
|
output := strings.TrimSpace(strings.Join(result.Stdout, "\n"))
|
||||||
|
|
|
@ -11,31 +11,6 @@ import (
|
||||||
timestamppb "google.golang.org/protobuf/types/known/timestamppb"
|
timestamppb "google.golang.org/protobuf/types/known/timestamppb"
|
||||||
)
|
)
|
||||||
|
|
||||||
// redo this. use go-git2 ?
|
|
||||||
func (repo *Repo) allCommits() error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
// this is dumb
|
|
||||||
func (repo *Repo) AllCommits() error {
|
|
||||||
// tags := []string{"cd", "%(creatordate)", "%(*authordate)", "%(refname)", "%(subject)"}
|
|
||||||
// format := strings.Join(tags, "_,,,_%")
|
|
||||||
|
|
||||||
cmd := []string{"git", "log", "--format=%cd"}
|
|
||||||
result := shell.PathRunQuiet(repo.FullPath, cmd)
|
|
||||||
if result.Error != nil {
|
|
||||||
log.Warn("git for-each-ref error:", result.Error)
|
|
||||||
return result.Error
|
|
||||||
}
|
|
||||||
newest := strings.Join(result.Stdout, "\n")
|
|
||||||
newest = strings.TrimSpace(newest)
|
|
||||||
tmp := getGitDateStamp(newest)
|
|
||||||
repo.Times.NewestCommit = timestamppb.New(tmp)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// reload the tags
|
// reload the tags
|
||||||
func (repo *Repo) reloadGitTags() error {
|
func (repo *Repo) reloadGitTags() error {
|
||||||
// todo: look for changes in the tags?
|
// todo: look for changes in the tags?
|
||||||
|
@ -92,14 +67,7 @@ func (repo *Repo) reloadGitTags() error {
|
||||||
repo.Tags.Append(&newr)
|
repo.Tags.Append(&newr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GIT_COMMITTER_DATE="$(git log -1 --format=%cI)" \
|
|
||||||
// GIT_AUTHOR_DATE="$(git log -1 --format=%aI)" \
|
|
||||||
// git am --committer-date-is-author-date < patch.mbox
|
|
||||||
|
|
||||||
// good format for insuring the hashs are identical when using git am
|
|
||||||
// git log -1 --format="%H %aI %cI %an %ae %cn %ce"
|
|
||||||
// also set the repo.NewestCommit
|
// also set the repo.NewestCommit
|
||||||
|
|
||||||
cmd = []string{"git", "log", "-1", "--format=%cd"}
|
cmd = []string{"git", "log", "-1", "--format=%cd"}
|
||||||
result = shell.PathRunQuiet(repo.FullPath, cmd)
|
result = shell.PathRunQuiet(repo.FullPath, cmd)
|
||||||
if result.Error != nil {
|
if result.Error != nil {
|
||||||
|
@ -168,16 +136,11 @@ func (repo *Repo) NewestTag() *GitTag {
|
||||||
}
|
}
|
||||||
|
|
||||||
// this should just do is.Exists(".git/refs/heads/findname")
|
// this should just do is.Exists(".git/refs/heads/findname")
|
||||||
// this is a simple check and doesn't work all the time
|
|
||||||
func (repo *Repo) LocalTagExists(findname string) bool {
|
func (repo *Repo) LocalTagExists(findname string) bool {
|
||||||
fname := filepath.Join(".git/refs/heads", findname)
|
fname := filepath.Join(".git/refs/heads", findname)
|
||||||
if repo.Exists(fname) {
|
if repo.Exists(fname) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
fname = filepath.Join(".git/refs/tags", findname)
|
|
||||||
if repo.Exists(fname) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
/*
|
/*
|
||||||
loop := repo.Tags.SortByRefname()
|
loop := repo.Tags.SortByRefname()
|
||||||
for loop.Scan() {
|
for loop.Scan() {
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
// Code generated by go.wit.com/apps/autogenpb DO NOT EDIT.
|
|
||||||
// This file was autogenerated with autogenpb v0.0.78 2025-08-31_15:49:04_UTC
|
|
||||||
// go install go.wit.com/apps/autogenpb@latest
|
|
||||||
//
|
|
||||||
// define which structs (messages) you want to use in the .proto file
|
|
||||||
// Then sort.pb.go and marshal.pb.go files are autogenerated
|
|
||||||
//
|
|
||||||
// autogenpb uses it and has an example .proto file with instructions
|
|
||||||
//
|
|
||||||
|
|
||||||
package gitpb
|
|
||||||
|
|
||||||
func (t *ReposTable) MyMasterBranch() *RepoStringFunc {
|
|
||||||
sf := t.AddStringFunc("master", func(m *Repo) string {
|
|
||||||
return m.MasterBranchName
|
|
||||||
})
|
|
||||||
sf.Width = 30
|
|
||||||
return sf
|
|
||||||
}
|
|
|
@ -1,92 +1,44 @@
|
||||||
package gitpb
|
package gitpb
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/go-cmd/cmd"
|
"github.com/go-cmd/cmd"
|
||||||
"go.wit.com/log"
|
"go.wit.com/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *Repo) MergeToDevel() (*cmd.Status, error) {
|
func (rs *Repo) MergeUserToDevel() (*cmd.Status, error) {
|
||||||
r.Reload()
|
startbranch := rs.GetCurrentBranchName()
|
||||||
if r.GetCurrentBranchName() != r.GetDevelBranchName() {
|
devel := rs.GetDevelBranchName()
|
||||||
return nil, fmt.Errorf("repo not on devel branch")
|
user := rs.GetUserBranchName()
|
||||||
}
|
|
||||||
if r.CheckDirty() {
|
|
||||||
return nil, fmt.Errorf("repo is dirty")
|
|
||||||
}
|
|
||||||
devel := r.GetDevelBranchName()
|
|
||||||
user := r.GetUserBranchName()
|
|
||||||
|
|
||||||
log.Info(r.FullPath, "MergeToDevel() merging from", user, "into", devel)
|
log.Info("MergeUserToDevel() checking out", devel, "started on", startbranch, "merge", user)
|
||||||
|
|
||||||
cmd := []string{"git", "merge", user}
|
var all [][]string
|
||||||
result := r.RunRealtimeVerbose(cmd)
|
all = append(all, []string{"git", "checkout", devel})
|
||||||
if result.Error != nil {
|
all = append(all, []string{"git", "merge", user})
|
||||||
log.Log(WARN, "MergeToDevel() failed", r.GetFullPath())
|
all = append(all, []string{"git", "push"})
|
||||||
return nil, result.Error
|
|
||||||
}
|
|
||||||
|
|
||||||
if !r.IsBranchRemote(devel) {
|
if result, err := rs.RunStrictAll(all); err != nil {
|
||||||
r.Reload() // rescan the repo
|
log.Log(WARN, "MergeUserToDevel() failed", rs.GetFullPath())
|
||||||
// devel branch is not remote. do not try 'git push'
|
return result, err
|
||||||
return nil, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// it seems like we have write access. lets find out!
|
|
||||||
cmd = []string{"git", "push"}
|
|
||||||
result = r.RunRealtimeVerbose(cmd)
|
|
||||||
if result.Error != nil {
|
|
||||||
log.Log(WARN, "GitPushToDevel() failed", r.GetFullPath())
|
|
||||||
return nil, result.Error
|
|
||||||
}
|
|
||||||
r.Reload() // rescan the repo
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Repo) MergeToMaster() (*cmd.Status, error) {
|
func (rs *Repo) MergeDevelToMaster() (*cmd.Status, error) {
|
||||||
r.Reload()
|
startbranch := rs.GetCurrentBranchName()
|
||||||
|
devel := rs.GetDevelBranchName()
|
||||||
|
main := rs.GetMasterBranchName()
|
||||||
|
|
||||||
if r.GetCurrentBranchName() != r.GetMasterBranchName() {
|
log.Info("MergeDevelToMaster() checking out", main, "started on", startbranch, "merge", devel)
|
||||||
return nil, fmt.Errorf("repo not on master branch")
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
if r.GetReadOnly() {
|
|
||||||
r.Reload() // rescan the repo
|
|
||||||
// master branch is read only. you can not git push
|
|
||||||
lh := r.GetLocalHash("devel")
|
|
||||||
rh := r.GetRemoteHash("devel")
|
|
||||||
if lh == rh {
|
|
||||||
// log.Info(r.FullPath, "local devel == remote devel", lh, rh)
|
|
||||||
} else {
|
|
||||||
log.Info(r.FullPath, "local devel != remote devel", lh, rh)
|
|
||||||
}
|
|
||||||
log.Info("can't merge to master on read only() repos. trying anyway")
|
|
||||||
// return nil, fmt.Errorf("can't merge to master on read only() repos")
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
if r.CheckDirty() {
|
|
||||||
return nil, fmt.Errorf("repo is dirty")
|
|
||||||
}
|
|
||||||
master := r.GetMasterBranchName()
|
|
||||||
devel := r.GetDevelBranchName()
|
|
||||||
|
|
||||||
log.Info("MergeToMaster() merging from", devel, "into", master)
|
var all [][]string
|
||||||
|
all = append(all, []string{"git", "checkout", main})
|
||||||
|
all = append(all, []string{"git", "merge", devel})
|
||||||
|
all = append(all, []string{"git", "push"})
|
||||||
|
|
||||||
cmd := []string{"git", "merge", devel}
|
if result, err := rs.RunStrictAll(all); err != nil {
|
||||||
result := r.RunRealtimeVerbose(cmd)
|
log.Log(WARN, "MergeDevelToMaster() failed", rs.GetFullPath())
|
||||||
if result.Error != nil {
|
return result, err
|
||||||
log.Log(WARN, "MergeToMaster() failed", r.GetFullPath())
|
|
||||||
return nil, result.Error
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// it seems like we have write access. lets find out!
|
|
||||||
cmd = []string{"git", "push"}
|
|
||||||
result = r.RunRealtimeVerbose(cmd)
|
|
||||||
if result.Error != nil {
|
|
||||||
log.Log(WARN, "GitPushToMaster() failed", r.GetFullPath())
|
|
||||||
return nil, result.Error
|
|
||||||
}
|
|
||||||
r.Reload() // rescan the repo
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
70
repo.new.go
70
repo.new.go
|
@ -2,8 +2,6 @@ package gitpb
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"net/url"
|
|
||||||
"path/filepath"
|
|
||||||
|
|
||||||
"go.wit.com/log"
|
"go.wit.com/log"
|
||||||
)
|
)
|
||||||
|
@ -27,8 +25,7 @@ func (all *Repos) NewGoRepo(fullpath string, gopath string) (*Repo, error) {
|
||||||
|
|
||||||
// add a new one here
|
// add a new one here
|
||||||
newr := Repo{
|
newr := Repo{
|
||||||
FullPath: fullpath,
|
FullPath: fullpath,
|
||||||
Namespace: gopath,
|
|
||||||
}
|
}
|
||||||
newr.Times = new(GitTimes)
|
newr.Times = new(GitTimes)
|
||||||
|
|
||||||
|
@ -37,7 +34,6 @@ func (all *Repos) NewGoRepo(fullpath string, gopath string) (*Repo, error) {
|
||||||
// everything happens in here
|
// everything happens in here
|
||||||
newr.Reload()
|
newr.Reload()
|
||||||
|
|
||||||
newr.ValidateUTF8()
|
|
||||||
if all.AppendByFullPath(&newr) {
|
if all.AppendByFullPath(&newr) {
|
||||||
// worked
|
// worked
|
||||||
return &newr, nil
|
return &newr, nil
|
||||||
|
@ -53,10 +49,7 @@ func (all *Repos) NewGoRepo(fullpath string, gopath string) (*Repo, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// enforces GoPath is unique
|
// enforces GoPath is unique
|
||||||
// TODO: deprecate this (?)
|
func (all *Repos) AppendByGoPath(newr *Repo) bool {
|
||||||
// mutex's should finally work in the autogenpb protobuf code
|
|
||||||
/*
|
|
||||||
func (all *Repos) AppendByGoPathOld(newr *Repo) bool {
|
|
||||||
// all.RLock()
|
// all.RLock()
|
||||||
repoMu.RLock()
|
repoMu.RLock()
|
||||||
|
|
||||||
|
@ -70,64 +63,7 @@ func (all *Repos) AppendByGoPathOld(newr *Repo) bool {
|
||||||
// all.RUnlock()
|
// all.RUnlock()
|
||||||
repoMu.RUnlock()
|
repoMu.RUnlock()
|
||||||
|
|
||||||
|
// all.Repos = append(all.Repos, newr)
|
||||||
all.Append(newr)
|
all.Append(newr)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
func (all *Repos) NewRepo(fullpath string, namespace string) (*Repo, error) {
|
|
||||||
if r := all.FindByFullPath(fullpath); r != nil {
|
|
||||||
log.Info("gitpb.NewRepo() might already have namespace", r.GetNamespace())
|
|
||||||
log.Info("gitpb.NewRepo() already has FullPath", r.FullPath)
|
|
||||||
// already had this gopath
|
|
||||||
return r, errors.New("gitpb.NewRepo() duplicate path " + fullpath)
|
|
||||||
}
|
|
||||||
|
|
||||||
// add a new one here
|
|
||||||
newr := Repo{
|
|
||||||
FullPath: fullpath,
|
|
||||||
Namespace: namespace,
|
|
||||||
}
|
|
||||||
newr.Times = new(GitTimes)
|
|
||||||
|
|
||||||
// everything happens in here
|
|
||||||
newr.Reload()
|
|
||||||
|
|
||||||
newr.ValidateUTF8()
|
|
||||||
if all.AppendByFullPath(&newr) {
|
|
||||||
// worked
|
|
||||||
return &newr, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// todo: use Repos.Lock()
|
|
||||||
return nil, errors.New("gitpb.NewRepo() append failed " + fullpath)
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewRepo(fullpath string) (*Repo, error) {
|
|
||||||
// add a new one here
|
|
||||||
repo := Repo{
|
|
||||||
FullPath: fullpath,
|
|
||||||
}
|
|
||||||
repo.Times = new(GitTimes)
|
|
||||||
|
|
||||||
// everything happens in here
|
|
||||||
repo.Reload()
|
|
||||||
repo.ValidateUTF8()
|
|
||||||
if repo.Namespace == "" {
|
|
||||||
giturl := repo.GetURL()
|
|
||||||
if giturl == "" {
|
|
||||||
log.Info(repo.FullPath, "Namespace & URL are both blank. Warn the user of a local repo.")
|
|
||||||
return &repo, nil
|
|
||||||
}
|
|
||||||
// log.Info("GET Namespace from URL", giturl)
|
|
||||||
tmpURL, err := url.Parse(giturl)
|
|
||||||
if err != nil {
|
|
||||||
log.Info(repo.FullPath, "URL parse failed", giturl, err)
|
|
||||||
return &repo, nil
|
|
||||||
}
|
|
||||||
// log.Info(repo.FullPath, "namespace might be:", tmpURL.Hostname(), tmpURL.Path)
|
|
||||||
repo.Namespace = filepath.Join(tmpURL.Hostname(), tmpURL.Path)
|
|
||||||
// log.Info(repo.FullPath, "Namesapce =", repo.Namespace)
|
|
||||||
}
|
|
||||||
return &repo, nil
|
|
||||||
}
|
|
||||||
|
|
121
repo.proto
121
repo.proto
|
@ -11,72 +11,65 @@ import "google/protobuf/timestamp.proto"; // Import the well-known type for Time
|
||||||
|
|
||||||
// global settings for autogenpb `autogenpb:mutex`
|
// global settings for autogenpb `autogenpb:mutex`
|
||||||
|
|
||||||
// should it be done this way?
|
message Repo { // `autogenpb:marshal` `autogenpb:nomutex`
|
||||||
|
string fullPath = 1; // `autogenpb:unique` `autogenpb:sort` // the actual path to the .git directory: '/home/devel/golang.org/x/tools'
|
||||||
|
string masterBranchName = 3; // git 'main' or 'master' branch name
|
||||||
|
string develBranchName = 4; // whatever the git 'devel' branch name is
|
||||||
|
string userBranchName = 5; // whatever your username branch is
|
||||||
|
bool dirty = 6; // if git says things have been changed
|
||||||
|
string URL = 7; // the URL
|
||||||
|
GitTags tags = 8; // known tags
|
||||||
|
GitTimes times = 9; // store all the mtime values here. these are temporary
|
||||||
|
GoInfo goInfo = 10; // put all the go specifcs here
|
||||||
|
GoDeps goDeps = 11; // what is in the go.sum file
|
||||||
|
string currentBranchName = 12; // the branch currently checked out
|
||||||
|
string currentBranchVersion = 13; // the branch currently checked out
|
||||||
|
string lastTag = 14; // the oldest tag
|
||||||
|
string targetVersion = 15; // useful during the package release process
|
||||||
|
bool readOnly = 16; // tracks access to 'git push'
|
||||||
|
string desc = 17; // what is this repo?
|
||||||
|
string stateChange = 18; // used for debugging tool logic
|
||||||
|
string masterVersion = 19; // just store this for now
|
||||||
|
string develVersion = 20; //
|
||||||
|
string userVersion = 21; //
|
||||||
|
repeated string dirtyList = 22; // store the list from git status --porcelain
|
||||||
|
string state = 23; // status or state. useful for building tooling
|
||||||
|
GitTag currentTag = 24; // used to examine repo branches
|
||||||
|
GitConfig gitConfig = 25; // protobuf of the current .git/config
|
||||||
|
}
|
||||||
|
|
||||||
message GitTimes { // `autogenpb:nomutex`
|
message Repos { // `autogenpb:marshal` `autogenpb:sort` `autogenpb:nomutex`
|
||||||
google.protobuf.Timestamp lastPull = 1; // last time a git pull was done
|
string uuid = 1; // `autogenpb:uuid:8daaeba1-fb1f-4762-ae6e-95a55d352673`
|
||||||
google.protobuf.Timestamp lastUpdate = 2; // when was ReloadGit() last done
|
string version = 2; // `autogenpb:version:v3`
|
||||||
google.protobuf.Timestamp lastDirty = 3; // last time CheckDirty() was run
|
repeated Repo repos = 3; // `autogenpb:append` // generate AppendUnique() function for this
|
||||||
google.protobuf.Timestamp mtimeDir = 4; // mtime for ./git // maybe useful to track
|
}
|
||||||
google.protobuf.Timestamp mtimeHead = 5; // mtime for ./git/HEAD // these two mtimes allow really fast checks to see if git has changed
|
|
||||||
google.protobuf.Timestamp mtimeIndex = 6; // mtime for ./git/HEAD // probably always in sync with HEAD
|
// should it be done this way?
|
||||||
google.protobuf.Timestamp mtimeFetch = 7; // mtime for ./git/FETCH_HEAD // last time 'git fetch' or 'git pull' was run on current branch?
|
message GitTimes { // `autogenpb:nomutex`
|
||||||
google.protobuf.Timestamp lastGoDep = 8; // mtime for last go.sum scan
|
google.protobuf.Timestamp lastPull = 1; // last time a git pull was done
|
||||||
google.protobuf.Timestamp newestCommit = 9; // when the newest commit was
|
google.protobuf.Timestamp lastUpdate = 2; // when was ReloadGit() last done
|
||||||
google.protobuf.Timestamp mtimeConfig = 10; // mtime for the .git/config file
|
google.protobuf.Timestamp lastDirty = 3; // last time CheckDirty() was run
|
||||||
|
google.protobuf.Timestamp mtimeDir = 4; // mtime for ./git // maybe useful to track
|
||||||
|
google.protobuf.Timestamp mtimeHead = 5; // mtime for ./git/HEAD // these two mtimes allow really fast checks to see if git has changed
|
||||||
|
google.protobuf.Timestamp mtimeIndex = 6; // mtime for ./git/HEAD // probably always in sync with HEAD
|
||||||
|
google.protobuf.Timestamp mtimeFetch = 7; // mtime for ./git/FETCH_HEAD // last time 'git fetch' or 'git pull' was run on current branch?
|
||||||
|
google.protobuf.Timestamp lastGoDep = 8; // mtime for last go.sum scan
|
||||||
|
google.protobuf.Timestamp newestCommit = 9; // when the newest commit was
|
||||||
|
google.protobuf.Timestamp mtimeConfig = 10; // mtime for the .git/config file
|
||||||
}
|
}
|
||||||
|
|
||||||
// this is probably better. think about moving to this instead
|
// this is probably better. think about moving to this instead
|
||||||
message GoInfo { // `autogenpb:nomutex`
|
message GoInfo { // `autogenpb:nomutex`
|
||||||
string goPath = 1; // the logical path as used by golang: 'go.wit.com/apps/helloworld'
|
string goPath = 1; // the logical path as used by golang: 'go.wit.com/apps/helloworld'
|
||||||
string desc = 2; // what is this repo?
|
string desc = 2; // what is this repo?
|
||||||
bool goLibrary = 3; // is this a golang library?
|
bool goLibrary = 3; // is this a golang library?
|
||||||
bool goBinary = 4; // is this a golang binary?
|
bool goBinary = 4; // is this a golang binary?
|
||||||
bool goPrimitive = 5; // if this is a golang primitive (only has go.mod)
|
bool goPrimitive = 5; // if this is a golang primitive (only has go.mod)
|
||||||
bool goPlugin = 6; // is this a golang plugin?
|
bool goPlugin = 6; // is this a golang plugin?
|
||||||
bool goProtobuf = 7; // autogen go files from .proto
|
bool goProtobuf = 7; // autogen go files from .proto
|
||||||
GoDeps goDeps = 8; // what is in the go.sum file
|
GoDeps goDeps = 8; // what is in the go.sum file
|
||||||
GoDeps published = 9; // the last published go.mod/go.sum
|
GoDeps published = 9; // the last published go.mod/go.sum
|
||||||
bytes goMod = 10; // the last go.mod file
|
bytes goMod = 10; // the last go.mod file
|
||||||
bytes goSum = 11; // the last go.sum file
|
bytes goSum = 11; // the last go.sum file
|
||||||
bool gitIgnoresGoSum = 12; // does .gitignore ignore go.mod & go.sum?
|
bool gitIgnoresGoSum = 12; // does .gitignore ignore go.mod & go.sum?
|
||||||
}
|
|
||||||
|
|
||||||
message Repo { // `autogenpb:marshal` `autogenpb:nomutex`
|
|
||||||
string namespace = 1; // `autogenpb:unique` `autogenpb:sort` // this repo is 'go.wit.com/lib/protobuf/gitpb'
|
|
||||||
string fullPath = 2; // `autogenpb:unique` `autogenpb:sort` // the OS path to the .git directory: '/home/devel/golang.org/x/tools'
|
|
||||||
string masterBranchName = 3; // git 'main' or 'master' branch name
|
|
||||||
string develBranchName = 4; // whatever the git 'devel' branch name is
|
|
||||||
string userBranchName = 5; // whatever your username branch is
|
|
||||||
bool dirty = 6; // if git says things have been changed
|
|
||||||
string URL = 7; // the URL
|
|
||||||
GitTags tags = 8; // known tags
|
|
||||||
GitTimes times = 9; // store all the mtime values here. these are temporary
|
|
||||||
GoInfo goInfo = 10; // put all the go specifcs here
|
|
||||||
GoDeps goDeps = 11; // what is in the go.sum file
|
|
||||||
string currentBranchName = 12; // the branch currently checked out
|
|
||||||
string currentBranchVersion = 13; // the branch currently checked out
|
|
||||||
string lastTag = 14; // the oldest tag
|
|
||||||
string targetVersion = 15; // useful during the package release process
|
|
||||||
bool readOnly = 16; // tracks access to 'git push'
|
|
||||||
string desc = 17; // what is this repo?
|
|
||||||
string stateChange = 18; // used for debugging tool logic
|
|
||||||
string masterVersion = 19; // just store this for now
|
|
||||||
string develVersion = 20; //
|
|
||||||
string userVersion = 21; //
|
|
||||||
repeated string dirtyList = 22; // store the list from git status --porcelain
|
|
||||||
string state = 23; // status or state. useful for building tooling
|
|
||||||
GitTag currentTag = 24; // used to examine repo branches
|
|
||||||
GitConfig gitConfig = 25; // protobuf of the current .git/config
|
|
||||||
string MasterHash = 26; // hash of the current master branch
|
|
||||||
string DevelHash = 27; // hash of the current devel branch
|
|
||||||
map<string, string> control = 28; // control values. can be used to make packages (like .deb or .rpm)
|
|
||||||
}
|
|
||||||
|
|
||||||
message Repos { // `autogenpb:marshal` `autogenpb:sort` `autogenpb:gui` `autogenpb:nomutex` `autogenpb:http`
|
|
||||||
string uuid = 1; // `autogenpb:uuid:8daaeba1-fb1f-4762-ae6e-95a55d352673`
|
|
||||||
string version = 2; // `autogenpb:version:v4`
|
|
||||||
repeated Repo repos = 3; // `autogenpb:append` // generate AppendUnique() function for this
|
|
||||||
bool hasFullScan = 4; // a full repo scan has been saved to disk
|
|
||||||
google.protobuf.Timestamp fullScan = 5; // mtime of the last full scan saved to disk
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,23 +9,6 @@ import (
|
||||||
"go.wit.com/log"
|
"go.wit.com/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
// does this repo build a binary?
|
|
||||||
func (r *Repo) IsBinary() bool {
|
|
||||||
if r.GoInfo != nil {
|
|
||||||
return r.GoInfo.GetGoBinary()
|
|
||||||
}
|
|
||||||
// todo: detect C & other language binary packages
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// does this repo build a binary?
|
|
||||||
func (r *Repo) IsGoPlugin() bool {
|
|
||||||
if r.GoInfo != nil {
|
|
||||||
return r.GoInfo.GetGoPlugin()
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// This returns the list of autogenerated protobuf files
|
// This returns the list of autogenerated protobuf files
|
||||||
// it assumes any file *.pb.go is autogenerated
|
// it assumes any file *.pb.go is autogenerated
|
||||||
//
|
//
|
2
rill.go
2
rill.go
|
@ -29,7 +29,7 @@ func (repo *Repo) GitPull() (*cmd.Status, error) {
|
||||||
*/
|
*/
|
||||||
var cmd []string
|
var cmd []string
|
||||||
cmd = append(cmd, "git", "pull")
|
cmd = append(cmd, "git", "pull")
|
||||||
return nil, repo.RunVerbose(cmd)
|
return repo.RunVerbose(cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
// rill is awesome. long live rill
|
// rill is awesome. long live rill
|
||||||
|
|
70
shell.go
70
shell.go
|
@ -25,6 +25,11 @@ func (repo *Repo) Run(cmd []string) cmd.Status {
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (repo *Repo) RunQuiet(cmd []string) cmd.Status {
|
||||||
|
result := shell.PathRunQuiet(repo.FullPath, cmd)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
func (repo *Repo) RunEcho(cmd []string) cmd.Status {
|
func (repo *Repo) RunEcho(cmd []string) cmd.Status {
|
||||||
result := shell.PathRunQuiet(repo.FullPath, cmd)
|
result := shell.PathRunQuiet(repo.FullPath, cmd)
|
||||||
log.Log(NOW, "cmd:", repo.FullPath, cmd)
|
log.Log(NOW, "cmd:", repo.FullPath, cmd)
|
||||||
|
@ -43,32 +48,41 @@ func (repo *Repo) RunRealtime(cmd []string) cmd.Status {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *Repo) RunRealtimeVerbose(cmd []string) cmd.Status {
|
func (repo *Repo) RunRealtimeVerbose(cmd []string) cmd.Status {
|
||||||
log.Log(NOW, "EXEC: cd", repo.GetFullPath(), ";", cmd)
|
log.Log(NOW, "Run:", repo.GetFullPath(), cmd)
|
||||||
return shell.PathRunRealtime(repo.GetFullPath(), cmd)
|
return shell.PathRunRealtime(repo.GetFullPath(), cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *Repo) RunQuiet(cmd []string) (*cmd.Status, error) {
|
// error if result.Error or if result.Exit != 0
|
||||||
result := shell.PathRunQuiet(repo.FullPath, cmd)
|
func (repo *Repo) RunStrict(cmd []string) error {
|
||||||
|
return repo.StrictRun(cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (repo *Repo) StrictRun(cmd []string) error {
|
||||||
|
result := repo.RunQuiet(cmd)
|
||||||
|
if result.Error != nil {
|
||||||
|
log.Warn(repo.GetGoPath(), cmd, "wow. golang is cool. an os.Error:", result.Error)
|
||||||
|
return result.Error
|
||||||
|
}
|
||||||
|
if result.Exit != 0 {
|
||||||
|
log.Warn(cmd, "failed with", result.Exit)
|
||||||
|
return errors.New(fmt.Sprint(cmd, "failed with", result.Exit))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (repo *Repo) RunStrictNew(cmd []string) (*cmd.Status, error) {
|
||||||
|
result := repo.RunQuiet(cmd)
|
||||||
if result.Error != nil {
|
if result.Error != nil {
|
||||||
log.Warn(repo.GetGoPath(), cmd, "wow. golang is cool. an os.Error:", result.Error)
|
log.Warn(repo.GetGoPath(), cmd, "wow. golang is cool. an os.Error:", result.Error)
|
||||||
return &result, result.Error
|
return &result, result.Error
|
||||||
}
|
}
|
||||||
if result.Exit != 0 {
|
if result.Exit != 0 {
|
||||||
// log.Warn(cmd, "failed with", result.Exit, repo.GetGoPath())
|
log.Warn(cmd, "failed with", result.Exit)
|
||||||
return &result, errors.New(fmt.Sprint(cmd, "failed with", result.Exit))
|
return &result, errors.New(fmt.Sprint(cmd, "failed with", result.Exit))
|
||||||
}
|
}
|
||||||
return &result, nil
|
return &result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *Repo) RunStrict(cmd []string) (*cmd.Status, error) {
|
|
||||||
result, err := repo.RunQuiet(cmd)
|
|
||||||
if err != nil {
|
|
||||||
log.Warn(cmd, "failed with", result.Exit, repo.GetGoPath())
|
|
||||||
return result, errors.New(fmt.Sprint(cmd, "failed with", result.Exit))
|
|
||||||
}
|
|
||||||
return result, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (repo *Repo) Exists(filename string) bool {
|
func (repo *Repo) Exists(filename string) bool {
|
||||||
if repo == nil {
|
if repo == nil {
|
||||||
return false
|
return false
|
||||||
|
@ -129,25 +143,30 @@ func (repo *Repo) RunAll(all [][]string) bool {
|
||||||
func (repo *Repo) RunStrictAll(all [][]string) (*cmd.Status, error) {
|
func (repo *Repo) RunStrictAll(all [][]string) (*cmd.Status, error) {
|
||||||
for _, cmd := range all {
|
for _, cmd := range all {
|
||||||
log.Log(WARN, "doAll() RUNNING: cmd =", cmd)
|
log.Log(WARN, "doAll() RUNNING: cmd =", cmd)
|
||||||
if result, err := repo.RunStrict(cmd); err != nil {
|
if result, err := repo.RunStrictNew(cmd); err != nil {
|
||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *Repo) RunVerbose(cmd []string) error {
|
func (repo *Repo) RunVerbose(cmd []string) (*cmd.Status, error) {
|
||||||
// log.Info("EXEC Running:", repo.GetGoPath(), cmd)
|
log.Info("Running:", repo.GetGoPath(), cmd)
|
||||||
err := shell.PathExecVerbose(repo.GetFullPath(), cmd)
|
r, err := repo.RunStrictNew(cmd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Info("Error", cmd, err)
|
log.Info("Error", cmd, err)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
return nil
|
for _, line := range r.Stdout {
|
||||||
|
log.Info(line)
|
||||||
|
}
|
||||||
|
for _, line := range r.Stderr {
|
||||||
|
log.Info(line)
|
||||||
|
}
|
||||||
|
return r, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *Repo) RunVerboseOnError(cmd []string) (*cmd.Status, error) {
|
func (repo *Repo) RunVerboseOnError(cmd []string) (*cmd.Status, error) {
|
||||||
r, err := repo.RunStrict(cmd)
|
r, err := repo.RunStrictNew(cmd)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return r, err
|
return r, err
|
||||||
}
|
}
|
||||||
|
@ -174,14 +193,3 @@ func (repo *Repo) ConstructGitDiffLog(branch1, branch2 string) []string {
|
||||||
cmd = append(cmd, branch2)
|
cmd = append(cmd, branch2)
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
// count all objects only in branch1
|
|
||||||
func (repo *Repo) CountDiffObjects(branch1, branch2 string) int {
|
|
||||||
cmd := repo.ConstructGitDiffLog(branch1, branch2)
|
|
||||||
r, err := repo.RunVerboseOnError(cmd)
|
|
||||||
if err != nil {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
// log.Info("countDiffObjects()", cmd, len(r.Stdout), strings.Join(r.Stdout, " "))
|
|
||||||
return len(r.Stdout)
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue