diff --git a/common.go b/common.go index a2c8685..3c6259f 100644 --- a/common.go +++ b/common.go @@ -45,6 +45,13 @@ func (rs *RepoStatus) GoPath() string { return rs.goPath.String() } +func (rs *RepoStatus) IsPrimitive() bool { + if rs.primitive.String() == "true" { + return true + } + return false +} + // returns the filesystem path to the repo func (rs *RepoStatus) Path() string { return rs.realPath.String() @@ -98,15 +105,6 @@ func (rs *RepoStatus) IsGoLang() bool { return false } -/* -func (rs *RepoStatus) Initialized() bool { - log.Log(CHANGE, "checking Initialized()") - if rs == nil {return false} - if rs.parent == nil {return false} - return true -} -*/ - func (rs *RepoStatus) RepoType() string { if !rs.IsGoLang() { return "" @@ -151,20 +149,14 @@ func (rs *RepoStatus) Build() bool { return false } -// moved to repolist -func (rs *RepoStatus) GetGoSumStatusOld() string { - return rs.goSumStatus.String() -} - -// moved to repolist -func (rs *RepoStatus) SetGoSumStatusOld(s string) { - rs.goSumStatus.SetText(s) -} - func (rs *RepoStatus) GetTargetVersion() string { return rs.targetReleaseVersion.String() } +func (rs *RepoStatus) GetCurrentVersion() string { + return rs.currentVersion.String() +} + func (rs *RepoStatus) IncrementVersion() bool { return rs.setTag() } @@ -197,10 +189,6 @@ func (rs *RepoStatus) MirrorGitState() *gui.Node { return rs.gitState.MirrorValue() } -func (rs *RepoStatus) MirrorGoState() *gui.Node { - return rs.goSumStatus.MirrorValue() -} - func (rs *RepoStatus) MirrorMasterVersion() *gui.Node { return rs.mainBranchVersion.MirrorValue() } diff --git a/draw.go b/draw.go index b632df7..cdf89c2 100644 --- a/draw.go +++ b/draw.go @@ -27,7 +27,7 @@ func (rs *RepoStatus) drawGitStatus(box *gui.Node) { rs.dirtyLabel = gadgets.NewOneLiner(newgrid, "dirty") rs.gitState = gadgets.NewOneLiner(newgrid, "git state") rs.readOnly = gadgets.NewOneLiner(newgrid, "read only") - rs.goSumStatus = gadgets.NewOneLiner(newgrid, "go mod status") + rs.primitive = gadgets.NewOneLiner(newgrid, "primitive") rs.targetReleaseVersion = gadgets.NewOneLiner(newgrid, "target release version") rs.speed = gadgets.NewOneLiner(newgrid, "refresh speed =") diff --git a/gitConfig.go b/gitConfig.go index 2f70773..e49c2b7 100644 --- a/gitConfig.go +++ b/gitConfig.go @@ -214,30 +214,6 @@ func (rs *RepoStatus) GitLsFiles() (bool, string) { return true, output } -func ScanGoSrc() { - log.Log(WARN, "Scanning all go.sum files") - for path, rs := range windowMap { - if rs.ReadGoMod() { - // everything is ok - } else { - log.Log(WARN, "failed reading go.sum repo:", path) - } - } -} - -func (rs *RepoStatus) ScanGoSrc() { - if rs.ReadGoMod() { - log.Log(INFO, "parsed go.mod", rs.realPath.String()) - } else { - log.Log(WARN, "Something went wrong parsing go.mod", rs.realPath.String()) - } - - log.Log(WARN, "go.sum:", rs.realPath.String()) - for depname, version := range rs.goConfig { - log.Log(WARN, " ", depname, version) - } -} - func (rs *RepoStatus) Writable() { rs.readOnly.SetText("false") } diff --git a/goConfig.go b/goConfig.go new file mode 100644 index 0000000..310aed6 --- /dev/null +++ b/goConfig.go @@ -0,0 +1,159 @@ +package repostatus + +// does processing on the go.mod and go.sum files + +import ( + "bufio" + "errors" + "os" + "path/filepath" + "strings" + + "go.wit.com/log" +) + +// Detect a 'Primative' package. Sets the isPrimative flag +// will return true if the repo is truly not dependent on _anything_ else +// like spew or lib/widget +func (rs *RepoStatus) isPrimativeGoMod() (bool, error) { + // go mod init & go mod tidy ran without errors + log.Log(WARN, "isPrimativeGoMod()", rs.realPath.String()) + tmp := filepath.Join(rs.realPath.String(), "go.mod") + gomod, err := os.Open(tmp) + if err != nil { + log.Log(WARN, "missing go.mod", rs.realPath.String()) + rs.goConfig = nil + return false, err + } + defer gomod.Close() + + scanner := bufio.NewScanner(gomod) + for scanner.Scan() { + line := strings.TrimSpace(scanner.Text()) + + parts := strings.Split(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("bad go.mod file" + rs.GoPath()) + } + + } + } + return true, nil +} + +// readGoMod reads and parses the go.sum file +// saves the config information in repo.goConfig +func (rs *RepoStatus) parseGoSum() (bool, error) { + ok, err := rs.isPrimativeGoMod() + if err != nil { + // this means this repo does not depend on any other package + log.Info("PRIMATIVE repo:", rs.String(), "err =", err) + rs.goConfig = nil + rs.primitive.SetText("false") + return false, err + } + if ok { + // this means the repo is primitive so there is no go.sum + rs.goConfig = nil + rs.primitive.SetText("true") + return true, nil + } + rs.primitive.SetText("false") + + tmp := filepath.Join(rs.realPath.String(), "go.sum") + gosum, err := os.Open(tmp) + if err != nil { + log.Log(WARN, "missing go.sum", rs.realPath.String()) + rs.goConfig = nil + return false, err + } + defer gosum.Close() + + var deps GoConfig + deps = make(GoConfig) + + scanner := bufio.NewScanner(gosum) + log.Log(INFO, "gosum:", 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") + } + currentversion, ok := deps[godep] + if ok { + if currentversion != version { + // ignore these warnings for now + depname := rs.String() + if strings.HasPrefix(depname, "go.wit.com") { + log.Log(INFO, "REPO:", rs.realPath.String()) + log.Log(INFO, " version mismatch:", godep, version, currentversion) + } else { + log.Log(INFO, "REPO:", rs.realPath.String()) + log.Log(INFO, " version mismatch:", godep, version, currentversion) + } + } + } else { + deps[godep] = version + log.Log(INFO, "\t", godep, "=", version) + } + } else { + log.Log(WARN, "\t INVALID:", parts) + } + } + + if err := scanner.Err(); err != nil { + rs.goConfig = nil + return false, err + } + + rs.goConfig = deps + return true, nil +} + +func (rs *RepoStatus) GoConfig() map[string]string { + return rs.goConfig +} + +// poor name perhaps. It's because in most of these +// repos you can also type "make redomod" to do the same thing +// since it's a Makefile task that is also useful to be able to run +// from the command line +func (rs *RepoStatus) MakeRedomod() (bool, error) { + var err error + var output string + if rs.ReadOnly() { + log.Log(WARN, "will not go mod redo read only repos", rs.String()) + return false, errors.New(rs.GoPath() + " is read-only ") + } + + // unset the go development ENV var to generate release files + os.Unsetenv("GO111MODULE") + err, output = rs.RunCmd([]string{"rm", "-f", "go.mod", "go.sum"}) + if err != nil { + log.Log(WARN, "rm failed", err, output) + return false, err + } + err, output = rs.RunCmd([]string{"go", "mod", "init"}) + if err != nil { + log.Log(WARN, "go mod init failed", err, output) + return false, err + } + err, output = rs.RunCmd([]string{"go", "mod", "tidy"}) + if err != nil { + log.Log(WARN, "go mod tidy failed", err, output) + return false, err + } + log.Log(INFO, "MakeRedomod() worked", rs.GoPath()) + + // return the attempt to parse go.mod & go.sum + return rs.parseGoSum() +} diff --git a/redomod.go b/redomod.go deleted file mode 100644 index ac17c78..0000000 --- a/redomod.go +++ /dev/null @@ -1,287 +0,0 @@ -package repostatus - -import ( - "bufio" - "os" - "path/filepath" - "strings" - - "go.wit.com/log" -) - -// this checks to see if the repo is truly not dependent on _anything_ else -// like spew or lib/widget -func (rs *RepoStatus) CheckPrimativeGoMod() bool { - log.Log(WARN, "CheckPrimativeGoMod()", rs.realPath.String()) - tmp := filepath.Join(rs.realPath.String(), "go.mod") - gomod, err := os.Open(tmp) - if err != nil { - log.Log(WARN, "missing go.mod", rs.realPath.String()) - rs.goConfig = nil - return false - } - defer gomod.Close() - - scanner := bufio.NewScanner(gomod) - for scanner.Scan() { - line := strings.TrimSpace(scanner.Text()) - - parts := strings.Split(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 - } - - } - } - return true -} - -// readGoMod reads and parses the go.sum file (TODO: do the go.mod file) -func (rs *RepoStatus) ReadGoMod() bool { - if rs.CheckPrimativeGoMod() { - log.Info("PRIMATIVE repo:", rs.String()) - return true - } - - tmp := filepath.Join(rs.realPath.String(), "go.sum") - gosum, err := os.Open(tmp) - if err != nil { - log.Log(WARN, "missing go.sum", rs.realPath.String()) - rs.goConfig = nil - return false - } - defer gosum.Close() - - var deps GoConfig - deps = make(GoConfig) - - scanner := bufio.NewScanner(gosum) - log.Log(INFO, "gosum:", 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") - } - currentversion, ok := deps[godep] - if ok { - if currentversion != version { - // ignore these warnings for now - depname := rs.String() - if strings.HasPrefix(depname, "go.wit.com") { - log.Log(INFO, "REPO:", rs.realPath.String()) - log.Log(INFO, " version mismatch:", godep, version, currentversion) - } else { - log.Log(INFO, "REPO:", rs.realPath.String()) - log.Log(INFO, " version mismatch:", godep, version, currentversion) - } - } - } else { - deps[godep] = version - log.Log(INFO, "\t", godep, "=", version) - } - } else { - log.Log(WARN, "\t INVALID:", parts) - } - } - - if err := scanner.Err(); err != nil { - rs.goConfig = nil - return false - } - - rs.goConfig = deps - return true -} - -// check if it is safe to remake the go.sum & go.mod files -func (rs *RepoStatus) CheckSafeGoSumRemake() (bool, []string) { - myGoSumS := rs.goSumStatus.String() - if rs.ReadGoMod() { - log.Log(INFO, "parsed go.mod", rs.realPath.String()) - } else { - log.Log(WARN, "Something went wrong parsing go.mod", rs.realPath.String()) - return false, nil - } - log.Log(WARN, "go.sum:", rs.realPath.String()) - var clean []string - for depname, version := range rs.goConfig { - if strings.HasSuffix(depname, "/v2") { - log.Log(WARN, " FOUND /v2 wierd golang stuff. instead, look for:", depname) - depname = strings.TrimSuffix(depname, "/v2") - } - log.Log(WARN, " ", depname, version) - deprs, ok := windowMap[depname] - if ok { - if deprs.CheckDirty() { - log.Log(WARN, " IS DIRTY", deprs.String()) - clean = append(clean, deprs.String()) - } - if deprs.readOnly.String() == "true" { - log.Log(WARN, " SKIPPING Read Only", deprs.String()) - } else { - goSumS := deprs.goSumStatus.String() - log.Log(WARN, " FOUND", deprs.String(), goSumS) - username := deprs.mainWorkingName.String() - userhash, _ := deprs.gitConfig.hashes[username] - userversion, _ := deprs.gitConfig.versions[userhash] - log.Log(WARN, " username :"+username, userhash) - log.Log(WARN, " username :"+username, userversion) - if version == userversion { - log.Log(WARN, " USER VERSIONS MATCH", version, userversion, goSumS) - clean = append(clean, deprs.String()) - } else { - os.Unsetenv("GO111MODULE") - log.Log(WARN, " USER VERSIONS MISMATCH", version, userversion, myGoSumS) - log.Log(WARN, " IGNORE UNCHANGED REPO. RUNNING 'go get'", depname, userversion) - err, output := rs.RunCmd([]string{"go", "get", depname + "@" + userversion}) - log.Log(WARN, " go get", depname, err, output) - /* - switch goSumS { - case "SAFE": - log.Log(WARN, " USER VERSIONS MISMATCH", version, userversion) - log.Log(WARN, " IGNORE SAFE REPO") - err, output := rs.RunCmd([]string{"go", "get", depname + "@" + userversion}) - log.Log(WARN, " go get", depname, err, output) - case "CLEAN": - log.Log(WARN, " USER VERSIONS MISMATCH", version, userversion) - log.Log(WARN, " IGNORE CLEAN REPO") - case "PRIMATIVE": - log.Log(WARN, " USER VERSIONS MISMATCH", version, userversion) - log.Log(WARN, " IGNORE PRIMATIVE REPO") - err, output := rs.RunCmd([]string{"go", "get", depname + "@" + userversion}) - log.Log(WARN, " go get", depname, err, output) - default: - log.Log(WARN, " USER VERSIONS MISMATCH default", version, userversion) - clean = append(clean, deprs.String()) - if myGoSumS == "UNCHANGED" { - } - } - */ - } - } - } else { - // log.Log(WARN, " NOT FOUND", depname) - // only fail on our stuff - if strings.HasPrefix(depname, "go.wit.com") { - log.Log(WARN, " go get -v", depname) - // rs.RunCmd([]string{"go", "get", "-v", depname}) - return false, clean - } - // log.Log(WARN, " NOT FOUND BUT IGNORING FOR NOW") - } - } - if len(clean) == 0 { - return true, nil - } - return false, clean -} - -func (rs *RepoStatus) CheckGoSum() (bool, string) { - if rs.ReadGoMod() { - log.Log(INFO, "parsed go.mod", rs.realPath.String()) - } else { - log.Log(WARN, "Something went wrong parsing go.mod", rs.realPath.String()) - return false, "" - } - log.Log(WARN, "go.sum:", rs.realPath.String()) - for depname, version := range rs.goConfig { - if strings.HasSuffix(depname, "/v2") { - log.Log(WARN, " FOUND /v2 wierd golang stuff. instead, look for:", depname) - depname = strings.TrimSuffix(depname, "/v2") - } - log.Log(WARN, " ", depname, version) - deprs, ok := windowMap[depname] - if ok { - if deprs.CheckDirty() { - log.Log(WARN, " IS DIRTY", deprs.String()) - return false, "" - } - if deprs.readOnly.String() == "true" { - log.Log(WARN, " SKIPPING Read Only", deprs.String()) - } else { - log.Log(WARN, " FOUND", deprs.String(), deprs.goSumStatus.String()) - username := deprs.mainWorkingName.String() - userhash, _ := deprs.gitConfig.hashes[username] - userversion, _ := deprs.gitConfig.versions[userhash] - log.Log(WARN, " username :"+username, userhash) - log.Log(WARN, " username :"+username, userversion) - if version == userversion { - log.Log(WARN, " USER VERSIONS MATCH", version, userversion) - if deprs.goSumStatus.String() == "BAD" { - log.Log(WARN, " USER VERSION IS BAD!! return false") - return false, "" - } - } else { - log.Log(WARN, " USER VERSIONS MISMATCH", version, userversion) - return false, "" - } - } - } else { - // log.Log(WARN, " NOT FOUND", depname) - if strings.HasSuffix(depname, "/v2") { - log.Log(WARN, " FOUND /v2 wierd golang stuff. instead, look for:", depname) - } - // only fail on our stuff - if strings.HasPrefix(depname, "go.wit.com") { - log.Log(WARN, " go get -v", depname) - // rs.RunCmd([]string{"go", "get", "-v", depname}) - return false, depname - } - // log.Log(WARN, " NOT FOUND BUT IGNORING FOR NOW") - } - } - err, output := rs.RunCmd([]string{"git", "branch", "--remotes"}) - if err == nil { - lines := strings.Split(output, "\n") - for i, s := range lines { - log.Log(WARN, "add line", i, s) - } - } else { - log.Log(WARN, "git branch --remotes failed", err) - } - return true, "" -} - -func (rs *RepoStatus) MakeRedomod() bool { - var err error - var b bool - var output string - var worked bool = true - if rs.ReadOnly() { - log.Log(WARN, "will not go mod redo read only repos", rs.String()) - return false - } - - os.Unsetenv("GO111MODULE") - path := rs.realPath.String() - err, b, output = RunCmd(path, []string{"rm", "-f", "go.mod", "go.sum"}) - if err != nil { - worked = false - log.Log(WARN, "rm failed", err, b, output) - } - err, b, output = RunCmd(path, []string{"go", "mod", "init"}) - if err != nil { - worked = false - log.Log(WARN, "go mod init failed", err, b, output) - } - err, b, output = RunCmd(path, []string{"go", "mod", "tidy"}) - if err != nil { - worked = false - log.Log(WARN, "go mod tidy failed", err, b, output) - } - if worked { - log.Log(WARN, "MakeRedomod() worked", path) - } else { - log.Log(WARN, "MakeRedomod() failed", path) - } - return worked -} diff --git a/structs.go b/structs.go index 869a9f8..5afc1c8 100644 --- a/structs.go +++ b/structs.go @@ -22,10 +22,10 @@ type RepoStatus struct { // a box of all the git tags Tags *GitTagBox - dirtyLabel *gadgets.OneLiner - readOnly *gadgets.OneLiner - goSumStatus *gadgets.OneLiner - gitState *gadgets.OneLiner + dirtyLabel *gadgets.OneLiner + readOnly *gadgets.OneLiner + gitState *gadgets.OneLiner + primitive *gadgets.OneLiner path *gadgets.OneLiner goSrcPath *gadgets.OneLiner