summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--age.go70
-rw-r--r--changed.go97
-rw-r--r--goDep.redoGoMod.go24
-rw-r--r--reload.go39
-rw-r--r--repo.new.go78
-rw-r--r--repo.proto31
-rw-r--r--rill.go15
-rw-r--r--shell.go11
8 files changed, 259 insertions, 106 deletions
diff --git a/age.go b/age.go
new file mode 100644
index 0000000..d70c863
--- /dev/null
+++ b/age.go
@@ -0,0 +1,70 @@
+package gitpb
+
+// functions that check the ages of files
+// and track if the repo needs to be re-scanned
+
+import (
+ "errors"
+ "os"
+ "path/filepath"
+ "time"
+
+ "go.wit.com/log"
+)
+
+func (repo *Repo) LastGitPull() (time.Time, error) {
+ return repo.oldMtime(".git/FETCH_HEAD")
+}
+
+func (repo *Repo) GoSumAge() (time.Duration, error) {
+ var mtime time.Time
+ var err error
+ mtime, err = repo.oldMtime("go.sum")
+ if err == nil {
+ return time.Since(mtime), nil
+ }
+ mtime, err = repo.oldMtime("go.mod")
+ if err == nil {
+ return time.Since(mtime), nil
+ }
+ now := time.Now()
+ return time.Since(now), errors.New(repo.GoPath + " go.mod missing")
+}
+
+func (repo *Repo) GitChanged() bool {
+ fullfile := filepath.Join(repo.FullPath, ".git/FETCH_HEAD")
+ lasttime, err := repo.LastGitPull()
+ if err == nil {
+ // if error, something is wrong, assume true
+ log.Info("gitpb:", fullfile, "changed")
+ return true
+ }
+ newtime := repo.LastPull.AsTime()
+
+ if lasttime == newtime {
+ return false
+ }
+ log.Info("gitpb:", fullfile, "changed")
+ return true
+}
+
+func (repo *Repo) GitPullAge() time.Duration {
+ lastpull, err := repo.LastGitPull()
+ if err == nil {
+ // if error, something is wrong, assume true
+ ltime := repo.LastPull.AsTime()
+ return time.Since(ltime)
+ }
+
+ return time.Since(lastpull)
+}
+
+func (repo *Repo) oldMtime(filename string) (time.Time, error) {
+ pathf := filepath.Join(repo.FullPath, filename)
+ statf, err := os.Stat(pathf)
+ if err == nil {
+ return statf.ModTime(), nil
+ }
+ log.Log(GITPBWARN, "Mtime() os.Stat() error", pathf, err)
+ return time.Now(), err
+}
diff --git a/changed.go b/changed.go
new file mode 100644
index 0000000..d9d4bad
--- /dev/null
+++ b/changed.go
@@ -0,0 +1,97 @@
+package gitpb
+
+// An app to submit patches for the 30 GO GUI repos
+
+import (
+ "fmt"
+ "time"
+
+ "go.wit.com/lib/gui/shell"
+ "go.wit.com/log"
+ "google.golang.org/protobuf/types/known/timestamppb"
+)
+
+func (repo *Repo) Mtime(fname string) *time.Time {
+ var fileTime *time.Time
+ tmp, err := repo.oldMtime(fname)
+ fileTime = &tmp
+ if err != nil {
+ log.Info("MTime got err", err)
+ return nil
+ }
+ return fileTime
+}
+
+func (repo *Repo) changedDir() bool {
+ fname := ".git"
+ fileTime := repo.Mtime(fname)
+ if fileTime == nil {
+ // .git doesn't exist. something is wrong. rescan this repo
+ return true
+ }
+ pbtime := repo.Times.MtimeDir
+ mtime := timestamppb.New(*fileTime)
+ if (pbtime.Seconds == mtime.Seconds) && (pbtime.Nanos == mtime.Nanos) {
+ return false
+ }
+ dur := mtime.AsTime().Sub(pbtime.AsTime())
+ repo.StateChange = fmt.Sprintf("%s changed %s", fname, shell.FormatDuration(dur))
+ repo.Times.MtimeDir = mtime
+ return true
+}
+
+func (repo *Repo) changedHead() bool {
+ fname := ".git/HEAD"
+ fileTime := repo.Mtime(fname)
+ if fileTime == nil {
+ // .git/HEAD doesn't exist. something is wrong. rescan this repo
+ return true
+ }
+ pbtime := repo.Times.MtimeHead
+ mtime := timestamppb.New(*fileTime)
+ if (pbtime.Seconds == mtime.Seconds) && (pbtime.Nanos == mtime.Nanos) {
+ return false
+ }
+ dur := mtime.AsTime().Sub(pbtime.AsTime())
+ repo.StateChange = fmt.Sprintf("%s changed %s", fname, shell.FormatDuration(dur))
+ repo.Times.MtimeHead = mtime
+ return true
+}
+
+func (repo *Repo) changedIndex() bool {
+ fname := ".git/index"
+ fileTime := repo.Mtime(fname)
+ if fileTime == nil {
+ // .git/index doesn't exist. something is wrong. rescan this repo
+ return true
+ }
+ pbtime := repo.Times.MtimeIndex
+ mtime := timestamppb.New(*fileTime)
+ if (pbtime.Seconds == mtime.Seconds) && (pbtime.Nanos == mtime.Nanos) {
+ return false
+ }
+ dur := mtime.AsTime().Sub(pbtime.AsTime())
+ repo.StateChange = fmt.Sprintf("%s changed %s", fname, shell.FormatDuration(dur))
+ repo.Times.MtimeIndex = mtime
+ return true
+}
+
+func (repo *Repo) RepoChanged() bool {
+ var changed bool
+ if repo.Times == nil {
+ repo.Times = new(GitTimes)
+ log.Info(repo.FullPath, "repo.Times were nil")
+ }
+
+ if repo.changedHead() {
+ changed = true
+ }
+ if repo.changedIndex() {
+ changed = true
+ }
+ if repo.changedDir() {
+ changed = true
+ }
+
+ return changed
+}
diff --git a/goDep.redoGoMod.go b/goDep.redoGoMod.go
index 59845af..633f07f 100644
--- a/goDep.redoGoMod.go
+++ b/goDep.redoGoMod.go
@@ -4,7 +4,6 @@ package gitpb
import (
"errors"
- "time"
)
// checks to see if the go.sum and go.mod files exist
@@ -24,7 +23,7 @@ func (repo *Repo) ValidGoSum() error {
}
/*
// todo: fix this
- mtime, err := repo.mtime("go.mod")
+ mtime, err := repo.Mtime("go.mod")
if err == nil {
return err
}
@@ -38,7 +37,7 @@ func (repo *Repo) ValidGoSum() error {
return errors.New("ValidGoSum() go.sum is missing")
}
/*
- mtime, err := repo.mtime("go.sum")
+ mtime, err := repo.Mtime("go.sum")
// todo: fix this
if err == nil {
return err
@@ -56,22 +55,3 @@ func (repo *Repo) GoDepsLen() int {
}
return len(repo.GoDeps.GoDeps)
}
-
-func (repo *Repo) LastGitPull() (time.Time, error) {
- return repo.mtime(".git/FETCH_HEAD")
-}
-
-func (repo *Repo) GoSumAge() (time.Duration, error) {
- var mtime time.Time
- var err error
- mtime, err = repo.mtime("go.sum")
- if err == nil {
- return time.Since(mtime), nil
- }
- mtime, err = repo.mtime("go.mod")
- if err == nil {
- return time.Since(mtime), nil
- }
- now := time.Now()
- return time.Since(now), errors.New(repo.GoPath + " go.mod missing")
-}
diff --git a/reload.go b/reload.go
new file mode 100644
index 0000000..7a8c212
--- /dev/null
+++ b/reload.go
@@ -0,0 +1,39 @@
+package gitpb
+
+func (repo *Repo) Reload() error {
+ repo.Tags = new(GitTags)
+ repo.UpdateGitTags()
+ repo.GoDeps = new(GoDeps)
+ repo.ParseGoSum()
+
+ if repo.GoInfo != nil {
+ repo.ReloadGo()
+ }
+ return nil
+}
+
+func (repo *Repo) ReloadGo() error {
+ repo.GoPlugin = false
+ repo.GoProtobuf = false
+ repo.GoLibrary = false
+ repo.GoBinary = false
+ switch repo.goListRepoType() {
+ case "plugin":
+ repo.GoPlugin = true
+ case "protobuf":
+ repo.GoProtobuf = true
+ case "library":
+ repo.GoLibrary = true
+ case "binary":
+ repo.GoBinary = true
+ }
+ return nil
+}
+
+func (repo *Repo) SetDevelBranchName(bname string) {
+ repo.DevelBranchName = bname
+}
+
+func (repo *Repo) SetUserBranchName(bname string) {
+ repo.UserBranchName = bname
+}
diff --git a/repo.new.go b/repo.new.go
index fa1d258..10b5fcb 100644
--- a/repo.new.go
+++ b/repo.new.go
@@ -2,12 +2,8 @@ package gitpb
import (
"errors"
- "os"
- "path/filepath"
- "time"
"go.wit.com/log"
- timestamppb "google.golang.org/protobuf/types/known/timestamppb"
)
// scans in a new git repo. If it detects the repo is a golang project,
@@ -15,52 +11,24 @@ import (
// TODO: try adding python, rails, perl, rust, other language things?
// I probably will never have time to try that, but I'd take patches for anyone
// that might see this note and feel so inclined.
-func (all *Repos) NewGoPath(basepath string, gopath string, url string) (*Repo, error) {
+// todo: use Repos.Lock() ?
+func (all *Repos) NewGoRepo(fullpath string, gopath string) (*Repo, error) {
if gopath == "" {
return nil, errors.New("blank gopath")
}
if r := all.FindByGoPath(gopath); r != nil {
log.Info("gitpb.NewGoPath() already has gopath", r.GoPath)
log.Info("gitpb.NewGoPath() already has FullPath", r.FullPath)
- log.Info("gitpb.NewGoPath() already has URL", r.URL)
// already had this gopath
return r, errors.New("gitpb.NewGoPath() duplicate gopath " + gopath)
}
- log.Info("gitpb.NewGoPath() Attempting to add new path", basepath, gopath)
-
- // if .git doesn't exist, error out here
- gitpath := filepath.Join(basepath, gopath, ".git")
- _, err := os.Stat(gitpath)
- if err != nil {
- log.Warn("gitpb.NewGoPath() not a git directory", gitpath)
- return nil, err
- }
// add a new one here
newr := Repo{
- FullPath: filepath.Join(basepath, gopath),
- GoPath: gopath,
- URL: url,
- }
- newr.Tags = new(GitTags)
- newr.UpdateGitTags()
- newr.GoDeps = new(GoDeps)
-
- switch newr.goListRepoType() {
- case "plugin":
- newr.GoPlugin = true
- case "protobuf":
- newr.GoProtobuf = true
- case "library":
- newr.GoLibrary = true
- case "binary":
- newr.GoBinary = true
- }
-
- lastpull, err := newr.LastGitPull()
- if err == nil {
- newr.LastPull = timestamppb.New(lastpull)
+ FullPath: fullpath,
}
+ newr.GoInfo = new(GoInfo)
+ newr.GoInfo.GoPath = gopath
if all.AppendUniqueGoPath(&newr) {
// worked
@@ -75,39 +43,3 @@ func (all *Repos) NewGoPath(basepath string, gopath string, url string) (*Repo,
// todo: use Repos.Lock()
return nil, errors.New("repo gitpb.NewGoPath() should never have gotten here " + gopath)
}
-
-func (repo *Repo) SetDevelBranchName(bname string) {
- repo.DevelBranchName = bname
-}
-
-func (repo *Repo) SetUserBranchName(bname string) {
- repo.UserBranchName = bname
-}
-
-func (repo *Repo) GitChanged() bool {
- fullfile := filepath.Join(repo.FullPath, ".git/FETCH_HEAD")
- lasttime, err := repo.LastGitPull()
- if err == nil {
- // if error, something is wrong, assume true
- log.Info("gitpb:", fullfile, "changed")
- return true
- }
- newtime := repo.LastPull.AsTime()
-
- if lasttime == newtime {
- return false
- }
- log.Info("gitpb:", fullfile, "changed")
- return true
-}
-
-func (repo *Repo) GitPullAge() time.Duration {
- lastpull, err := repo.LastGitPull()
- if err == nil {
- // if error, something is wrong, assume true
- ltime := repo.LastPull.AsTime()
- return time.Since(ltime)
- }
-
- return time.Since(lastpull)
-}
diff --git a/repo.proto b/repo.proto
index 840804c..71f3010 100644
--- a/repo.proto
+++ b/repo.proto
@@ -34,6 +34,11 @@ message Repo { // `autogenpb:marshal`
string desc = 20; // what is this repo?
bytes goMod = 21; // the last go.mod file
bytes goSum = 22; // the last go.sum file
+ google.protobuf.Timestamp mtimeGitDir = 23; // mtime for ./git
+ google.protobuf.Timestamp mtimeGitHead = 24; // mtime for ./git/HEAD // these two mtimes allow really fast checks to see if git has changed
+ GitTimes times = 25; // store all the mtime values here. these are temporary
+ GoInfo goInfo = 26; // put all the go specifcs here
+ string stateChange = 27; // reason for state change
}
message Repos { // `autogenpb:marshal`
@@ -41,3 +46,29 @@ message Repos { // `autogenpb:marshal`
string version = 2; // maybe can be used for protobuf schema change violations
repeated Repo repos = 3;
}
+
+// should it be done this way?
+message GitTimes {
+ google.protobuf.Timestamp lastPull = 1; // last time a git pull was done
+ google.protobuf.Timestamp lastUpdate = 2; // when was ReloadGit() last done
+ 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?
+}
+
+// this is probably better. think about moving to this instead
+message GoInfo {
+ string goPath = 1; // the logical path as used by golang: 'go.wit.com/apps/helloworld'
+ string desc = 2; // what is this repo?
+ bool goLibrary = 3; // is this a golang library?
+ bool goBinary = 4; // is this a golang binary?
+ bool goPrimitive = 5; // if this is a golang primitive (only has go.mod)
+ bool goPlugin = 6; // is this a golang plugin?
+ bool goProtobuf = 7; // autogen go files from .proto
+ GoDeps goDeps = 8; // what is in the go.sum file
+ GoDeps published = 9; // the last published go.mod/go.sum
+ bytes goMod = 10; // the last go.mod file
+ bytes goSum = 11; // the last go.sum file
+}
diff --git a/rill.go b/rill.go
index 142b201..7b4bb87 100644
--- a/rill.go
+++ b/rill.go
@@ -102,3 +102,18 @@ func (all *Repos) RillGitPull(part1 int, part2 int) map[*Repo]cmd.Status {
return allerr
}
+
+func (repo *Repo) GitPullRealtime() cmd.Status {
+ currentName := repo.GetCurrentBranchName()
+ if repo.IsOnlyLocalTag(currentName) {
+ var result cmd.Status
+ result.Exit = 21
+ result.Error = ErrorGitPullOnLocal
+ // log.Info("git pull skipped on local only branch", repo.GoPath)
+ return result
+ }
+ var cmd []string
+ cmd = append(cmd, "git", "pull")
+ r := repo.RunRealtime(cmd)
+ return r
+}
diff --git a/shell.go b/shell.go
index efb682d..3d15eee 100644
--- a/shell.go
+++ b/shell.go
@@ -6,7 +6,6 @@ import (
"os"
"path/filepath"
"strings"
- "time"
"github.com/go-cmd/cmd"
"go.wit.com/lib/gui/shell"
@@ -109,13 +108,3 @@ func (repo *Repo) IsDirectory() bool {
}
return info.IsDir()
}
-
-func (repo *Repo) mtime(filename string) (time.Time, error) {
- pathf := filepath.Join(repo.FullPath, filename)
- statf, err := os.Stat(pathf)
- if err == nil {
- return statf.ModTime(), nil
- }
- log.Log(GITPB, "mtime() os.Stat() error", pathf, err)
- return time.Now(), err
-}