first attempt that seems to kinda work on New()
This commit is contained in:
parent
8b987962ea
commit
ed3eacfe75
|
@ -2,4 +2,4 @@ go.*
|
||||||
|
|
||||||
*.pb.go
|
*.pb.go
|
||||||
|
|
||||||
example/example
|
scanGoSrc/scanGoSrc
|
||||||
|
|
1
Makefile
1
Makefile
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
|
|
||||||
all: refs.pb.go godep.pb.go repo.pb.go vet
|
all: refs.pb.go godep.pb.go repo.pb.go vet
|
||||||
|
make -C scanGoSrc/
|
||||||
|
|
||||||
vet: lint
|
vet: lint
|
||||||
GO111MODULE=off go vet
|
GO111MODULE=off go vet
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
|
@ -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")
|
||||||
|
}
|
54
repo.new.go
54
repo.new.go
|
@ -1,7 +1,13 @@
|
||||||
package gitpb
|
package gitpb
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
|
"errors"
|
||||||
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"go.wit.com/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
// scans in a new git repo. If it detects the repo is a golang project,
|
// 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?
|
// 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
|
// 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.
|
// 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 {
|
if r := all.FindByGoPath(gopath); r != nil {
|
||||||
// already had this gopath
|
// 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
|
// add a new one here
|
||||||
newr := Repo{
|
newr := Repo{
|
||||||
FullPath: filepath.Join(basepath, gopath),
|
FullPath: filepath.Join(basepath, gopath),
|
||||||
|
@ -22,5 +36,39 @@ func (all *Repos) NewGoPath(basepath string, gopath string) *Repo {
|
||||||
newr.UpdateGit()
|
newr.UpdateGit()
|
||||||
|
|
||||||
all.add(&newr)
|
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
|
||||||
}
|
}
|
||||||
|
|
13
repo.proto
13
repo.proto
|
@ -11,12 +11,15 @@ import "google/protobuf/timestamp.proto"; // Import the well-known type for Time
|
||||||
|
|
||||||
message Repo {
|
message Repo {
|
||||||
string fullPath = 1; // the actual path to the .git directory: '/home/devel/golang.org/x/tools'
|
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'
|
repeated Ref refs = 2;
|
||||||
bool library = 3; // if this is a golang library
|
google.protobuf.Timestamp lastPull = 3; // last time a git pull was done
|
||||||
repeated Ref refs = 4;
|
|
||||||
repeated GoDep GoDeps = 5;
|
// things specific to golang projects
|
||||||
google.protobuf.Timestamp lastPull = 6; // last time a git pull was done
|
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
|
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 {
|
message Repos {
|
||||||
|
|
|
@ -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
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
|
@ -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)
|
||||||
|
}
|
|
@ -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
|
||||||
|
}
|
Loading…
Reference in New Issue