summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--Makefile1
-rw-r--r--godep.redoGoMod.go117
-rw-r--r--log.go16
-rw-r--r--repo.new.go54
-rw-r--r--repo.proto13
-rw-r--r--scanGoSrc/Makefile23
-rw-r--r--scanGoSrc/argv.go50
-rw-r--r--scanGoSrc/main.go61
-rw-r--r--shell.go51
10 files changed, 379 insertions, 9 deletions
diff --git a/.gitignore b/.gitignore
index 6cce53e..4bfdc3c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,4 +2,4 @@ go.*
*.pb.go
-example/example
+scanGoSrc/scanGoSrc
diff --git a/Makefile b/Makefile
index 362df41..905df97 100644
--- a/Makefile
+++ b/Makefile
@@ -6,6 +6,7 @@
all: refs.pb.go godep.pb.go repo.pb.go vet
+ make -C scanGoSrc/
vet: lint
GO111MODULE=off go vet
diff --git a/godep.redoGoMod.go b/godep.redoGoMod.go
new file mode 100644
index 0000000..2ce7676
--- /dev/null
+++ b/godep.redoGoMod.go
@@ -0,0 +1,117 @@
+package gitpb
+
+// does processing on the go.mod and go.sum files
+
+import (
+ "bufio"
+ "errors"
+ "os"
+ "path/filepath"
+ "strings"
+
+ "go.wit.com/log"
+)
+
+// 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 (repo *Repo) MakeRedomod() (bool, error) {
+ // unset the go development ENV var to generate release files
+ os.Unsetenv("GO111MODULE")
+ if ok, err := repo.strictRun([]string{"rm", "-f", "go.mod", "go.sum"}); !ok {
+ log.Warn("rm go.mod go.sum failed", err)
+ return ok, err
+ }
+ if ok, err := repo.strictRun([]string{"go", "mod", "init", repo.GoPath}); !ok {
+ log.Warn("go mod init failed", err)
+ return ok, err
+ }
+ if ok, err := repo.strictRun([]string{"go", "mod", "tidy"}); !ok {
+ log.Warn("go mod tidy failed", err)
+ return ok, err
+ }
+ log.Info("MakeRedomod() worked", repo.GoPath)
+
+ if repo.Exists("go.sum") {
+ // return the attempt to parse go.mod & go.sum
+ return repo.parseGoSum()
+ }
+ repo.GoDeps = nil
+ repo.GoPrimitive = false
+
+ ok, err := repo.isPrimativeGoMod()
+ if err != nil {
+ // this means this repo does not depend on any other package
+ log.Info("PRIMATIVE repo error:", repo.GoPath, "err =", err)
+ return false, err
+ }
+ if ok {
+ // this means the repo is primitive so there is no go.sum
+ repo.GoPrimitive = true
+ return true, nil
+ }
+ // this should never happen
+ return false, errors.New("MakeRedomod() logic failed")
+}
+
+// reads and parses the go.sum file
+func (repo *Repo) parseGoSum() (bool, error) {
+ // empty out what was there before
+ repo.GoDeps = nil
+ tmp := filepath.Join(repo.FullPath, "go.sum")
+ gosum, err := os.Open(tmp)
+ if err != nil {
+ log.Warn("missing go.sum", repo.FullPath)
+ return false, err
+ }
+ defer gosum.Close()
+
+ scanner := bufio.NewScanner(gosum)
+ 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")
+ }
+ new1 := GoDep{
+ GoPath: godep,
+ Version: version,
+ }
+ repo.AppendGoDep(&new1)
+ /*
+ found := repo.FindGoDepByPath(godep)
+ if found == nil {
+ currentversion, ok := deps[godep]
+ if ok {
+ // only use the first value found in the file?
+ // this shouldn't have been possible. this function should
+ // only be called from MakeRedomod()
+ // todo: make go things a seperate package so this function
+ // isn't exported?
+ if version != currentversion {
+ log.Warn("\tgo.sum ", godep, "had both", version, currentversion)
+ }
+ } else {
+ deps[godep] = version
+ log.Info("\t", godep, "=", version)
+ }
+ */
+ } else {
+ // I've never seen this happen yet
+ panic(errors.New("go.sum invalid: " + line))
+ // return false, errors.New("go.sum invalid: " + line)
+ }
+ }
+
+ if err := scanner.Err(); err != nil {
+ repo.GoDeps = nil
+ return false, err
+ }
+ return true, nil
+}
diff --git a/log.go b/log.go
new file mode 100644
index 0000000..df58886
--- /dev/null
+++ b/log.go
@@ -0,0 +1,16 @@
+package gitpb
+
+import (
+ "go.wit.com/log"
+)
+
+var GITPB *log.LogFlag
+var GITPBWARN *log.LogFlag
+
+func init() {
+ full := "go.wit.com/lib/protobuf/gitpb"
+ short := "gitpb"
+
+ GITPB = log.NewFlag("GITPB", false, full, short, "general gitpb things")
+ GITPBWARN = log.NewFlag("GITPBWARN", true, full, short, "gitpb warnings")
+}
diff --git a/repo.new.go b/repo.new.go
index c7f000f..bab2b25 100644
--- a/repo.new.go
+++ b/repo.new.go
@@ -1,7 +1,13 @@
package gitpb
import (
+ "bufio"
+ "errors"
+ "os"
"path/filepath"
+ "strings"
+
+ "go.wit.com/log"
)
// scans in a new git repo. If it detects the repo is a golang project,
@@ -9,11 +15,19 @@ 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) *Repo {
+func (all *Repos) NewGoPath(basepath string, gopath string) (*Repo, error) {
if r := all.FindByGoPath(gopath); r != nil {
// already had this gopath
- return r
+ return r, nil
+ }
+
+ // if .git doesn't exist, error out here
+ gitpath := filepath.Join(basepath, gopath, ".git")
+ _, err := os.Stat(gitpath)
+ if err != nil {
+ return nil, err
}
+
// add a new one here
newr := Repo{
FullPath: filepath.Join(basepath, gopath),
@@ -22,5 +36,39 @@ func (all *Repos) NewGoPath(basepath string, gopath string) *Repo {
newr.UpdateGit()
all.add(&newr)
- return &newr
+ return &newr, nil
+}
+
+// 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
+// it assumes go mod ran init and tidy ran without error
+func (repo *Repo) isPrimativeGoMod() (bool, error) {
+ // go mod init & go mod tidy ran without errors
+ log.Log(GITPB, "isPrimativeGoMod()", repo.FullPath)
+ tmp := filepath.Join(repo.FullPath, "go.mod")
+ gomod, err := os.Open(tmp)
+ if err != nil {
+ log.Log(GITPB, "missing go.mod", repo.FullPath)
+ repo.GoDeps = 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(GITPB, " gomod:", parts)
+ if len(parts) >= 1 {
+ log.Log(GITPB, " gomod: part[0] =", parts[0])
+ if parts[0] == "require" {
+ log.Log(GITPB, " should return false here")
+ return false, errors.New("go.mod file is not primative")
+ }
+
+ }
+ }
+ return true, nil
}
diff --git a/repo.proto b/repo.proto
index 03fbd6e..029bad2 100644
--- a/repo.proto
+++ b/repo.proto
@@ -11,12 +11,15 @@ import "google/protobuf/timestamp.proto"; // Import the well-known type for Time
message Repo {
string fullPath = 1; // the actual path to the .git directory: '/home/devel/golang.org/x/tools'
- string goPath = 2; // the logical path as used by golang: 'go.wit.com/apps/helloworld'
- bool library = 3; // if this is a golang library
- repeated Ref refs = 4;
- repeated GoDep GoDeps = 5;
- google.protobuf.Timestamp lastPull = 6; // last time a git pull was done
+ repeated Ref refs = 2;
+ google.protobuf.Timestamp lastPull = 3; // last time a git pull was done
+
+ // things specific to golang projects
+ string goPath = 4; // the logical path as used by golang: 'go.wit.com/apps/helloworld'
+ repeated GoDep GoDeps = 6;
google.protobuf.Timestamp lastGoDep = 7; // last time go.sum was processed
+ bool goLibrary = 8; // if this is a golang library
+ bool goPrimitive = 9; // if this is a golang primitive
}
message Repos {
diff --git a/scanGoSrc/Makefile b/scanGoSrc/Makefile
new file mode 100644
index 0000000..bcd01e3
--- /dev/null
+++ b/scanGoSrc/Makefile
@@ -0,0 +1,23 @@
+VERSION = $(shell git describe --tags)
+BUILDTIME = $(shell date +%Y.%m.%d)
+
+build:
+ GO111MODULE=off go build \
+ -ldflags "-X main.VERSION=${VERSION} -X main.BUILDTIME=${BUILDTIME} -X gui.GUIVERSION=${VERSION}"
+ FORGE_HOME=/tmp/forge ./scanGoSrc
+
+install:
+ GO111MODULE=off go install \
+ -ldflags "-X main.VERSION=${VERSION} -X main.BUILDTIME=${BUILDTIME} -X gui.GUIVERSION=${VERSION}"
+
+goimports:
+ goimports -w *.go
+
+prep:
+ go get -v -t -u
+
+run:
+ go run *.go
+
+clean:
+ -rm -f scanGoSrc
diff --git a/scanGoSrc/argv.go b/scanGoSrc/argv.go
new file mode 100644
index 0000000..5e01d4f
--- /dev/null
+++ b/scanGoSrc/argv.go
@@ -0,0 +1,50 @@
+package main
+
+import (
+ "os"
+
+ "github.com/alexflint/go-arg"
+)
+
+var argv args
+
+type args struct {
+ ConfigDir string `arg:"env:FORGE_HOME" help:"defaults to ~/.config/forge/"`
+ List bool `arg:"--list" default:"false" help:"list repos in your config"`
+ Add bool `arg:"--add" default:"false" help:"add a new repo"`
+ Delete bool `arg:"--delete" default:"false" help:"delete a repo"`
+ Update bool `arg:"--update" default:"false" help:"update a repo"`
+ GoPath string `arg:"--gopath" help:"gopath of the repo"`
+ Directory bool `arg:"--directory" default:"false" help:"repo is a directory to match against"`
+ ReadOnly bool `arg:"--readonly" default:"false" help:"repo is readonly"`
+ Writable bool `arg:"--writable" default:"false" help:"repo is writable"`
+ Favorite bool `arg:"--favorite" default:"false" help:"forge will always go-clone or git clone this"`
+ Private bool `arg:"--private" default:"false" help:"repo can not be published"`
+ Interesting bool `arg:"--interesting" default:"false" help:"something you decided was cool"`
+}
+
+func (a args) Description() string {
+ return `
+ forgeConfig -- add entries to your config files
+
+This is just example protobuf code to test forgepb is working
+but it could be used to automagically create a config file too.
+
+If you need to change your config file, just edit the forge.text or forge.json
+files then remove the forge.pb and ConfigLoad() will attempt to load those files instead
+`
+}
+
+func (args) Version() string {
+ return "virtigo " + VERSION
+}
+
+func init() {
+ var pp *arg.Parser
+ pp = arg.MustParse(&argv)
+
+ if pp == nil {
+ pp.WriteHelp(os.Stdout)
+ os.Exit(0)
+ }
+}
diff --git a/scanGoSrc/main.go b/scanGoSrc/main.go
new file mode 100644
index 0000000..ff24c9c
--- /dev/null
+++ b/scanGoSrc/main.go
@@ -0,0 +1,61 @@
+package main
+
+import (
+ "os"
+
+ "go.wit.com/lib/protobuf/forgepb"
+ "go.wit.com/lib/protobuf/gitpb"
+ "go.wit.com/log"
+)
+
+// sent via ldflags
+var VERSION string
+
+func main() {
+ var config forgepb.ForgeConfigs
+ if err := config.ConfigLoad(); err != nil {
+ log.Warn("forgepb.ConfigLoad() failed", err)
+ os.Exit(-1)
+ }
+
+ config.PrintTable()
+
+ var repos *gitpb.Repos
+ repos = new(gitpb.Repos)
+
+ newr, err := repos.NewGoPath("/home/jcarr/go/src", "go.wit.com/apps/wit-package")
+ if err != nil {
+ log.Info("init failed", err)
+ } else {
+ log.Info("init worked for", newr.GoPath)
+ }
+
+ newr, err = repos.NewGoPath("/home/jcarr/go/src", "go.wit.com/apps/notathing")
+ if err != nil {
+ log.Info("init failed correctly:", err)
+ } else {
+ log.Info("init should have failed for", newr.GoPath)
+ }
+
+ /*
+ log.Info(forgepb.RepoHeader())
+ loop := repos.SortByPath() // get the list of repos
+ for loop.Scan() {
+ r := loop.Repo()
+ log.Info("repo:", r.GoPath)
+ }
+ */
+ /*
+ log.Info("going to add a new repo", argv.GoPath)
+ new1 := forgepb.Repo{
+ GoPath: argv.GoPath,
+ Writable: argv.Writable,
+ ReadOnly: argv.ReadOnly,
+ Private: argv.Private,
+ Directory: argv.Directory,
+ Favorite: argv.Favorite,
+ Interesting: argv.Interesting,
+ }
+ */
+ os.Exit(0)
+}
diff --git a/shell.go b/shell.go
new file mode 100644
index 0000000..de82f84
--- /dev/null
+++ b/shell.go
@@ -0,0 +1,51 @@
+package gitpb
+
+import (
+ "os"
+ "path/filepath"
+ "strings"
+
+ "github.com/go-cmd/cmd"
+ "go.wit.com/lib/gui/shell"
+ "go.wit.com/log"
+)
+
+// execute something with the working directory
+// set to the FullPath
+func (repo *Repo) Run(cmd []string) cmd.Status {
+ result := shell.PathRun(repo.FullPath, cmd)
+ output := strings.Join(result.Stdout, "\n")
+ if result.Error != nil {
+ log.Warn("cmd:", cmd)
+ log.Warn("ouptput:", output)
+ log.Warn("failed with error:", result.Error)
+ }
+ return result
+}
+
+// for now, even check cmd.Exit
+func (repo *Repo) strictRun(cmd []string) (bool, error) {
+ result := repo.Run(cmd)
+ if result.Error != nil {
+ log.Warn("go mod init failed err:", result.Error)
+ return false, result.Error
+ }
+ if result.Exit != 0 {
+ log.Warn("go mod init exit =", result.Exit)
+ return false, result.Error
+ }
+ return true, nil
+}
+
+func (repo *Repo) Exists(filename string) bool {
+ if repo == nil {
+ log.Warn("repo == nil for Exists()")
+ panic(-1)
+ }
+ testf := filepath.Join(repo.FullPath, filename)
+ _, err := os.Stat(testf)
+ if err != nil {
+ return false
+ }
+ return true
+}