Compare commits
66 Commits
Author | SHA1 | Date |
---|---|---|
|
7e1804f6e3 | |
|
8ceec9210d | |
|
cf6db578a4 | |
|
da485dcc3f | |
|
5377a89d2c | |
|
f7d6dfa6a7 | |
|
281ffbc75b | |
|
4193f41847 | |
|
9d5bae8a14 | |
|
f540aab434 | |
|
a170250cb4 | |
|
2fc67512c8 | |
|
eaadfa21d3 | |
|
22ebf174c8 | |
|
9a87c93bad | |
|
b7b18626d8 | |
|
7900b1416e | |
|
5c84b9ab66 | |
|
c09e292a66 | |
|
3278f6400e | |
|
83ad663fc0 | |
|
f70f54615f | |
|
018772dbfb | |
|
9baa477990 | |
|
ab01c2cd60 | |
|
c89f101fb2 | |
|
23d7ad1581 | |
|
ec4acd425c | |
|
0614066fdb | |
|
b60279b19a | |
|
95fcacfde0 | |
|
b6a71a515f | |
|
47ee3f1493 | |
|
329710f9e7 | |
|
f7b5e1a83e | |
|
7c37e3841a | |
|
f146bf4ef0 | |
|
d9d90e9e12 | |
|
393b91c415 | |
|
b412e50df0 | |
|
aa06450042 | |
|
121e9f08da | |
|
df19b5b8f8 | |
|
0efc3c67ca | |
|
667257595d | |
|
76a0347fdf | |
|
66738e4300 | |
|
3e4b1ddc83 | |
|
9ec7b4394f | |
|
1191b9b65d | |
|
52b8a4e312 | |
|
b770759167 | |
|
0898c24f45 | |
|
58c64cd53b | |
|
f29f25b9b7 | |
|
4328692039 | |
|
244bf612f9 | |
|
f4ac491490 | |
|
bdf9d97cf9 | |
|
a822e1e4f0 | |
|
cee7e25f3d | |
|
9b8cb52b7b | |
|
538531f503 | |
|
e8f29e593d | |
|
b8d0864c37 | |
|
156af56859 |
|
@ -1,5 +1,5 @@
|
|||
go.*
|
||||
|
||||
*.swp
|
||||
*.patch
|
||||
*.mbox
|
||||
*.pb.go
|
||||
|
||||
forgeConfig/forgeConfig
|
||||
|
|
2
Makefile
2
Makefile
|
@ -20,7 +20,7 @@ goimports:
|
|||
goimports -w *.go
|
||||
|
||||
clean:
|
||||
rm -f *.pb.go
|
||||
rm -f *.pb.go *.patch
|
||||
-rm -f go.*
|
||||
go-mod-clean --purge
|
||||
|
||||
|
|
24
build.go
24
build.go
|
@ -58,6 +58,9 @@ func (f *Forge) doBuild(repo *gitpb.Repo, userFlags []string, goWhat string) err
|
|||
data, _ := repo.ReadFile(".forge")
|
||||
log.Info(".forge =", string(data))
|
||||
log.Info("todo: do the custom build instructions")
|
||||
basedir, filename := filepath.Split(repo.GetGoPath())
|
||||
log.Info("touching filename", basedir, filename)
|
||||
repo.RunVerbose([]string{"touch", filename})
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -115,7 +118,8 @@ func (f *Forge) doBuild(repo *gitpb.Repo, userFlags []string, goWhat string) err
|
|||
|
||||
// set standard ldflag options
|
||||
now := time.Now()
|
||||
datestamp := now.UTC().Format("2006/01/02_1504_UTC")
|
||||
// datestamp := now.UTC().Format("2006/01/02_1504_UTC")
|
||||
datestamp := now.UTC().Format("2006-01-02_15:04:05_UTC") // 2006-01-02 15:04:05 UTC
|
||||
// log.Info("datestamp =", datestamp)
|
||||
// add some standard golang flags
|
||||
ldflags := "-X main.VERSION=" + version + " "
|
||||
|
@ -205,3 +209,21 @@ func (f *Forge) FindWorkingDirRepo() *gitpb.Repo {
|
|||
basedir = strings.Trim(basedir, "/")
|
||||
return f.FindByGoPath(basedir)
|
||||
}
|
||||
|
||||
// Never do this. this is stupid. fix your repo
|
||||
// Never try to version & release broken repos
|
||||
// leave this code here as a reminder to never attempt this
|
||||
func (f *Forge) forgeIgnoreGoMod(repo *gitpb.Repo) bool {
|
||||
if !repo.Exists(".forge") {
|
||||
return false
|
||||
}
|
||||
log.Info("custom build instructions")
|
||||
data, _ := repo.ReadFile(".forge")
|
||||
log.Info(".forge =", string(data))
|
||||
for _, line := range strings.Split(string(data), "\n") {
|
||||
if strings.Contains(line, "forge:ignore:gomod") { // this is stupid
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -0,0 +1,161 @@
|
|||
package forgepb
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"go.wit.com/lib/protobuf/gitpb"
|
||||
"go.wit.com/log"
|
||||
)
|
||||
|
||||
// This will recreate your go.sum and go.mod files
|
||||
var cleanVerbose bool = false
|
||||
|
||||
// checks to see if every 'master' git branch version
|
||||
// matches the go.sum file
|
||||
func (f *Forge) CleanGoDepsCheckOk(check *gitpb.Repo) error {
|
||||
var err error = nil
|
||||
var fixes [][]string
|
||||
log.Printf("current repo %s go dependancy count: %d", check.GetGoPath(), check.GoDepsLen())
|
||||
if check.GoDeps == nil {
|
||||
return errors.New("check.GoDeps == nil")
|
||||
}
|
||||
all := check.GoDeps.SortByGoPath()
|
||||
for all.Scan() {
|
||||
depRepo := all.Next()
|
||||
found := f.FindByGoPath(depRepo.GetGoPath())
|
||||
if found == nil {
|
||||
if f.CheckOverride(depRepo.GetGoPath()) {
|
||||
// skip this gopath because it's probably broken forever
|
||||
continue
|
||||
}
|
||||
log.Info("not found:", depRepo.GetGoPath())
|
||||
err = errors.New("not found: " + depRepo.GetGoPath())
|
||||
continue
|
||||
}
|
||||
// log.Info("found dep", depRepo.GetGoPath())
|
||||
if depRepo.GetVersion() != found.GetMasterVersion() {
|
||||
check := f.FindByGoPath(depRepo.GetGoPath())
|
||||
var ends string
|
||||
if check.CheckDirty() {
|
||||
ends = "(dirty) "
|
||||
}
|
||||
|
||||
if f.Config.IsReadOnly(check.GetGoPath()) {
|
||||
ends += "(ignoring read-only) "
|
||||
if cleanVerbose {
|
||||
log.Printf("%-48s ok error .%s. vs .%s. %s", depRepo.GetGoPath(),
|
||||
depRepo.GetVersion(), found.GetMasterVersion(), ends)
|
||||
}
|
||||
} else {
|
||||
if f.CheckOverride(depRepo.GetGoPath()) {
|
||||
ends += "(override) "
|
||||
if cleanVerbose {
|
||||
log.Printf("%-48s ok error .%s. vs .%s. %s", depRepo.GetGoPath(),
|
||||
depRepo.GetVersion(), found.GetMasterVersion(), ends)
|
||||
// skip this gopath because it's probably broken forever
|
||||
}
|
||||
continue
|
||||
} else {
|
||||
log.Printf("%-48s error %10s vs %10s %s", depRepo.GetGoPath(),
|
||||
depRepo.GetVersion(), found.GetMasterVersion(), ends)
|
||||
errs := fmt.Sprintf("%s error %s vs %s %s", depRepo.GetGoPath(),
|
||||
depRepo.GetVersion(), found.GetMasterVersion(), ends)
|
||||
if ok, _ := ValidGoVersion(found.GetMasterVersion()); ok {
|
||||
// can't go get invalid version numbers
|
||||
cmd := []string{"go", "get", depRepo.GetGoPath() + "@" + found.GetMasterVersion()}
|
||||
fixes = append(fixes, cmd)
|
||||
}
|
||||
err = errors.New(errs)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for i, cmd := range fixes {
|
||||
log.Info("try cmd", i, cmd)
|
||||
check.RunRealtime(cmd)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (f *Forge) TrimGoSum(check *gitpb.Repo) error {
|
||||
var stuff map[string]string
|
||||
stuff = make(map[string]string)
|
||||
|
||||
var modver map[string]string
|
||||
modver = make(map[string]string)
|
||||
|
||||
var good map[string]bool
|
||||
good = make(map[string]bool)
|
||||
|
||||
if check == nil {
|
||||
log.Info("boo, check == nil")
|
||||
return errors.New("*repo == nil")
|
||||
}
|
||||
filename := filepath.Join(filepath.Join(check.FullPath, "go.sum"))
|
||||
data, err := os.ReadFile(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, line := range strings.Split(string(data), "\n") {
|
||||
parts := strings.Fields(line)
|
||||
if len(parts) < 3 {
|
||||
log.Info("WIERD OR BAD:", line)
|
||||
continue
|
||||
}
|
||||
|
||||
gopath := parts[0]
|
||||
version := parts[1]
|
||||
hash := parts[2]
|
||||
|
||||
if strings.HasSuffix(version, "/go.mod") {
|
||||
if _, ok := stuff[gopath]; ok {
|
||||
if cleanVerbose {
|
||||
log.Info("MATCHED: gopath:", gopath, "version:", version)
|
||||
}
|
||||
modver[gopath] = version + " " + hash
|
||||
good[gopath] = true
|
||||
} else {
|
||||
if cleanVerbose {
|
||||
log.Info("GARBAGE: gopath:", gopath, "version:", version)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if cleanVerbose {
|
||||
log.Info("GOOD : gopath:", gopath, "version:", version)
|
||||
}
|
||||
stuff[gopath] = version + " " + hash
|
||||
}
|
||||
}
|
||||
|
||||
keys := make([]string, 0, len(stuff))
|
||||
for k := range stuff {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
|
||||
// rewrite the go.sum file
|
||||
newfilename := filepath.Join(filepath.Join(check.FullPath, "go.sum"))
|
||||
newf, err := os.OpenFile(newfilename, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer newf.Close()
|
||||
sort.Strings(keys)
|
||||
for _, gopath := range keys {
|
||||
if good[gopath] {
|
||||
fmt.Fprintf(newf, "%s %s\n", gopath, stuff[gopath])
|
||||
fmt.Fprintf(newf, "%s %s\n", gopath, modver[gopath])
|
||||
check := f.FindByGoPath(gopath)
|
||||
if check == nil {
|
||||
log.Info("gopath does not really exist:", gopath)
|
||||
}
|
||||
}
|
||||
}
|
||||
// fmt.Fprintln(newf, "test")
|
||||
return nil
|
||||
}
|
2
clone.go
2
clone.go
|
@ -1,3 +1,5 @@
|
|||
// Copyright 2025 WIT.COM Inc Licensed GPL 3.0
|
||||
|
||||
package forgepb
|
||||
|
||||
import (
|
||||
|
|
11
config.go
11
config.go
|
@ -1,3 +1,5 @@
|
|||
// Copyright 2025 WIT.COM Inc Licensed GPL 3.0
|
||||
|
||||
package forgepb
|
||||
|
||||
// functions to import and export the protobuf
|
||||
|
@ -8,8 +10,10 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"go.wit.com/log"
|
||||
timestamppb "google.golang.org/protobuf/types/known/timestamppb"
|
||||
)
|
||||
|
||||
func (f *Forge) ConfigSave() error {
|
||||
|
@ -28,6 +32,11 @@ func (f *Forge) ConfigSave() error {
|
|||
}
|
||||
}
|
||||
if f.Repos != nil {
|
||||
if f.HasFullScan() {
|
||||
f.Repos.HasFullScan = true
|
||||
t := time.Now()
|
||||
f.Repos.FullScan = timestamppb.New(t)
|
||||
}
|
||||
if e := f.Repos.ConfigSave(); e != nil {
|
||||
log.Info("forge.Repos.ConfigSave() error", e)
|
||||
err = e
|
||||
|
@ -43,7 +52,7 @@ func (f *ForgeConfigs) ConfigSave() error {
|
|||
log.Info("proto.Marshal() failed len", len(data), err)
|
||||
return err
|
||||
}
|
||||
log.Info("forgepb.ConfigSave() proto.Marshal() worked len", len(data))
|
||||
// log.Info("forgepb.ConfigSave() proto.Marshal() worked len", len(data))
|
||||
|
||||
s := f.FormatTEXT()
|
||||
configWrite("forge.text", []byte(s))
|
||||
|
|
|
@ -7,7 +7,6 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
@ -15,12 +14,8 @@ import (
|
|||
|
||||
func backupConfig() error {
|
||||
// make a new dir to backup the files
|
||||
now := time.Now()
|
||||
// timestamp := now.Format("2022.07.18.190545") // 50yr shout out to K&R
|
||||
timestamp := now.Format("2006.01.02.150405") // bummer. other date doesn't work?
|
||||
srcDir := filepath.Join(os.Getenv("FORGE_CONFIG"))
|
||||
destDir := filepath.Join(os.Getenv("FORGE_CONFIG"), timestamp)
|
||||
|
||||
destDir := filepath.Join(os.Getenv("FORGE_CONFIG"), "backup")
|
||||
return backupFiles(srcDir, destDir)
|
||||
}
|
||||
|
||||
|
@ -44,7 +39,7 @@ func backupFiles(srcDir string, destDir string) error {
|
|||
continue
|
||||
}
|
||||
|
||||
log.Println("backing up file", entry.Name())
|
||||
// log.Println("backing up file", entry.Name())
|
||||
srcPath := filepath.Join(srcDir, entry.Name())
|
||||
destPath := filepath.Join(destDir, entry.Name())
|
||||
|
||||
|
@ -64,6 +59,9 @@ func copyFile(src, dest string) error {
|
|||
}
|
||||
defer srcFile.Close()
|
||||
|
||||
now := time.Now()
|
||||
timestamp := now.Format("2006.01.02.150405") // bummer. other date doesn't work?
|
||||
dest = dest + timestamp
|
||||
destFile, err := os.Create(dest)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package forgepb
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"go.wit.com/lib/protobuf/gitpb"
|
||||
|
@ -16,21 +18,18 @@ import (
|
|||
// it re-scans the go.sum file. DOES NOT MODIFY ANYTHING
|
||||
// this is the last thing to run to double check everything
|
||||
// before 'git tag' or git push --tags
|
||||
func (f *Forge) FinalGoDepsCheckOk(check *gitpb.Repo, verbose bool) bool {
|
||||
var good bool = true
|
||||
func (f *Forge) FinalGoDepsCheckOk(check *gitpb.Repo, verbose bool) error {
|
||||
if check == nil {
|
||||
log.Info("boo, check == nil")
|
||||
return false
|
||||
return errors.New("FinalGoDepsCheckOk() boo, check == nil")
|
||||
}
|
||||
|
||||
// parse the go.mod and go.sum files
|
||||
if !check.ParseGoSum() {
|
||||
log.Info("forge.FinalGoDepsCheckOk() failed")
|
||||
return false
|
||||
return fmt.Errorf("forge.ParseGoSum() failed. go.mod & go.sum are broken")
|
||||
}
|
||||
|
||||
if check.GetGoPrimitive() {
|
||||
return true
|
||||
return nil
|
||||
}
|
||||
|
||||
deps := check.GoDeps.SortByGoPath()
|
||||
|
@ -42,8 +41,10 @@ func (f *Forge) FinalGoDepsCheckOk(check *gitpb.Repo, verbose bool) bool {
|
|||
// skip this gopath because it's probably broken forever
|
||||
continue
|
||||
}
|
||||
log.Info("not found:", depRepo.GetGoPath())
|
||||
good = false
|
||||
return fmt.Errorf("dep not found: %s", depRepo.GetGoPath())
|
||||
}
|
||||
if depRepo.GetVersion() == found.GetMasterVersion() {
|
||||
// log.Printf("%-48s error ?? %-10s vs %-10s\n", depRepo.GetGoPath(), depRepo.GetVersion(), found.GetMasterVersion())
|
||||
continue
|
||||
}
|
||||
// log.Info("found dep", depRepo.GetGoPath())
|
||||
|
@ -61,51 +62,93 @@ func (f *Forge) FinalGoDepsCheckOk(check *gitpb.Repo, verbose bool) bool {
|
|||
// skip this gopath because it's probably broken forever
|
||||
continue
|
||||
} else {
|
||||
log.Printf("%-48s error %10s vs %10s\n", depRepo.GetGoPath(), depRepo.GetVersion(), found.GetTargetVersion())
|
||||
good = false
|
||||
// log.Printf("%-48s error ?? %-10s vs %-10s\n", depRepo.GetGoPath(), depRepo.GetVersion(), found.GetMasterVersion())
|
||||
// log.Printf("%-48s error %10s vs %10s\n", depRepo.GetGoPath(), depRepo.GetVersion(), found.GetTargetVersion())
|
||||
return fmt.Errorf("%-48s error %10s vs %10s", depRepo.GetGoPath(), depRepo.GetVersion(), found.GetMasterVersion())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if good {
|
||||
log.Printf("current repo %s go dependancy count: %d\n", check.GetGoPath(), check.GoDepsLen())
|
||||
}
|
||||
return good
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *Forge) CheckOverride(gopath string) bool {
|
||||
if gopath == "cloud.google.com/go" {
|
||||
log.Info("CheckOverride() is ignoring", gopath)
|
||||
// log.Info("CheckOverride() is ignoring", gopath)
|
||||
return true
|
||||
}
|
||||
if gopath == "bou.ke/monkey" {
|
||||
log.Info("CheckOverride() is ignoring", gopath)
|
||||
// log.Info("CheckOverride() is ignoring", gopath)
|
||||
return true
|
||||
}
|
||||
if gopath == "github.com/posener/complete/v2" {
|
||||
log.Info("CheckOverride() is ignoring", gopath)
|
||||
// log.Info("CheckOverride() is ignoring", gopath)
|
||||
return true
|
||||
}
|
||||
if strings.HasPrefix(gopath, "github.com/go-gl") {
|
||||
log.Info("CheckOverride() is ignoring", gopath)
|
||||
// log.Info("CheckOverride() is ignoring", gopath)
|
||||
return true
|
||||
}
|
||||
if strings.HasPrefix(gopath, "google.golang.org") {
|
||||
log.Info("CheckOverride() is ignoring", gopath)
|
||||
// log.Info("CheckOverride() is ignoring", gopath)
|
||||
return true
|
||||
}
|
||||
if strings.HasPrefix(gopath, "go.opencensus.io") {
|
||||
log.Info("CheckOverride() is ignoring", gopath)
|
||||
// log.Info("CheckOverride() is ignoring", gopath)
|
||||
return true
|
||||
}
|
||||
if strings.HasPrefix(gopath, "github.com/nicksnyder/go-i18n") {
|
||||
log.Info("CheckOverride() is ignoring", gopath)
|
||||
// log.Info("CheckOverride() is ignoring", gopath)
|
||||
return true
|
||||
}
|
||||
// fuckit for now. just blacklist github.com
|
||||
if strings.HasPrefix(gopath, "github.com/") {
|
||||
log.Info("CheckOverride() is ignoring", gopath)
|
||||
// log.Info("CheckOverride() is ignoring", gopath)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (f *Forge) TestGoDepsCheckOk(godeps *gitpb.GoDeps, verbose bool) error {
|
||||
if godeps == nil {
|
||||
return errors.New("forge.TestGoDepsCheckOk() godeps == nil")
|
||||
}
|
||||
all := godeps.SortByGoPath()
|
||||
for all.Scan() {
|
||||
depRepo := all.Next()
|
||||
found := f.FindByGoPath(depRepo.GetGoPath())
|
||||
if found == nil {
|
||||
if f.CheckOverride(depRepo.GetGoPath()) {
|
||||
// skip this gopath because it's probably broken forever
|
||||
continue
|
||||
}
|
||||
return fmt.Errorf("dep not found: %s", depRepo.GetGoPath())
|
||||
}
|
||||
if depRepo.GetVersion() == found.GetMasterVersion() {
|
||||
// log.Printf("%-48s error ?? %-10s vs %-10s\n", depRepo.GetGoPath(), depRepo.GetVersion(), found.GetMasterVersion())
|
||||
continue
|
||||
}
|
||||
// log.Info("found dep", depRepo.GetGoPath())
|
||||
if depRepo.GetVersion() != found.GetTargetVersion() {
|
||||
check := f.FindByGoPath(depRepo.GetGoPath())
|
||||
if f.Config.IsReadOnly(check.GetGoPath()) {
|
||||
if verbose {
|
||||
log.Printf("%-48s ok error .%s. vs .%s. (ignoring read-only repo)\n", depRepo.GetGoPath(), depRepo.GetVersion(), found.GetTargetVersion())
|
||||
}
|
||||
} else {
|
||||
if f.CheckOverride(depRepo.GetGoPath()) {
|
||||
if verbose {
|
||||
log.Printf("%-48s ok error .%s. vs .%s. (forge.CheckOverride())\n", depRepo.GetGoPath(), depRepo.GetVersion(), found.GetTargetVersion())
|
||||
}
|
||||
// skip this gopath because it's probably broken forever
|
||||
continue
|
||||
} else {
|
||||
// log.Printf("%-48s error ?? %-10s vs %-10s\n", depRepo.GetGoPath(), depRepo.GetVersion(), found.GetMasterVersion())
|
||||
// log.Printf("%-48s error %10s vs %10s\n", depRepo.GetGoPath(), depRepo.GetVersion(), found.GetTargetVersion())
|
||||
return fmt.Errorf("%-48s error %10s vs %10s", depRepo.GetGoPath(), depRepo.GetVersion(), found.GetMasterVersion())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// Copyright 2025 WIT.COM Inc Licensed GPL 3.0
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package forgepb;
|
||||
|
@ -12,33 +14,49 @@ import "google/protobuf/timestamp.proto"; // Import the well-known type for Time
|
|||
// package names sometimes must be different than the binary name
|
||||
// for example 'zookeeper' is packaged as 'zookeeper-go'
|
||||
// due to the prior apache foundation project. This happens and is ok!
|
||||
message ForgeConfig { // `autogenpb:nomutex`
|
||||
string goPath = 1; // `autogenpb:unique` `autogenpb:sort` // Examples: 'go.wit.com/apps/go-clone' or "~/mythings" or "/home/src/foo"
|
||||
message ForgeConfig { // `autogenpb:nomutex`
|
||||
string goPath = 1; // `autogenpb:unique` `autogenpb:sort` // Examples: 'go.wit.com/apps/go-clone' or "~/mythings" or "/home/src/foo"
|
||||
|
||||
bool writable = 2; // if you have write access to the repo
|
||||
bool readOnly = 3; // the opposite, but needed for now because I don't know what I'm doing
|
||||
bool private = 4; // if the repo can be published
|
||||
bool directory = 5; // everything in this directory should use these writable & private values
|
||||
bool favorite = 6; // you like this. always git clone/go clone this repo
|
||||
bool interesting = 7; // this is something interesting you found and want to remember it
|
||||
bool writable = 2; // if you have write access to the repo
|
||||
bool readOnly = 3; // the opposite, but needed for now because I don't know what I'm doing
|
||||
bool private = 4; // if the repo can be published
|
||||
bool directory = 5; // everything in this directory should use these writable & private values
|
||||
bool favorite = 6; // you like this. always git clone/go clone this repo
|
||||
bool interesting = 7; // this is something interesting you found and want to remember it
|
||||
|
||||
string masterBranchName = 8; // git 'main' or 'master' branch name
|
||||
string develBranchName = 9; // whatever the git 'devel' branch name is
|
||||
string userBranchName = 10; // whatever your username branch is
|
||||
string masterBranchName = 8; // git 'main' or 'master' branch name
|
||||
string develBranchName = 9; // whatever the git 'devel' branch name is
|
||||
string userBranchName = 10; // whatever your username branch is
|
||||
|
||||
string debName = 11; // the actual name used with 'apt install' (or distro apt equivalent.
|
||||
// todo: appeal to everyone to alias 'apt' on fedora, gentoo, arch, etc to alias 'apt install'
|
||||
// so we can make easier instructions for new linux users. KISS
|
||||
string debName = 11; // the actual name used with 'apt install' (or distro apt equivalent.
|
||||
// todo: appeal to everyone to alias 'apt' on fedora, gentoo, arch, etc to alias 'apt install'
|
||||
// so we can make easier instructions for new linux users. KISS
|
||||
|
||||
google.protobuf.Timestamp verstamp = 12; // the git commit timestamp of the version
|
||||
string goSrc = 13; // is ~/go/src unless a go.work file is found
|
||||
google.protobuf.Timestamp verstamp = 12; // the git commit timestamp of the version
|
||||
string goSrc = 13; // is ~/go/src unless a go.work file is found
|
||||
}
|
||||
|
||||
message ForgeConfigs { // `autogenpb:marshal` `autogenpb:nomutex`
|
||||
string uuid = 1; // `autogenpb:uuid:1941cd4f-1cfd-4bf6-aa75-c2c391907e81`
|
||||
string version = 2; // `autogenpb:version:v0.0.47`
|
||||
repeated ForgeConfig ForgeConfigs = 3;
|
||||
string username = 4; // what to use for the user branch (default ENV{USER})
|
||||
string xterm = 14; // what xterm the user wants as the default
|
||||
repeated string xtermArgv = 15; // the argv line for xterm
|
||||
// todo: fix autogenpb to look for enum
|
||||
enum ForgeMode {
|
||||
MASTER = 0; // "release mode"
|
||||
DEVEL = 1; // "patch mode"
|
||||
USER = 2; // "work mode"
|
||||
}
|
||||
|
||||
message ForgeConfigs { // `autogenpb:marshal` `autogenpb:nomutex`
|
||||
string uuid = 1; // `autogenpb:uuid:1941cd4f-1cfd-4bf6-aa75-c2c391907e81`
|
||||
string version = 2; // `autogenpb:version:v0.0.47`
|
||||
repeated ForgeConfig ForgeConfigs = 3;
|
||||
string username = 4; // what to use for the user branch (default ENV{USER})
|
||||
string xterm = 5; // what xterm the user wants as the default
|
||||
repeated string xtermArgv = 6; // the argv line for xterm
|
||||
string defaultGui = 7; // default GUI plugin to use
|
||||
ForgeMode mode = 8; // what "mode" forge is in
|
||||
}
|
||||
|
||||
// this generic message is used by autogen to identify and
|
||||
// then dump the uuid and version from any arbitrary .pb file
|
||||
message Identify { // `autogenpb:marshal`
|
||||
string uuid = 1; //
|
||||
string version = 2; //
|
||||
}
|
||||
|
|
173
gitCheckout.go
173
gitCheckout.go
|
@ -1,173 +0,0 @@
|
|||
package forgepb
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"go.wit.com/lib/protobuf/gitpb"
|
||||
"go.wit.com/log"
|
||||
)
|
||||
|
||||
func (f *Forge) GitPull() bool {
|
||||
f.Repos.RillGitPull(5, 5)
|
||||
/*
|
||||
|
||||
var localonly int
|
||||
var badmap int
|
||||
|
||||
log.Log(WARN, "running git pull everywhere")
|
||||
var failed int = 0
|
||||
for all.Scan() {
|
||||
repo := all.Next()
|
||||
if out, err := repo.GitPull(); err == nil {
|
||||
log.Log(WARN, "Ran git pull ok", repo.GetGoPath(), out)
|
||||
} else {
|
||||
failed += 1
|
||||
// repo.DumpTags()
|
||||
if errors.Is(repostatus.ErrorGitPullOnLocal, err) {
|
||||
localonly += 1
|
||||
continue
|
||||
}
|
||||
badmap += 1
|
||||
log.Log(WARN, "bad unknown git error", repo.GetGoPath(), out, err)
|
||||
}
|
||||
}
|
||||
log.Log(WARN, "Ran git pull in all repos. failure count =", failed)
|
||||
log.Log(WARN, "Ran git pull in all repos. bad errors =", badmap)
|
||||
if localonly != 0 {
|
||||
log.Log(WARN, "Ran git pull in all repos. ignored local only branches =", localonly)
|
||||
}
|
||||
*/
|
||||
return true
|
||||
}
|
||||
|
||||
func (f *Forge) CheckoutDevel() bool {
|
||||
log.Log(WARN, "running git checkout devel everwhere")
|
||||
var failed int = 0
|
||||
var count int = 0
|
||||
all := f.Repos.SortByFullPath()
|
||||
for all.Scan() {
|
||||
repo := all.Next()
|
||||
count += 1
|
||||
if repo.CheckoutDevel() {
|
||||
// checkout ok
|
||||
} else {
|
||||
dname := repo.GetDevelBranchName()
|
||||
if err := f.makeBranch(repo, dname); err != nil {
|
||||
log.Info(repo.GetGoPath(), "can not make devel branch", dname)
|
||||
failed += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
log.Log(WARN, "Ran git checkout in", count, "repos. failure count =", failed)
|
||||
return true
|
||||
}
|
||||
|
||||
func (f *Forge) MakeDevelBranch(repo *gitpb.Repo) error {
|
||||
dname := repo.GetDevelBranchName()
|
||||
if dname == "" {
|
||||
dname = f.configDevelBranchName(repo)
|
||||
}
|
||||
if err := f.makeBranch(repo, dname); err != nil {
|
||||
return err
|
||||
}
|
||||
repo.DevelBranchName = dname
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *Forge) MakeUserBranch(repo *gitpb.Repo) error {
|
||||
uname := repo.GetUserBranchName()
|
||||
if uname == "" {
|
||||
uname = f.configUserBranchName(repo)
|
||||
}
|
||||
if err := f.makeBranch(repo, uname); err != nil {
|
||||
return err
|
||||
}
|
||||
repo.UserBranchName = uname
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *Forge) makeBranch(repo *gitpb.Repo, bname string) error {
|
||||
if repo.IsLocalBranch(bname) {
|
||||
// branch already exists in refs/heads/
|
||||
return nil
|
||||
}
|
||||
if repo.IsBranch(bname) {
|
||||
// branch already exists refs/remotes/
|
||||
return nil
|
||||
} else {
|
||||
log.Info("makeBranch() says", bname, "does not exist")
|
||||
loop := repo.Tags.All()
|
||||
for loop.Scan() {
|
||||
t := loop.Next()
|
||||
log.Info("LocalTagExists() tag:", t.Refname)
|
||||
}
|
||||
}
|
||||
mname := repo.GetMasterBranchName()
|
||||
cname := repo.GetCurrentBranchName()
|
||||
if mname != cname {
|
||||
return errors.New("can only make branches from master branch")
|
||||
}
|
||||
cmd := []string{"git", "branch", bname}
|
||||
if err := repo.StrictRun(cmd); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *Forge) CheckoutMaster() bool {
|
||||
log.Log(WARN, "running git checkout master everwhere")
|
||||
var failed int = 0
|
||||
var count int = 0
|
||||
all := f.Repos.SortByFullPath()
|
||||
for all.Scan() {
|
||||
repo := all.Next()
|
||||
count += 1
|
||||
if repo.CheckoutMaster() {
|
||||
// checkout ok
|
||||
} else {
|
||||
failed += 1
|
||||
}
|
||||
}
|
||||
log.Log(WARN, "Ran git checkout in", count, "repos. failure count =", failed)
|
||||
return true
|
||||
}
|
||||
|
||||
func (f *Forge) CheckoutUser() bool {
|
||||
log.Log(WARN, "running git checkout user everwhere")
|
||||
var failed int = 0
|
||||
var count int = 0
|
||||
all := f.Repos.SortByFullPath()
|
||||
for all.Scan() {
|
||||
repo := all.Next()
|
||||
if repo.GetCurrentBranchName() == repo.GetUserBranchName() {
|
||||
// already on the user branch
|
||||
continue
|
||||
}
|
||||
count += 1
|
||||
if repo.CheckoutUser() {
|
||||
// checkout ok
|
||||
} else {
|
||||
failed += 1
|
||||
}
|
||||
}
|
||||
log.Log(WARN, "Ran git checkout in", count, "repos. failure count =", failed)
|
||||
return true
|
||||
}
|
||||
|
||||
func (f *Forge) CheckoutUserForce() bool {
|
||||
log.Log(WARN, "running git checkout user everwhere")
|
||||
var failed int = 0
|
||||
var count int = 0
|
||||
all := f.Repos.SortByFullPath()
|
||||
for all.Scan() {
|
||||
repo := all.Next()
|
||||
count += 1
|
||||
if repo.CheckoutUser() {
|
||||
// checkout ok
|
||||
} else {
|
||||
failed += 1
|
||||
}
|
||||
}
|
||||
log.Log(WARN, "Ran git checkout in", count, "repos. failure count =", failed)
|
||||
return true
|
||||
}
|
|
@ -12,6 +12,10 @@ import (
|
|||
"go.wit.com/log"
|
||||
)
|
||||
|
||||
func (f *Forge) GetHome() string {
|
||||
return f.goSrc
|
||||
}
|
||||
|
||||
// look for a go.work file
|
||||
// otherwise use ~/go/src
|
||||
func (f *Forge) findGoSrc() (string, error) {
|
||||
|
|
45
goSrcScan.go
45
goSrcScan.go
|
@ -46,6 +46,13 @@ func (f *Forge) ScanGoSrc() (bool, error) {
|
|||
return true, err
|
||||
}
|
||||
|
||||
func (f *Forge) ScanDir(dir string) *gitpb.Repo {
|
||||
// repo, err := f.NewGoRepo(gopath, "")
|
||||
repo, err := f.Repos.NewGoRepo(dir, "")
|
||||
log.Info("need to implement ScanDir()", dir, err)
|
||||
return repo
|
||||
}
|
||||
|
||||
// doesn't enter the directory any further when it finds a .git/
|
||||
// not stupid like my old version
|
||||
func gitDirectoriesNew(srcDir string) ([]string, error) {
|
||||
|
@ -160,44 +167,10 @@ func (f *Forge) rillScanDirs(gopaths []string) (int, error) {
|
|||
|
||||
func (f *Forge) checkpath(gopath string, url string) (*gitpb.Repo, error) {
|
||||
fullpath := filepath.Join(f.GetGoSrc(), gopath)
|
||||
log.Info("checkpath()", gopath, fullpath)
|
||||
log.Info("forge creating protobuf for", fullpath)
|
||||
repo, err := f.NewGoRepo(gopath, "")
|
||||
if err != nil {
|
||||
log.Info("checkpath()", gopath, err)
|
||||
log.Info("\tprotobuf error", gopath, err)
|
||||
}
|
||||
return repo, err
|
||||
}
|
||||
|
||||
func (f *Forge) RillRedoGoMod() int {
|
||||
var all []*gitpb.Repo
|
||||
tmp := f.Repos.SortByFullPath()
|
||||
for tmp.Scan() {
|
||||
repo := tmp.Next()
|
||||
if !repo.IsValidDir() {
|
||||
log.Printf("%10s %-50s", "why am I in RillRedoGoMod? old?", repo.GetGoPath())
|
||||
continue
|
||||
}
|
||||
all = append(all, repo)
|
||||
}
|
||||
// Convert a slice of user IDs into a channel
|
||||
ids := rill.FromSlice(all, nil)
|
||||
|
||||
var counter int
|
||||
// Read users from the API.
|
||||
// Concurrency = 20
|
||||
dirs := rill.Map(ids, 50, func(id *gitpb.Repo) (*gitpb.Repo, error) {
|
||||
return id, nil
|
||||
})
|
||||
|
||||
err := rill.ForEach(dirs, 20, func(repo *gitpb.Repo) error {
|
||||
counter += 1
|
||||
// repo.RedoGoMod()
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
log.Info("rill.ForEach() error:", err)
|
||||
}
|
||||
|
||||
return counter
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// Copyright 2025 WIT.COM Inc Licensed GPL 3.0
|
||||
|
||||
package forgepb
|
||||
|
||||
import (
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
// Copyright 1994-2025 WIT.COM Inc Licensed GPL 3.0
|
||||
|
||||
package forgepb
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os/user"
|
||||
|
||||
"go.wit.com/log"
|
||||
)
|
||||
|
||||
/*
|
||||
func (f *Forge) HttpPostMachine(url string) ([]byte, error) {
|
||||
if f.Machine == nil {
|
||||
// run f.InitMachine() here?
|
||||
log.Info("you must run f.InitMachine()")
|
||||
return nil, fmt.Errorf("you must run f.InitMachine()")
|
||||
}
|
||||
if f.Machine.Hostname == "" {
|
||||
log.Info("WTF. hostname is blank")
|
||||
} else {
|
||||
log.Info("GOOD. hostname is set to", f.Machine.Hostname)
|
||||
}
|
||||
log.Info("GOOD2. hostname is set to", f.Machine.Hostname)
|
||||
msg, err := f.Machine.Marshal()
|
||||
if err != nil {
|
||||
log.Info("proto.Marshal() failed:", err)
|
||||
return nil, err
|
||||
}
|
||||
log.Info("GOOD3. hostname is set to", f.Machine.Hostname)
|
||||
|
||||
check := new(zoopb.Machine)
|
||||
check.Unmarshal(msg)
|
||||
if check == nil {
|
||||
log.Info("WTF. check == nil")
|
||||
}
|
||||
log.Info("good? check.hostname =", check.Hostname)
|
||||
return f.HttpPost(url, msg)
|
||||
}
|
||||
*/
|
||||
|
||||
func (f *Forge) HttpPost(url string, data []byte) ([]byte, error) {
|
||||
var err error
|
||||
var req *http.Request
|
||||
|
||||
req, err = http.NewRequest(http.MethodPost, url, bytes.NewBuffer(data))
|
||||
// log.Info("httpPost() with len", len(data), "url", url)
|
||||
|
||||
usr, _ := user.Current()
|
||||
req.Header.Set("author", usr.Username)
|
||||
/*
|
||||
if f.Machine == nil {
|
||||
// run f.InitMachine() here?
|
||||
log.Info("you must run f.InitMachine()")
|
||||
return nil, fmt.Errorf("you must run f.InitMachine()")
|
||||
}
|
||||
*/
|
||||
req.Header.Set("hostname", "fixme:hostname")
|
||||
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return []byte("client.Do(req) error"), err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
// log.Info("httpPost() with len", len(data))
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return body, err
|
||||
}
|
||||
|
||||
return body, nil
|
||||
}
|
2
human.go
2
human.go
|
@ -1,3 +1,5 @@
|
|||
// Copyright 2025 WIT.COM Inc Licensed GPL 3.0
|
||||
|
||||
package forgepb
|
||||
|
||||
import (
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// Copyright 2025 WIT.COM Inc Licensed GPL 3.0
|
||||
|
||||
package forgepb
|
||||
|
||||
import (
|
||||
|
@ -86,7 +88,7 @@ func (f *Forge) testGoRepo(check *gitpb.Repo) {
|
|||
data, _ := os.ReadFile(filepath.Join(check.FullPath, "go.mod"))
|
||||
log.Info(string(data))
|
||||
|
||||
if f.FinalGoDepsCheckOk(check, true) {
|
||||
if err := f.FinalGoDepsCheckOk(check, true); err == nil {
|
||||
log.Info("forge.FinalGoDepsCheck(check) worked!")
|
||||
} else {
|
||||
log.Info("forge.FinalGoDepsCheck(check) failed. boo.")
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
// Copyright 2025 WIT.COM Inc Licensed GPL 3.0
|
||||
|
||||
package forgepb
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
|
||||
"go.wit.com/lib/gui/shell"
|
||||
"go.wit.com/lib/protobuf/gitpb"
|
||||
|
@ -37,7 +40,7 @@ func (f *Forge) PrintHumanTable(allr *gitpb.Repos) {
|
|||
|
||||
var count int
|
||||
// log.Info(standardStart5("gopath", "cur name", "master", "user", "repo type"))
|
||||
log.Info(standardTable8("repopath", "cur br", "age", "target", "master", "devel", "user", "curver", "repo type"))
|
||||
log.Info(standardTable10("repopath", "cur br", "age", "master", "devel", "user", "curver", "lasttag", "next", "repo type"))
|
||||
all := allr.SortByFullPath()
|
||||
for all.Scan() {
|
||||
repo := all.Next()
|
||||
|
@ -53,8 +56,9 @@ func (f *Forge) PrintHumanTableDirty(allr *gitpb.Repos) {
|
|||
|
||||
var count int
|
||||
// log.Info(standardStart5("gopath", "cur name", "master", "user", "repo type"))
|
||||
log.Info(standardTable8("repopath", "cur br", "age", "target", "master", "devel", "user", "curver", "repo type"))
|
||||
all := allr.SortByFullPath()
|
||||
log.Info(standardTable10("repopath", "cur br", "age", "master", "devel", "user", "curver", "lasttag", "next", "repo type"))
|
||||
// all := allr.SortByFullPath()
|
||||
all := allr.All()
|
||||
for all.Scan() {
|
||||
repo := all.Next()
|
||||
f.printRepoToTable(repo)
|
||||
|
@ -101,7 +105,7 @@ func standardTable5(arg1, arg2, arg3, arg4, arg5 string) string {
|
|||
return fmt.Sprintf(s, arg1, arg2, arg3, arg4, arg5)
|
||||
}
|
||||
|
||||
func standardTable8(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 string) string {
|
||||
func standardTable10(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10 string) string {
|
||||
len1 := 40
|
||||
len2 := 12
|
||||
len3 := 6
|
||||
|
@ -109,8 +113,9 @@ func standardTable8(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 string)
|
|||
len5 := 16
|
||||
len6 := 16
|
||||
len7 := 16
|
||||
len8 := 16
|
||||
len9 := 8
|
||||
len8 := 12
|
||||
len9 := 12
|
||||
len10 := 8
|
||||
var s string
|
||||
if len(arg1) > len1 {
|
||||
arg1 = arg1[:len1]
|
||||
|
@ -137,12 +142,12 @@ func standardTable8(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 string)
|
|||
if len(arg6) > len6 {
|
||||
arg6 = arg6[:len6]
|
||||
}
|
||||
s += "%-" + fmt.Sprintf("%d", len6) + "s "
|
||||
s += "%-" + fmt.Sprintf("%d", len6) + "s "
|
||||
|
||||
if len(arg7) > len7 {
|
||||
arg7 = arg7[:len7]
|
||||
}
|
||||
s += "%-" + fmt.Sprintf("%d", len7) + "s "
|
||||
s += "%-" + fmt.Sprintf("%d", len7) + "s "
|
||||
|
||||
if len(arg8) > len8 {
|
||||
arg8 = arg8[:len8]
|
||||
|
@ -154,17 +159,26 @@ func standardTable8(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 string)
|
|||
}
|
||||
s += "%-" + fmt.Sprintf("%d", len9) + "s "
|
||||
|
||||
return fmt.Sprintf(s, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
|
||||
if len(arg10) > len10 {
|
||||
arg10 = arg10[:len10]
|
||||
}
|
||||
s += "%-" + fmt.Sprintf("%d", len10) + "s "
|
||||
|
||||
return fmt.Sprintf(s, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10)
|
||||
}
|
||||
|
||||
func (f *Forge) printRepoToTable(repo *gitpb.Repo) {
|
||||
var end string
|
||||
if repo.IsDirty() {
|
||||
end += "(dirty) "
|
||||
}
|
||||
|
||||
// shortened version numbers
|
||||
var mhort string = repo.GetMasterVersion()
|
||||
var dhort string = repo.GetDevelVersion()
|
||||
var uhort string = repo.GetUserVersion()
|
||||
if uhort == "uerr" {
|
||||
// blank these out
|
||||
uhort = ""
|
||||
}
|
||||
var lasttag string = repo.GetLastTag()
|
||||
var thort string = repo.GetTargetVersion()
|
||||
var chort string = repo.GetCurrentBranchVersion()
|
||||
var cname string = repo.GetCurrentBranchName()
|
||||
|
@ -174,13 +188,27 @@ func (f *Forge) printRepoToTable(repo *gitpb.Repo) {
|
|||
|
||||
// ctime := repo.Tags.GetAge(mhort)
|
||||
// age := shell.FormatDuration(time.Since(ctime))
|
||||
age := shell.FormatDuration(repo.NewestAge())
|
||||
|
||||
start := standardTable8(gopath, cname, age, thort, mhort, dhort, uhort, chort, rtype)
|
||||
age := shell.FormatDuration(repo.BranchAge(cname))
|
||||
|
||||
if f.Config.IsReadOnly(repo.GetGoPath()) {
|
||||
end += "(readonly) "
|
||||
// end += "(readonly) "
|
||||
} else {
|
||||
end += "(rw) "
|
||||
}
|
||||
|
||||
if repo.IsDirty() {
|
||||
age = ""
|
||||
end += "(dirty) "
|
||||
}
|
||||
|
||||
start := standardTable10(gopath, cname, age, mhort, dhort, uhort, chort, lasttag, thort, rtype)
|
||||
|
||||
if rtype == "protobuf" {
|
||||
if repo.GoInfo.GoBinary {
|
||||
end += "(binary) "
|
||||
}
|
||||
}
|
||||
|
||||
if repo.GetMasterBranchName() != "master" && repo.GetMasterBranchName() != "main" {
|
||||
end += "(m:" + repo.GetMasterBranchName() + ") "
|
||||
}
|
||||
|
@ -193,9 +221,21 @@ func (f *Forge) printRepoToTable(repo *gitpb.Repo) {
|
|||
end += "(u:" + repo.GetUserBranchName() + ") "
|
||||
}
|
||||
|
||||
debname := f.Config.DebName(repo.GetGoPath())
|
||||
if debname != filepath.Base(gopath) {
|
||||
end += "(deb:" + debname + ") "
|
||||
}
|
||||
|
||||
switch repo.GetState() {
|
||||
case "PERFECT":
|
||||
case "unchanged":
|
||||
case "dirty":
|
||||
case "unknown branches":
|
||||
if repo.CurrentTag == nil {
|
||||
end += "(" + repo.GetState() + ") "
|
||||
} else {
|
||||
end += "(unknown branch " + repo.CurrentTag.Refname + ") "
|
||||
}
|
||||
// end += "(invalid tag) "
|
||||
default:
|
||||
end += "(" + repo.GetState() + ") "
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
package forgepb
|
||||
|
||||
import (
|
||||
"go.wit.com/log"
|
||||
)
|
||||
|
||||
// print the protobuf in human form
|
||||
func IdentifyProtobuf(data []byte) error {
|
||||
var pb *Identify
|
||||
pb = new(Identify)
|
||||
if err := pb.Unmarshal(data); err != nil {
|
||||
log.Info("data can't be identified as a standard protobuf. len =", len(data))
|
||||
return err
|
||||
}
|
||||
log.Info("Identify protobuf file uuid =", pb.Uuid, "version =", pb.Version)
|
||||
return nil
|
||||
}
|
69
init.go
69
init.go
|
@ -1,3 +1,5 @@
|
|||
// Copyright 2025 WIT.COM Inc Licensed GPL 3.0
|
||||
|
||||
package forgepb
|
||||
|
||||
import (
|
||||
|
@ -8,7 +10,6 @@ import (
|
|||
|
||||
"go.wit.com/lib/gui/shell"
|
||||
"go.wit.com/lib/protobuf/gitpb"
|
||||
"go.wit.com/lib/protobuf/zoopb"
|
||||
"go.wit.com/log"
|
||||
)
|
||||
|
||||
|
@ -18,11 +19,12 @@ import (
|
|||
func Init() *Forge {
|
||||
f := InitPB()
|
||||
|
||||
f.Machine = new(zoopb.Machine)
|
||||
|
||||
if err := f.Machine.ConfigLoad(); err != nil {
|
||||
log.Log(WARN, "zoopb.ConfigLoad() failed", err)
|
||||
}
|
||||
/*
|
||||
f.Machine = new(zoopb.Machine)
|
||||
if err := f.Machine.ConfigLoad(); err != nil {
|
||||
log.Log(WARN, "zoopb.ConfigLoad() failed", err)
|
||||
}
|
||||
*/
|
||||
if f.Config.Username == "" {
|
||||
usr, _ := user.Current()
|
||||
f.Config.Username = usr.Username
|
||||
|
@ -38,20 +40,31 @@ func Init() *Forge {
|
|||
f.SetConfigSave(true)
|
||||
}
|
||||
|
||||
f.Machine.InitWit()
|
||||
// f.Machine.InitWit()
|
||||
|
||||
if f.hasFullScan {
|
||||
// duplicate time checking below. which one to keep?
|
||||
if f.FullScanAge() > time.Minute {
|
||||
log.Log(INFO, "forgepb.Scan() skipping scan. been run a minute ago", f.FullScanAge())
|
||||
return f
|
||||
}
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
start := f.Repos.Len()
|
||||
f.ScanGoSrc()
|
||||
f.FullScanRan()
|
||||
end := f.Repos.Len()
|
||||
if (end - start) == 0 {
|
||||
log.Log(INFO, "forgepb.Scan() Scan did not find new git repositories. Total =", end)
|
||||
if f.FullScanAge() > time.Minute {
|
||||
f.rillUpdate(20, 10)
|
||||
}
|
||||
} else {
|
||||
log.Log(INFO, "forgepb.Scan() Scan found", end-start, "new git repositories. Total =", end)
|
||||
f.rillUpdate(20, 10)
|
||||
}
|
||||
|
||||
f.rillUpdate(20, 10)
|
||||
|
||||
if f.configSave {
|
||||
// taking this out to debug Marshal() panic
|
||||
// os.Exit(-1)
|
||||
|
@ -83,6 +96,8 @@ func DetermineGoPath() *Forge {
|
|||
os.Setenv("FORGE_CONFIG", fullpath)
|
||||
}
|
||||
|
||||
f.configDir = os.Getenv("FORGE_CONFIG")
|
||||
|
||||
// check again for go.work // user could have a go.work file in ~/go/src
|
||||
if f.goWorkExists() {
|
||||
f.goWork = true
|
||||
|
@ -106,8 +121,42 @@ func (f *Forge) InitPB() {
|
|||
} else {
|
||||
log.Log(INFO, "forgepb.Init() FORGE_GOSRC ", os.Getenv("FORGE_GOSRC"), "(go.work = false)")
|
||||
}
|
||||
f.Repos = new(gitpb.Repos)
|
||||
|
||||
f.Repos = gitpb.NewRepos()
|
||||
f.Repos.ConfigLoad()
|
||||
if f.Repos.HasFullScan {
|
||||
f.hasFullScan = true
|
||||
}
|
||||
|
||||
if os.Getenv("FORGE_URL") != "" {
|
||||
forgeURL = os.Getenv("FORGE_URL")
|
||||
log.Info("got forge url", forgeURL)
|
||||
}
|
||||
}
|
||||
|
||||
func (f *Forge) InitMachine() {
|
||||
/*
|
||||
f.Machine = new(zoopb.Machine)
|
||||
if err := f.Machine.ConfigLoad(); err != nil {
|
||||
log.Log(WARN, "zoopb.ConfigLoad() failed", err)
|
||||
f.Machine.InitWit()
|
||||
}
|
||||
*/
|
||||
|
||||
if f.Config.Username == "" {
|
||||
usr, _ := user.Current()
|
||||
f.Config.Username = usr.Username
|
||||
}
|
||||
|
||||
/*
|
||||
if f.Machine.Hostname == "" {
|
||||
r, err := shell.RunVerbose([]string{"hostname", "-f"})
|
||||
if err == nil {
|
||||
tmp := strings.Join(r.Stdout, "\n")
|
||||
f.Machine.Hostname = strings.TrimSpace(tmp)
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// only init's the protobuf. intended to not scan or change anything
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
// Copyright 1994-2025 WIT.COM Inc Licensed GPL 3.0
|
||||
|
||||
package forgepb
|
||||
|
||||
// TODO: implement i18n with the protobuf's
|
||||
func (f *Forge) GetMode() string {
|
||||
switch f.Config.Mode {
|
||||
case ForgeMode_MASTER:
|
||||
return "Release Mode (master branch)"
|
||||
case ForgeMode_DEVEL:
|
||||
return "Patch Mode (devel branch)"
|
||||
case ForgeMode_USER:
|
||||
return "Hack Mode (user branch)"
|
||||
default:
|
||||
return f.Config.Mode.String()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
// Copyright 1994-2025 WIT.COM Inc Licensed GPL 3.0
|
||||
|
||||
package forgepb
|
||||
|
||||
import (
|
||||
"go.wit.com/log"
|
||||
)
|
||||
|
||||
var forgeURL string = "https://go.wit.com/"
|
||||
|
||||
func (f *Forge) GetPatchesets() (*Patchsets, error) {
|
||||
url := forgeURL + "GetPatchsets"
|
||||
log.Info("GetPatchsets() url", url)
|
||||
body, err := f.HttpPost(url, nil)
|
||||
if err != nil {
|
||||
log.Info("httpPost() failed:", err)
|
||||
return nil, err
|
||||
}
|
||||
log.Info("GetPatchets() len(body)", len(body))
|
||||
var psets *Patchsets
|
||||
psets = new(Patchsets)
|
||||
err = psets.Unmarshal(body)
|
||||
if err != nil {
|
||||
log.Info("Unmarshal failed", err)
|
||||
return nil, err
|
||||
}
|
||||
/*
|
||||
filename := filepath.Join("/tmp", pbfile)
|
||||
f, _ := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
|
||||
f.Write(body)
|
||||
f.Close()
|
||||
*/
|
||||
return psets, nil
|
||||
}
|
110
patchset.Make.go
110
patchset.Make.go
|
@ -6,13 +6,32 @@ import (
|
|||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"go.wit.com/lib/protobuf/gitpb"
|
||||
"go.wit.com/log"
|
||||
timestamppb "google.golang.org/protobuf/types/known/timestamppb"
|
||||
)
|
||||
|
||||
func (f *Forge) MakeDevelPatchSet() (*Patchset, error) {
|
||||
// creates a patchset
|
||||
// works from the user branches against the devel branches
|
||||
func (f *Forge) MakeDevelPatchSet(name string) (*Patchset, error) {
|
||||
pset := new(Patchset)
|
||||
pset.Name = name
|
||||
pset.Ctime = timestamppb.New(time.Now())
|
||||
pset.Uuid = uuid.New().String()
|
||||
if os.Getenv("GIT_AUTHOR_NAME") == "" {
|
||||
return nil, fmt.Errorf("GIT_AUTHOR_NAME not set")
|
||||
} else {
|
||||
pset.GitAuthorName = os.Getenv("GIT_AUTHOR_NAME")
|
||||
}
|
||||
if os.Getenv("GIT_AUTHOR_EMAIL") == "" {
|
||||
return nil, fmt.Errorf("GIT_AUTHOR_EMAIL not set")
|
||||
} else {
|
||||
pset.GitAuthorEmail = os.Getenv("GIT_AUTHOR_EMAIL")
|
||||
}
|
||||
|
||||
dir, err := os.MkdirTemp("", "forge")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -23,17 +42,21 @@ func (f *Forge) MakeDevelPatchSet() (*Patchset, error) {
|
|||
all := f.Repos.SortByFullPath()
|
||||
for all.Scan() {
|
||||
repo := all.Next()
|
||||
userb := repo.GetUserBranchName()
|
||||
develb := repo.GetDevelBranchName()
|
||||
|
||||
if develb == "" {
|
||||
if !repo.IsLocalBranch(repo.GetUserBranchName()) {
|
||||
// log.Info("repo doesn't have user branch", repo.GetGoPath())
|
||||
continue
|
||||
}
|
||||
if userb == "" {
|
||||
if !repo.IsLocalBranch(repo.GetDevelBranchName()) {
|
||||
// log.Info("repo doesn't have devel branch", repo.GetGoPath())
|
||||
continue
|
||||
}
|
||||
pset.StartBranchName = develb
|
||||
pset.EndBranchName = userb
|
||||
|
||||
// make a patchset from user to devel
|
||||
// TODO: verify branches are otherwise exact
|
||||
pset.StartBranchName = repo.GetDevelBranchName()
|
||||
pset.EndBranchName = repo.GetUserBranchName()
|
||||
|
||||
err := pset.makePatchSetNew(repo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -42,6 +65,17 @@ func (f *Forge) MakeDevelPatchSet() (*Patchset, error) {
|
|||
return pset, nil
|
||||
}
|
||||
|
||||
func (f *Forge) SubmitDevelPatchSet(name string) (*Patchset, error) {
|
||||
pset, err := f.MakeDevelPatchSet(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := f.submitPatchset(pset); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return pset, nil
|
||||
}
|
||||
|
||||
func (f *Forge) MakeMasterPatchSet() (*Patchset, error) {
|
||||
pset := new(Patchset)
|
||||
dir, err := os.MkdirTemp("", "forge")
|
||||
|
@ -83,7 +117,19 @@ func (pset *Patchset) makePatchSetNew(repo *gitpb.Repo) error {
|
|||
return err
|
||||
}
|
||||
|
||||
// maybe better? maybe worse?
|
||||
// git format-patch -o patches --stdout <commit-range> > my-patch.mbox
|
||||
// git format-patch --stdout -5 > my-patch.mbox # last 5 patches
|
||||
// git am < my-patch.mbox
|
||||
// git format-patch branch1..branch2
|
||||
// export GIT_COMMITTER_DATE="2024-01-01T12:00:00"
|
||||
// export GIT_AUTHOR_DATE="2024-01-01T12:00:00"
|
||||
// export GIT_COMMITTER_NAME="Your Name"
|
||||
// export GIT_COMMITTER_EMAIL="your.email@example.com"
|
||||
// export GIT_AUTHOR_NAME="Your Name"
|
||||
// export GIT_AUTHOR_EMAIL="your.email@example.com"
|
||||
// git am < patch.mbox
|
||||
|
||||
cmd := []string{"git", "format-patch", "-o", repoDir, startBranch + ".." + endBranch}
|
||||
r := repo.Run(cmd)
|
||||
if r.Error != nil {
|
||||
|
@ -103,14 +149,16 @@ func (pset *Patchset) makePatchSetNew(repo *gitpb.Repo) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
return pset.addPatchFiles(repo)
|
||||
err = pset.addPatchFiles(repo)
|
||||
pset.Ctime = timestamppb.New(time.Now())
|
||||
return err
|
||||
}
|
||||
|
||||
// process each file in pDir/
|
||||
func (p *Patchset) addPatchFiles(repo *gitpb.Repo) error {
|
||||
psetDir := repo.GetGoPath()
|
||||
tmpDir := p.TmpDir
|
||||
log.Info("ADD PATCH FILES ADDED DIR", tmpDir)
|
||||
// log.Info("ADD PATCH FILES ADDED DIR", tmpDir)
|
||||
fullDir := filepath.Join(tmpDir, psetDir)
|
||||
var baderr error
|
||||
filepath.Walk(fullDir, func(path string, info os.FileInfo, err error) error {
|
||||
|
@ -124,10 +172,10 @@ func (p *Patchset) addPatchFiles(repo *gitpb.Repo) error {
|
|||
if info.IsDir() {
|
||||
return nil
|
||||
}
|
||||
log.Info("IS THIS A FULL PATH ?", path)
|
||||
log.Info("trim this from path ?", fullDir)
|
||||
log.Info("trim this from path ?", psetDir)
|
||||
log.Info("trim this from path ?", tmpDir)
|
||||
// log.Info("IS THIS A FULL PATH ?", path)
|
||||
// log.Info("trim this from path ?", fullDir)
|
||||
// log.Info("trim this from path ?", psetDir)
|
||||
// log.Info("trim this from path ?", tmpDir)
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
log.Info("addPatchFile() failed", path)
|
||||
|
@ -139,8 +187,14 @@ func (p *Patchset) addPatchFiles(repo *gitpb.Repo) error {
|
|||
patch.Data = data
|
||||
patch.parseData()
|
||||
patch.StartHash = repo.DevelHash()
|
||||
patch.NewHash = "na"
|
||||
patch.RepoNamespace = repo.GetGoPath()
|
||||
if p.Patches == nil {
|
||||
p.Patches = new(Patches)
|
||||
}
|
||||
p.Patches.Append(patch)
|
||||
log.Info("ADDED PATCH FILE", path)
|
||||
p.Patches.Uuid = uuid.New().String()
|
||||
// log.Info("ADDED PATCH FILE", path)
|
||||
return nil
|
||||
})
|
||||
return baderr
|
||||
|
@ -159,6 +213,8 @@ func (p *Patch) parseData() string {
|
|||
switch fields[0] {
|
||||
case "From":
|
||||
p.CommitHash = fields[1]
|
||||
case "Subject:":
|
||||
p.Comment = line
|
||||
case "diff":
|
||||
p.Files = append(p.Files, line)
|
||||
}
|
||||
|
@ -188,3 +244,29 @@ func onlyWalkDirs(pDir string) error {
|
|||
})
|
||||
return baderr
|
||||
}
|
||||
|
||||
func (f *Forge) submitPatchset(pset *Patchset) error {
|
||||
var url string
|
||||
url = forgeURL + "patchset"
|
||||
msg, err := pset.Marshal()
|
||||
if err != nil {
|
||||
log.Info("proto.Marshal() failed:", err)
|
||||
return err
|
||||
}
|
||||
log.Info("proto.Marshal() msg len", len(msg))
|
||||
body, err := f.HttpPost(url, msg)
|
||||
if err != nil {
|
||||
log.Info("httpPost() failed:", err)
|
||||
return err
|
||||
}
|
||||
|
||||
test := strings.TrimSpace(string(body))
|
||||
lines := strings.Split(test, "\n")
|
||||
count := 0
|
||||
for _, line := range lines {
|
||||
log.Info("got back:", line)
|
||||
count += 1
|
||||
}
|
||||
log.Info("Total patches:", count)
|
||||
return nil
|
||||
}
|
||||
|
|
101
patchset.proto
101
patchset.proto
|
@ -1,43 +1,86 @@
|
|||
// Copyright 2025 WIT.COM Inc Licensed GPL 3.0
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package forgepb;
|
||||
|
||||
import "google/protobuf/timestamp.proto"; // Import the well-known type for Timestamp
|
||||
|
||||
// Forge doesn't need this kind of specificity
|
||||
// but this is what the patch files contain and how git sees them
|
||||
// message Blob {
|
||||
// string hunkLine = 1;
|
||||
// bytes data = 2;
|
||||
// }
|
||||
//
|
||||
// message File {
|
||||
// string filename = 1;
|
||||
// string hashLine = 2;
|
||||
// repeated Blob Blobs = 3;
|
||||
// }
|
||||
//
|
||||
// message Patch {
|
||||
// repeated File Files = 1;
|
||||
// string repoNamespace = 2;
|
||||
// string gH = 3;
|
||||
// string gaI = 4;
|
||||
// string gcI = 5;
|
||||
// }
|
||||
|
||||
// git log -1 --format="%H %aI %cI %an %ae %cn %ce"
|
||||
message Patch {
|
||||
string filename = 1; // `autogenpb:unique` `autogenpb:sort`
|
||||
bytes data = 2; //
|
||||
string repoPath = 3; // path to the git repo
|
||||
string branchName = 4; //
|
||||
string branchHash = 5; //
|
||||
google.protobuf.Timestamp ctime = 7; // the git commit timestamp of this patch
|
||||
string commitHash = 8; // the git commit hash of this patch
|
||||
string startHash = 9; // the start commit hash
|
||||
repeated string Files = 10; // the filenames this patch changes
|
||||
string repoNamespace = 1; // the base repo git URL
|
||||
bytes data = 2; // the raw data of the whole patch
|
||||
string gH = 3; // after some deliberation, I think I'll just try variable names
|
||||
string gT = 4;
|
||||
string gP = 5;
|
||||
string gs = 6;
|
||||
string gaI = 7; // that exactly match what git uses.
|
||||
string gan = 8;
|
||||
string gae = 9;
|
||||
string gcI = 10;
|
||||
string gcn = 11;
|
||||
string gce = 12;
|
||||
string gN = 13;
|
||||
string gGG = 14;
|
||||
string gGS = 15;
|
||||
string gGK = 16;
|
||||
string newHash = 17; // new hash
|
||||
string state = 18; // the 'state' of the patch
|
||||
string filename = 19; // `autogenpb:unique` `autogenpb:sort`
|
||||
string startHash = 20; // the start commit hash
|
||||
string commitHash = 21; // the git commit hash of this patch
|
||||
string comment = 22; // the git commit message (in patch form)
|
||||
repeated string Files = 23; // the filenames this patch changes
|
||||
google.protobuf.Timestamp ctime = 24; // create time of the patch
|
||||
bool applied = 25; // have you applied this patch?
|
||||
bool upstream = 26; // has this patch been applied upstream?
|
||||
}
|
||||
|
||||
message Patches { // `autogenpb:marshal`
|
||||
string uuid = 1; // `autogenpb:uuid:be926ad9-1111-484c-adf2-d96eeabf3079` // todo: add autogenpb support for this
|
||||
string version = 2; // `autogenpb:version:v0.0.45` // todo: add autogenpb support for this
|
||||
repeated Patch Patches = 3;
|
||||
message Patches { // this is a "PATCH: [1/x]" series `autogenpb:gui:Patch`
|
||||
string uuid = 1; // `autogenpb:uuid:be926ad9-1111-484c-adf2-d96eeabf3079`
|
||||
string version = 2; // `autogenpb:version:v0.0.45`
|
||||
repeated Patch Patches = 3;
|
||||
}
|
||||
|
||||
message Patchset { // `autogenpb:marshal`
|
||||
Patches patches = 1; // `autogenpb:unique` `autogenpb:sort`
|
||||
string name = 2; // `autogenpb:sort`
|
||||
string comment = 3; //
|
||||
string gitAuthorName = 4; // `autogenpb:sort`
|
||||
string gitAuthorEmail = 5; //
|
||||
google.protobuf.Timestamp ctime = 6; // create time of this patchset
|
||||
string tmpDir = 7; // temp dir
|
||||
string startBranchName = 8; //
|
||||
string endBranchName = 9; //
|
||||
string startBranchHash = 10; //
|
||||
string endBranchHash = 11; //
|
||||
message Patchset { // `autogenpb:marshal`
|
||||
Patches patches = 1; //
|
||||
string name = 2; // `autogenpb:sort`
|
||||
string comment = 3; //
|
||||
string gitAuthorName = 4; // `autogenpb:sort`
|
||||
string gitAuthorEmail = 5; //
|
||||
google.protobuf.Timestamp ctime = 6; // create time of the patchset
|
||||
string tmpDir = 7; // temp dir
|
||||
string startBranchName = 8; //
|
||||
string endBranchName = 9; //
|
||||
string startBranchHash = 10; //
|
||||
string endBranchHash = 11; //
|
||||
string state = 12; // the state of the patch
|
||||
string uuid = 13; // `autogenpb:sort` `autogenpb:unique`
|
||||
}
|
||||
|
||||
message Patchsets { // `autogenpb:marshal`
|
||||
string uuid = 1; // `autogenpb:uuid:be926ad9-f07f-484c-adf2-d96eeabf3079` // todo: add autogenpb support for this
|
||||
string version = 2; // `autogenpb:version:v0.0.45` // todo: add autogenpb support for this
|
||||
repeated Patchset Patchsets = 3;
|
||||
message Patchsets { // `autogenpb:marshal` `autogenpb:gui`
|
||||
string uuid = 1; // `autogenpb:uuid:be926ad9-f07f-484c-adf2-d96eeabf3079`
|
||||
string version = 2; // `autogenpb:version:v0.0.45`
|
||||
repeated Patchset Patchsets = 3;
|
||||
}
|
||||
|
|
22
repoNew.go
22
repoNew.go
|
@ -1,3 +1,5 @@
|
|||
// Copyright 2025 WIT.COM Inc Licensed GPL 3.0
|
||||
|
||||
package forgepb
|
||||
|
||||
import (
|
||||
|
@ -13,11 +15,17 @@ import (
|
|||
|
||||
func (f *Forge) NewGoRepo(gopath string, url string) (*gitpb.Repo, error) {
|
||||
fullpath := filepath.Join(f.GetGoSrc(), gopath)
|
||||
test := f.Repos.FindByFullPath(fullpath)
|
||||
if test != nil {
|
||||
return test, nil
|
||||
}
|
||||
repo, err := f.Repos.NewGoRepo(fullpath, gopath)
|
||||
if err != nil {
|
||||
log.Info("WARNING. NEW FAILED", fullpath)
|
||||
return nil, err
|
||||
}
|
||||
// slices.Reverse(f.Repos.Repos)
|
||||
|
||||
repo.URL = url
|
||||
f.VerifyBranchNames(repo)
|
||||
if f.Config.IsReadOnly(repo.GetGoPath()) {
|
||||
|
@ -76,7 +84,7 @@ func (f *Forge) findMasterBranch(repo *gitpb.Repo) {
|
|||
if strings.HasPrefix(s, "ref: ") {
|
||||
fields := strings.Fields(s)
|
||||
_, bname := filepath.Split(fields[1])
|
||||
log.Info("Using master branch name from .git/ HEAD:", bname)
|
||||
// log.Info("Using master branch name from .git/ HEAD:", bname)
|
||||
repo.SetMasterBranchName(bname)
|
||||
return
|
||||
}
|
||||
|
@ -95,11 +103,13 @@ func (f *Forge) findMasterBranch(repo *gitpb.Repo) {
|
|||
|
||||
// TODO: figure out the name from git
|
||||
repo.SetMasterBranchName("master")
|
||||
/* no longer checkout on Init()
|
||||
if repo.CheckoutMaster() {
|
||||
} else {
|
||||
cmd := []string{"git", "branch", "master"}
|
||||
repo.Run(cmd)
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// figure out what the name of the git devel branch is
|
||||
|
@ -108,11 +118,13 @@ func (f *Forge) findDevelBranch(repo *gitpb.Repo) {
|
|||
// check the forge config first
|
||||
if bname := f.Config.FindDevelBranch(repo.GetGoPath()); bname != "" {
|
||||
repo.SetDevelBranchName(bname)
|
||||
/* no longer checkout on Init()
|
||||
if repo.CheckoutDevel() {
|
||||
} else {
|
||||
cmd := []string{"git", "branch", bname}
|
||||
repo.Run(cmd)
|
||||
}
|
||||
*/
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -121,13 +133,14 @@ func (f *Forge) findDevelBranch(repo *gitpb.Repo) {
|
|||
return
|
||||
}
|
||||
|
||||
// TODO: figure out the name from git
|
||||
repo.SetDevelBranchName("devel")
|
||||
/* no longer checkout on Init()
|
||||
if repo.CheckoutDevel() {
|
||||
} else {
|
||||
cmd := []string{"git", "branch", "devel"}
|
||||
repo.Run(cmd)
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// this is still in flux
|
||||
|
@ -149,11 +162,6 @@ func (f *Forge) VerifyBranchNames(repo *gitpb.Repo) {
|
|||
} else {
|
||||
// forcing for now. todo: warn users
|
||||
repo.SetUserBranchName(uname)
|
||||
if repo.CheckoutUser() {
|
||||
} else {
|
||||
cmd := []string{"git", "branch", uname}
|
||||
repo.Run(cmd)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
89
rill.go
89
rill.go
|
@ -1,6 +1,8 @@
|
|||
package forgepb
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/destel/rill"
|
||||
"go.wit.com/lib/protobuf/gitpb"
|
||||
"go.wit.com/log"
|
||||
|
@ -64,3 +66,90 @@ func (f *Forge) updateRepo(repo *gitpb.Repo) error {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var RillX int = 10
|
||||
var RillY int = 10
|
||||
|
||||
// x is the size of the queued up pool (shouldn't matter here for this I think)
|
||||
// y is how many simultanous functions will run
|
||||
// todo: tune and compute x,y by # of CPUs and disk io
|
||||
// todo: store x,y in forge config ? (or compute them. notsure)
|
||||
func (f *Forge) RillReload() int {
|
||||
var all []*gitpb.Repo
|
||||
tmp := f.Repos.All()
|
||||
for tmp.Scan() {
|
||||
repo := tmp.Next()
|
||||
if !repo.IsValidDir() {
|
||||
log.Printf("%s %-50s", "got an invalid repo in forgepb.RillFuncError()", repo.GetGoPath())
|
||||
continue
|
||||
}
|
||||
all = append(all, repo)
|
||||
}
|
||||
// Convert a slice of user IDs into a channel
|
||||
ids := rill.FromSlice(all, nil)
|
||||
|
||||
var counter int
|
||||
// Read users from the API.
|
||||
// Concurrency = 20
|
||||
dirs := rill.Map(ids, RillX, func(repo *gitpb.Repo) (*gitpb.Repo, error) {
|
||||
return repo, nil
|
||||
})
|
||||
|
||||
rill.ForEach(dirs, RillY, func(repo *gitpb.Repo) error {
|
||||
if !repo.DidRepoChange() {
|
||||
return nil
|
||||
}
|
||||
f.configSave = true
|
||||
repo.Reload()
|
||||
counter += 1
|
||||
return nil
|
||||
})
|
||||
|
||||
return counter
|
||||
}
|
||||
|
||||
// x is the size of the queued up pool (shouldn't matter here for this I think)
|
||||
// y is how many simultanous functions will run
|
||||
// todo: tune and compute x,y by # of CPUs and disk io
|
||||
// todo: store x,y in forge config ? (or compute them. notsure)
|
||||
func (f *Forge) RillFuncError(rillf func(*gitpb.Repo) error) int {
|
||||
var all []*gitpb.Repo
|
||||
tmp := f.Repos.All()
|
||||
for tmp.Scan() {
|
||||
repo := tmp.Next()
|
||||
if !repo.IsValidDir() {
|
||||
log.Printf("%s %-50s", "got an invalid repo in forgepb.RillFuncError()", repo.GetGoPath())
|
||||
continue
|
||||
}
|
||||
all = append(all, repo)
|
||||
}
|
||||
// Convert a slice of user IDs into a channel
|
||||
ids := rill.FromSlice(all, nil)
|
||||
|
||||
var counter int
|
||||
var watch int = 10
|
||||
var meMu sync.Mutex
|
||||
|
||||
// Read users from the API.
|
||||
// Concurrency = 20
|
||||
dirs := rill.Map(ids, RillX, func(id *gitpb.Repo) (*gitpb.Repo, error) {
|
||||
return id, nil
|
||||
})
|
||||
|
||||
err := rill.ForEach(dirs, RillY, func(repo *gitpb.Repo) error {
|
||||
meMu.Lock()
|
||||
counter += 1
|
||||
if counter > watch {
|
||||
// log.Info("Processed", watch, "repos") // this doesn't work
|
||||
watch += 50
|
||||
}
|
||||
meMu.Unlock()
|
||||
return rillf(repo)
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
log.Info("rill.ForEach() error:", err)
|
||||
}
|
||||
|
||||
return counter
|
||||
}
|
||||
|
|
39
structs.go
39
structs.go
|
@ -2,29 +2,48 @@ package forgepb
|
|||
|
||||
import (
|
||||
sync "sync"
|
||||
"time"
|
||||
|
||||
"go.wit.com/lib/protobuf/gitpb"
|
||||
"go.wit.com/lib/protobuf/zoopb"
|
||||
)
|
||||
|
||||
// maybe an interface someday?
|
||||
type Forge struct {
|
||||
// one-time initialized data
|
||||
initOnce sync.Once
|
||||
initErr error // init error, if any
|
||||
|
||||
goSrc string // the path to go/src
|
||||
goWork bool // means the user is currently using a go.work file
|
||||
Config *ForgeConfigs // config repos for readonly, private, etc
|
||||
Repos *gitpb.Repos
|
||||
Machine *zoopb.Machine
|
||||
configSave bool
|
||||
initOnce sync.Once
|
||||
initErr error // init error, if any
|
||||
goSrc string // the path to go/src
|
||||
configDir string // normally ~/.config/forge
|
||||
goWork bool // means the user is currently using a go.work file
|
||||
Config *ForgeConfigs // config repos for readonly, private, etc
|
||||
Repos *gitpb.Repos // the repo protobufs
|
||||
// Machine *zoopb.Machine // things for virtigo to track vm's
|
||||
configSave bool // if you need to save the config because things changed
|
||||
hasFullScan bool // track last scan so it can be throttled
|
||||
fullscan time.Time // time of the last scan so it can be throttled
|
||||
}
|
||||
|
||||
func (f *Forge) GetGoSrc() string {
|
||||
return f.goSrc
|
||||
}
|
||||
|
||||
func (f *Forge) GetConfigDir() string {
|
||||
return f.configDir
|
||||
}
|
||||
|
||||
func (f *Forge) IsGoWork() bool {
|
||||
return f.goWork
|
||||
}
|
||||
|
||||
func (f *Forge) HasFullScan() bool {
|
||||
return f.Repos.HasFullScan
|
||||
}
|
||||
|
||||
func (f *Forge) FullScanRan() {
|
||||
f.fullscan = time.Now()
|
||||
}
|
||||
|
||||
func (f *Forge) FullScanAge() time.Duration {
|
||||
fs := f.Repos.FullScan.AsTime()
|
||||
return time.Since(fs)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue