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
|
||||
|
||||
example/example
|
||||
scanGoSrc/scanGoSrc
|
||||
|
|
1
Makefile
1
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
|
||||
|
|
|
@ -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
|
||||
|
||||
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
|
||||
}
|
||||
|
|
13
repo.proto
13
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 {
|
||||
|
|
|
@ -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