Compare commits
70 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 | |
|
8d275ff054 | |
|
0f232fe342 | |
|
9e81be86da | |
|
2398e30048 |
|
@ -1,5 +1,5 @@
|
||||||
go.*
|
go.*
|
||||||
|
*.swp
|
||||||
|
*.patch
|
||||||
|
*.mbox
|
||||||
*.pb.go
|
*.pb.go
|
||||||
|
|
||||||
forgeConfig/forgeConfig
|
|
||||||
|
|
3
Makefile
3
Makefile
|
@ -20,8 +20,9 @@ goimports:
|
||||||
goimports -w *.go
|
goimports -w *.go
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.pb.go
|
rm -f *.pb.go *.patch
|
||||||
-rm -f go.*
|
-rm -f go.*
|
||||||
|
go-mod-clean --purge
|
||||||
|
|
||||||
forgeConfig.pb.go: forgeConfig.proto
|
forgeConfig.pb.go: forgeConfig.proto
|
||||||
autogenpb --proto forgeConfig.proto
|
autogenpb --proto forgeConfig.proto
|
||||||
|
|
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")
|
data, _ := repo.ReadFile(".forge")
|
||||||
log.Info(".forge =", string(data))
|
log.Info(".forge =", string(data))
|
||||||
log.Info("todo: do the custom build instructions")
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,7 +118,8 @@ func (f *Forge) doBuild(repo *gitpb.Repo, userFlags []string, goWhat string) err
|
||||||
|
|
||||||
// set standard ldflag options
|
// set standard ldflag options
|
||||||
now := time.Now()
|
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)
|
// log.Info("datestamp =", datestamp)
|
||||||
// add some standard golang flags
|
// add some standard golang flags
|
||||||
ldflags := "-X main.VERSION=" + version + " "
|
ldflags := "-X main.VERSION=" + version + " "
|
||||||
|
@ -205,3 +209,21 @@ func (f *Forge) FindWorkingDirRepo() *gitpb.Repo {
|
||||||
basedir = strings.Trim(basedir, "/")
|
basedir = strings.Trim(basedir, "/")
|
||||||
return f.FindByGoPath(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
|
package forgepb
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
11
config.go
11
config.go
|
@ -1,3 +1,5 @@
|
||||||
|
// Copyright 2025 WIT.COM Inc Licensed GPL 3.0
|
||||||
|
|
||||||
package forgepb
|
package forgepb
|
||||||
|
|
||||||
// functions to import and export the protobuf
|
// functions to import and export the protobuf
|
||||||
|
@ -8,8 +10,10 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"time"
|
||||||
|
|
||||||
"go.wit.com/log"
|
"go.wit.com/log"
|
||||||
|
timestamppb "google.golang.org/protobuf/types/known/timestamppb"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (f *Forge) ConfigSave() error {
|
func (f *Forge) ConfigSave() error {
|
||||||
|
@ -28,6 +32,11 @@ func (f *Forge) ConfigSave() error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if f.Repos != nil {
|
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 {
|
if e := f.Repos.ConfigSave(); e != nil {
|
||||||
log.Info("forge.Repos.ConfigSave() error", e)
|
log.Info("forge.Repos.ConfigSave() error", e)
|
||||||
err = e
|
err = e
|
||||||
|
@ -43,7 +52,7 @@ func (f *ForgeConfigs) ConfigSave() error {
|
||||||
log.Info("proto.Marshal() failed len", len(data), err)
|
log.Info("proto.Marshal() failed len", len(data), err)
|
||||||
return 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()
|
s := f.FormatTEXT()
|
||||||
configWrite("forge.text", []byte(s))
|
configWrite("forge.text", []byte(s))
|
||||||
|
|
|
@ -7,7 +7,6 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"time"
|
"time"
|
||||||
|
@ -15,12 +14,8 @@ import (
|
||||||
|
|
||||||
func backupConfig() error {
|
func backupConfig() error {
|
||||||
// make a new dir to backup the files
|
// 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"))
|
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)
|
return backupFiles(srcDir, destDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +39,7 @@ func backupFiles(srcDir string, destDir string) error {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Println("backing up file", entry.Name())
|
// log.Println("backing up file", entry.Name())
|
||||||
srcPath := filepath.Join(srcDir, entry.Name())
|
srcPath := filepath.Join(srcDir, entry.Name())
|
||||||
destPath := filepath.Join(destDir, entry.Name())
|
destPath := filepath.Join(destDir, entry.Name())
|
||||||
|
|
||||||
|
@ -64,6 +59,9 @@ func copyFile(src, dest string) error {
|
||||||
}
|
}
|
||||||
defer srcFile.Close()
|
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)
|
destFile, err := os.Create(dest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package forgepb
|
package forgepb
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"go.wit.com/lib/protobuf/gitpb"
|
"go.wit.com/lib/protobuf/gitpb"
|
||||||
|
@ -16,24 +18,20 @@ import (
|
||||||
// it re-scans the go.sum file. DOES NOT MODIFY ANYTHING
|
// it re-scans the go.sum file. DOES NOT MODIFY ANYTHING
|
||||||
// this is the last thing to run to double check everything
|
// this is the last thing to run to double check everything
|
||||||
// before 'git tag' or git push --tags
|
// before 'git tag' or git push --tags
|
||||||
func (f *Forge) FinalGoDepsCheckOk(check *gitpb.Repo) bool {
|
func (f *Forge) FinalGoDepsCheckOk(check *gitpb.Repo, verbose bool) error {
|
||||||
var good bool = true
|
|
||||||
if check == nil {
|
if check == nil {
|
||||||
log.Info("boo, check == nil")
|
return errors.New("FinalGoDepsCheckOk() boo, check == nil")
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse the go.mod and go.sum files
|
// parse the go.mod and go.sum files
|
||||||
if !check.ParseGoSum() {
|
if !check.ParseGoSum() {
|
||||||
log.Info("forge.FinalGoDepsCheckOk() failed")
|
return fmt.Errorf("forge.ParseGoSum() failed. go.mod & go.sum are broken")
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if check.GetGoPrimitive() {
|
if check.GetGoPrimitive() {
|
||||||
return true
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("current repo %s go dependancy count: %d", check.GetGoPath(), check.GoDepsLen())
|
|
||||||
deps := check.GoDeps.SortByGoPath()
|
deps := check.GoDeps.SortByGoPath()
|
||||||
for deps.Scan() {
|
for deps.Scan() {
|
||||||
depRepo := deps.Next()
|
depRepo := deps.Next()
|
||||||
|
@ -43,63 +41,114 @@ func (f *Forge) FinalGoDepsCheckOk(check *gitpb.Repo) bool {
|
||||||
// skip this gopath because it's probably broken forever
|
// skip this gopath because it's probably broken forever
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
log.Info("not found:", depRepo.GetGoPath())
|
return fmt.Errorf("dep not found: %s", depRepo.GetGoPath())
|
||||||
good = false
|
}
|
||||||
|
if depRepo.GetVersion() == found.GetMasterVersion() {
|
||||||
|
// log.Printf("%-48s error ?? %-10s vs %-10s\n", depRepo.GetGoPath(), depRepo.GetVersion(), found.GetMasterVersion())
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// log.Info("found dep", depRepo.GetGoPath())
|
// log.Info("found dep", depRepo.GetGoPath())
|
||||||
if depRepo.GetVersion() != found.GetTargetVersion() {
|
if depRepo.GetVersion() != found.GetTargetVersion() {
|
||||||
check := f.FindByGoPath(depRepo.GetGoPath())
|
check := f.FindByGoPath(depRepo.GetGoPath())
|
||||||
if f.Config.IsReadOnly(check.GetGoPath()) {
|
if f.Config.IsReadOnly(check.GetGoPath()) {
|
||||||
log.Printf("%-48s ok error .%s. vs .%s. (ignoring read-only repo)", depRepo.GetGoPath(), depRepo.GetVersion(), found.GetTargetVersion())
|
if verbose {
|
||||||
|
log.Printf("%-48s ok error .%s. vs .%s. (ignoring read-only repo)\n", depRepo.GetGoPath(), depRepo.GetVersion(), found.GetTargetVersion())
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if f.CheckOverride(depRepo.GetGoPath()) {
|
if f.CheckOverride(depRepo.GetGoPath()) {
|
||||||
log.Printf("%-48s ok error .%s. vs .%s. (forge.CheckOverride())", depRepo.GetGoPath(), depRepo.GetVersion(), found.GetTargetVersion())
|
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
|
// skip this gopath because it's probably broken forever
|
||||||
continue
|
continue
|
||||||
} else {
|
} else {
|
||||||
log.Printf("%-48s error %10s vs %10s", depRepo.GetGoPath(), depRepo.GetVersion(), found.GetTargetVersion())
|
// log.Printf("%-48s error ?? %-10s vs %-10s\n", depRepo.GetGoPath(), depRepo.GetVersion(), found.GetMasterVersion())
|
||||||
good = false
|
// 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 good
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Forge) CheckOverride(gopath string) bool {
|
func (f *Forge) CheckOverride(gopath string) bool {
|
||||||
if gopath == "cloud.google.com/go" {
|
if gopath == "cloud.google.com/go" {
|
||||||
log.Info("CheckOverride() is ignoring", gopath)
|
// log.Info("CheckOverride() is ignoring", gopath)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if gopath == "bou.ke/monkey" {
|
if gopath == "bou.ke/monkey" {
|
||||||
log.Info("CheckOverride() is ignoring", gopath)
|
// log.Info("CheckOverride() is ignoring", gopath)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if gopath == "github.com/posener/complete/v2" {
|
if gopath == "github.com/posener/complete/v2" {
|
||||||
log.Info("CheckOverride() is ignoring", gopath)
|
// log.Info("CheckOverride() is ignoring", gopath)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if strings.HasPrefix(gopath, "github.com/go-gl") {
|
if strings.HasPrefix(gopath, "github.com/go-gl") {
|
||||||
log.Info("CheckOverride() is ignoring", gopath)
|
// log.Info("CheckOverride() is ignoring", gopath)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if strings.HasPrefix(gopath, "google.golang.org") {
|
if strings.HasPrefix(gopath, "google.golang.org") {
|
||||||
log.Info("CheckOverride() is ignoring", gopath)
|
// log.Info("CheckOverride() is ignoring", gopath)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if strings.HasPrefix(gopath, "go.opencensus.io") {
|
if strings.HasPrefix(gopath, "go.opencensus.io") {
|
||||||
log.Info("CheckOverride() is ignoring", gopath)
|
// log.Info("CheckOverride() is ignoring", gopath)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if strings.HasPrefix(gopath, "github.com/nicksnyder/go-i18n") {
|
if strings.HasPrefix(gopath, "github.com/nicksnyder/go-i18n") {
|
||||||
log.Info("CheckOverride() is ignoring", gopath)
|
// log.Info("CheckOverride() is ignoring", gopath)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
// fuckit for now. just blacklist github.com
|
// fuckit for now. just blacklist github.com
|
||||||
if strings.HasPrefix(gopath, "github.com/") {
|
if strings.HasPrefix(gopath, "github.com/") {
|
||||||
log.Info("CheckOverride() is ignoring", gopath)
|
// log.Info("CheckOverride() is ignoring", gopath)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
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";
|
syntax = "proto3";
|
||||||
|
|
||||||
package forgepb;
|
package forgepb;
|
||||||
|
@ -12,31 +14,49 @@ import "google/protobuf/timestamp.proto"; // Import the well-known type for Time
|
||||||
// package names sometimes must be different than the binary name
|
// package names sometimes must be different than the binary name
|
||||||
// for example 'zookeeper' is packaged as 'zookeeper-go'
|
// for example 'zookeeper' is packaged as 'zookeeper-go'
|
||||||
// due to the prior apache foundation project. This happens and is ok!
|
// due to the prior apache foundation project. This happens and is ok!
|
||||||
message ForgeConfig { // `autogenpb:nomutex`
|
message ForgeConfig { // `autogenpb:nomutex`
|
||||||
string goPath = 1; // `autogenpb:unique` `autogenpb:sort` // Examples: 'go.wit.com/apps/go-clone' or "~/mythings" or "/home/src/foo"
|
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 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 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 private = 4; // if the repo can be published
|
||||||
bool directory = 5; // everything in this directory should use these writable & private values
|
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 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 interesting = 7; // this is something interesting you found and want to remember it
|
||||||
|
|
||||||
string masterBranchName = 8; // git 'main' or 'master' branch name
|
string masterBranchName = 8; // git 'main' or 'master' branch name
|
||||||
string develBranchName = 9; // whatever the git 'devel' branch name is
|
string develBranchName = 9; // whatever the git 'devel' branch name is
|
||||||
string userBranchName = 10; // whatever your username branch is
|
string userBranchName = 10; // whatever your username branch is
|
||||||
|
|
||||||
string debName = 11; // the actual name used with 'apt install' (or distro apt equivalent.
|
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'
|
// 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
|
// so we can make easier instructions for new linux users. KISS
|
||||||
|
|
||||||
google.protobuf.Timestamp verstamp = 12; // the git commit timestamp of the version
|
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
|
string goSrc = 13; // is ~/go/src unless a go.work file is found
|
||||||
}
|
}
|
||||||
|
|
||||||
message ForgeConfigs { // `autogenpb:marshal` `autogenpb:nomutex`
|
// todo: fix autogenpb to look for enum
|
||||||
string uuid = 1; // could be useful for /usr/share/file/magic someday?
|
enum ForgeMode {
|
||||||
string version = 2; // could be used for protobuf schema change violations?
|
MASTER = 0; // "release mode"
|
||||||
repeated ForgeConfig ForgeConfigs = 3;
|
DEVEL = 1; // "patch mode"
|
||||||
string username = 4; // what to use for the user branch (default ENV{USER})
|
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"
|
"go.wit.com/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func (f *Forge) GetHome() string {
|
||||||
|
return f.goSrc
|
||||||
|
}
|
||||||
|
|
||||||
// look for a go.work file
|
// look for a go.work file
|
||||||
// otherwise use ~/go/src
|
// otherwise use ~/go/src
|
||||||
func (f *Forge) findGoSrc() (string, error) {
|
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
|
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/
|
// doesn't enter the directory any further when it finds a .git/
|
||||||
// not stupid like my old version
|
// not stupid like my old version
|
||||||
func gitDirectoriesNew(srcDir string) ([]string, error) {
|
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) {
|
func (f *Forge) checkpath(gopath string, url string) (*gitpb.Repo, error) {
|
||||||
fullpath := filepath.Join(f.GetGoSrc(), gopath)
|
fullpath := filepath.Join(f.GetGoSrc(), gopath)
|
||||||
log.Info("checkpath()", gopath, fullpath)
|
log.Info("forge creating protobuf for", fullpath)
|
||||||
repo, err := f.NewGoRepo(gopath, "")
|
repo, err := f.NewGoRepo(gopath, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Info("checkpath()", gopath, err)
|
log.Info("\tprotobuf error", gopath, err)
|
||||||
}
|
}
|
||||||
return repo, 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
|
package forgepb
|
||||||
|
|
||||||
import (
|
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
|
package forgepb
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// Copyright 2025 WIT.COM Inc Licensed GPL 3.0
|
||||||
|
|
||||||
package forgepb
|
package forgepb
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -86,7 +88,7 @@ func (f *Forge) testGoRepo(check *gitpb.Repo) {
|
||||||
data, _ := os.ReadFile(filepath.Join(check.FullPath, "go.mod"))
|
data, _ := os.ReadFile(filepath.Join(check.FullPath, "go.mod"))
|
||||||
log.Info(string(data))
|
log.Info(string(data))
|
||||||
|
|
||||||
if f.FinalGoDepsCheckOk(check) {
|
if err := f.FinalGoDepsCheckOk(check, true); err == nil {
|
||||||
log.Info("forge.FinalGoDepsCheck(check) worked!")
|
log.Info("forge.FinalGoDepsCheck(check) worked!")
|
||||||
} else {
|
} else {
|
||||||
log.Info("forge.FinalGoDepsCheck(check) failed. boo.")
|
log.Info("forge.FinalGoDepsCheck(check) failed. boo.")
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
|
// Copyright 2025 WIT.COM Inc Licensed GPL 3.0
|
||||||
|
|
||||||
package forgepb
|
package forgepb
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
"go.wit.com/lib/gui/shell"
|
"go.wit.com/lib/gui/shell"
|
||||||
"go.wit.com/lib/protobuf/gitpb"
|
"go.wit.com/lib/protobuf/gitpb"
|
||||||
|
@ -37,11 +40,36 @@ func (f *Forge) PrintHumanTable(allr *gitpb.Repos) {
|
||||||
|
|
||||||
var count int
|
var count int
|
||||||
// log.Info(standardStart5("gopath", "cur name", "master", "user", "repo type"))
|
// 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()
|
all := allr.SortByFullPath()
|
||||||
for all.Scan() {
|
for all.Scan() {
|
||||||
repo := all.Next()
|
repo := all.Next()
|
||||||
f.sendRepoToTable(repo)
|
f.printRepoToTable(repo)
|
||||||
|
count += 1
|
||||||
|
}
|
||||||
|
log.Info("Total git repositories:", count)
|
||||||
|
}
|
||||||
|
|
||||||
|
// also shows which files are dirty
|
||||||
|
func (f *Forge) PrintHumanTableDirty(allr *gitpb.Repos) {
|
||||||
|
log.DaemonMode(true)
|
||||||
|
|
||||||
|
var count int
|
||||||
|
// log.Info(standardStart5("gopath", "cur name", "master", "user", "repo type"))
|
||||||
|
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)
|
||||||
|
if len(repo.DirtyList) != 0 {
|
||||||
|
for _, line := range repo.DirtyList {
|
||||||
|
log.Info("\t", line)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var mver string = repo.GetMasterVersion()
|
||||||
|
repo.Tags.GetAge(mver)
|
||||||
|
|
||||||
count += 1
|
count += 1
|
||||||
}
|
}
|
||||||
log.Info("Total git repositories:", count)
|
log.Info("Total git repositories:", count)
|
||||||
|
@ -77,7 +105,7 @@ func standardTable5(arg1, arg2, arg3, arg4, arg5 string) string {
|
||||||
return fmt.Sprintf(s, arg1, arg2, arg3, arg4, arg5)
|
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
|
len1 := 40
|
||||||
len2 := 12
|
len2 := 12
|
||||||
len3 := 6
|
len3 := 6
|
||||||
|
@ -85,8 +113,9 @@ func standardTable8(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 string)
|
||||||
len5 := 16
|
len5 := 16
|
||||||
len6 := 16
|
len6 := 16
|
||||||
len7 := 16
|
len7 := 16
|
||||||
len8 := 16
|
len8 := 12
|
||||||
len9 := 8
|
len9 := 12
|
||||||
|
len10 := 8
|
||||||
var s string
|
var s string
|
||||||
if len(arg1) > len1 {
|
if len(arg1) > len1 {
|
||||||
arg1 = arg1[:len1]
|
arg1 = arg1[:len1]
|
||||||
|
@ -113,12 +142,12 @@ func standardTable8(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 string)
|
||||||
if len(arg6) > len6 {
|
if len(arg6) > len6 {
|
||||||
arg6 = arg6[:len6]
|
arg6 = arg6[:len6]
|
||||||
}
|
}
|
||||||
s += "%-" + fmt.Sprintf("%d", len6) + "s "
|
s += "%-" + fmt.Sprintf("%d", len6) + "s "
|
||||||
|
|
||||||
if len(arg7) > len7 {
|
if len(arg7) > len7 {
|
||||||
arg7 = arg7[:len7]
|
arg7 = arg7[:len7]
|
||||||
}
|
}
|
||||||
s += "%-" + fmt.Sprintf("%d", len7) + "s "
|
s += "%-" + fmt.Sprintf("%d", len7) + "s "
|
||||||
|
|
||||||
if len(arg8) > len8 {
|
if len(arg8) > len8 {
|
||||||
arg8 = arg8[:len8]
|
arg8 = arg8[:len8]
|
||||||
|
@ -130,17 +159,26 @@ func standardTable8(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 string)
|
||||||
}
|
}
|
||||||
s += "%-" + fmt.Sprintf("%d", len9) + "s "
|
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) sendRepoToTable(repo *gitpb.Repo) {
|
func (f *Forge) printRepoToTable(repo *gitpb.Repo) {
|
||||||
var end string
|
var end string
|
||||||
if repo.IsDirty() {
|
|
||||||
end += "(dirty) "
|
// shortened version numbers
|
||||||
}
|
|
||||||
var mhort string = repo.GetMasterVersion()
|
var mhort string = repo.GetMasterVersion()
|
||||||
var dhort string = repo.GetDevelVersion()
|
var dhort string = repo.GetDevelVersion()
|
||||||
var uhort string = repo.GetUserVersion()
|
var uhort string = repo.GetUserVersion()
|
||||||
|
if uhort == "uerr" {
|
||||||
|
// blank these out
|
||||||
|
uhort = ""
|
||||||
|
}
|
||||||
|
var lasttag string = repo.GetLastTag()
|
||||||
var thort string = repo.GetTargetVersion()
|
var thort string = repo.GetTargetVersion()
|
||||||
var chort string = repo.GetCurrentBranchVersion()
|
var chort string = repo.GetCurrentBranchVersion()
|
||||||
var cname string = repo.GetCurrentBranchName()
|
var cname string = repo.GetCurrentBranchName()
|
||||||
|
@ -148,13 +186,29 @@ func (f *Forge) sendRepoToTable(repo *gitpb.Repo) {
|
||||||
var gopath string = repo.GetGoPath()
|
var gopath string = repo.GetGoPath()
|
||||||
var rtype string = repo.GetRepoType()
|
var rtype string = repo.GetRepoType()
|
||||||
|
|
||||||
age := shell.FormatDuration(repo.NewestAge())
|
// ctime := repo.Tags.GetAge(mhort)
|
||||||
|
// age := shell.FormatDuration(time.Since(ctime))
|
||||||
start := standardTable8(gopath, cname, age, thort, mhort, dhort, uhort, chort, rtype)
|
age := shell.FormatDuration(repo.BranchAge(cname))
|
||||||
|
|
||||||
if f.Config.IsReadOnly(repo.GetGoPath()) {
|
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" {
|
if repo.GetMasterBranchName() != "master" && repo.GetMasterBranchName() != "main" {
|
||||||
end += "(m:" + repo.GetMasterBranchName() + ") "
|
end += "(m:" + repo.GetMasterBranchName() + ") "
|
||||||
}
|
}
|
||||||
|
@ -167,9 +221,21 @@ func (f *Forge) sendRepoToTable(repo *gitpb.Repo) {
|
||||||
end += "(u:" + repo.GetUserBranchName() + ") "
|
end += "(u:" + repo.GetUserBranchName() + ") "
|
||||||
}
|
}
|
||||||
|
|
||||||
|
debname := f.Config.DebName(repo.GetGoPath())
|
||||||
|
if debname != filepath.Base(gopath) {
|
||||||
|
end += "(deb:" + debname + ") "
|
||||||
|
}
|
||||||
|
|
||||||
switch repo.GetState() {
|
switch repo.GetState() {
|
||||||
case "PERFECT":
|
case "PERFECT":
|
||||||
case "unchanged":
|
case "unchanged":
|
||||||
|
case "dirty":
|
||||||
|
case "unknown branches":
|
||||||
|
if repo.CurrentTag == nil {
|
||||||
|
end += "(" + repo.GetState() + ") "
|
||||||
|
} else {
|
||||||
|
end += "(unknown branch " + repo.CurrentTag.Refname + ") "
|
||||||
|
}
|
||||||
// end += "(invalid tag) "
|
// end += "(invalid tag) "
|
||||||
default:
|
default:
|
||||||
end += "(" + repo.GetState() + ") "
|
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
|
||||||
|
}
|
79
init.go
79
init.go
|
@ -1,3 +1,5 @@
|
||||||
|
// Copyright 2025 WIT.COM Inc Licensed GPL 3.0
|
||||||
|
|
||||||
package forgepb
|
package forgepb
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -8,7 +10,6 @@ import (
|
||||||
|
|
||||||
"go.wit.com/lib/gui/shell"
|
"go.wit.com/lib/gui/shell"
|
||||||
"go.wit.com/lib/protobuf/gitpb"
|
"go.wit.com/lib/protobuf/gitpb"
|
||||||
"go.wit.com/lib/protobuf/zoopb"
|
|
||||||
"go.wit.com/log"
|
"go.wit.com/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -18,30 +19,52 @@ import (
|
||||||
func Init() *Forge {
|
func Init() *Forge {
|
||||||
f := InitPB()
|
f := InitPB()
|
||||||
|
|
||||||
f.Machine = new(zoopb.Machine)
|
/*
|
||||||
|
f.Machine = new(zoopb.Machine)
|
||||||
if err := f.Machine.ConfigLoad(); err != nil {
|
if err := f.Machine.ConfigLoad(); err != nil {
|
||||||
log.Log(WARN, "zoopb.ConfigLoad() failed", err)
|
log.Log(WARN, "zoopb.ConfigLoad() failed", err)
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
if f.Config.Username == "" {
|
if f.Config.Username == "" {
|
||||||
usr, _ := user.Current()
|
usr, _ := user.Current()
|
||||||
f.Config.Username = usr.Username
|
f.Config.Username = usr.Username
|
||||||
f.SetConfigSave(true)
|
f.SetConfigSave(true)
|
||||||
}
|
}
|
||||||
f.Machine.InitWit()
|
|
||||||
|
if f.Config.Xterm == "" {
|
||||||
|
f.Config.Xterm = "xterm"
|
||||||
|
f.Config.XtermArgv = append(f.Config.XtermArgv, "-bg")
|
||||||
|
f.Config.XtermArgv = append(f.Config.XtermArgv, "black")
|
||||||
|
f.Config.XtermArgv = append(f.Config.XtermArgv, "-fg")
|
||||||
|
f.Config.XtermArgv = append(f.Config.XtermArgv, "white")
|
||||||
|
f.SetConfigSave(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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()
|
now := time.Now()
|
||||||
start := f.Repos.Len()
|
start := f.Repos.Len()
|
||||||
f.ScanGoSrc()
|
f.ScanGoSrc()
|
||||||
|
f.FullScanRan()
|
||||||
end := f.Repos.Len()
|
end := f.Repos.Len()
|
||||||
if (end - start) == 0 {
|
if (end - start) == 0 {
|
||||||
log.Log(INFO, "forgepb.Scan() Scan did not find new git repositories. Total =", end)
|
log.Log(INFO, "forgepb.Scan() Scan did not find new git repositories. Total =", end)
|
||||||
|
if f.FullScanAge() > time.Minute {
|
||||||
|
f.rillUpdate(20, 10)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
log.Log(INFO, "forgepb.Scan() Scan found", end-start, "new git repositories. Total =", end)
|
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 {
|
if f.configSave {
|
||||||
// taking this out to debug Marshal() panic
|
// taking this out to debug Marshal() panic
|
||||||
// os.Exit(-1)
|
// os.Exit(-1)
|
||||||
|
@ -73,6 +96,8 @@ func DetermineGoPath() *Forge {
|
||||||
os.Setenv("FORGE_CONFIG", fullpath)
|
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
|
// check again for go.work // user could have a go.work file in ~/go/src
|
||||||
if f.goWorkExists() {
|
if f.goWorkExists() {
|
||||||
f.goWork = true
|
f.goWork = true
|
||||||
|
@ -96,8 +121,42 @@ func (f *Forge) InitPB() {
|
||||||
} else {
|
} else {
|
||||||
log.Log(INFO, "forgepb.Init() FORGE_GOSRC ", os.Getenv("FORGE_GOSRC"), "(go.work = false)")
|
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()
|
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
|
// 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"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
"go.wit.com/lib/protobuf/gitpb"
|
"go.wit.com/lib/protobuf/gitpb"
|
||||||
"go.wit.com/log"
|
"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 := 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")
|
dir, err := os.MkdirTemp("", "forge")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -23,17 +42,21 @@ func (f *Forge) MakeDevelPatchSet() (*Patchset, error) {
|
||||||
all := f.Repos.SortByFullPath()
|
all := f.Repos.SortByFullPath()
|
||||||
for all.Scan() {
|
for all.Scan() {
|
||||||
repo := all.Next()
|
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
|
continue
|
||||||
}
|
}
|
||||||
if userb == "" {
|
if !repo.IsLocalBranch(repo.GetDevelBranchName()) {
|
||||||
|
// log.Info("repo doesn't have devel branch", repo.GetGoPath())
|
||||||
continue
|
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)
|
err := pset.makePatchSetNew(repo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -42,6 +65,17 @@ func (f *Forge) MakeDevelPatchSet() (*Patchset, error) {
|
||||||
return pset, nil
|
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) {
|
func (f *Forge) MakeMasterPatchSet() (*Patchset, error) {
|
||||||
pset := new(Patchset)
|
pset := new(Patchset)
|
||||||
dir, err := os.MkdirTemp("", "forge")
|
dir, err := os.MkdirTemp("", "forge")
|
||||||
|
@ -83,7 +117,19 @@ func (pset *Patchset) makePatchSetNew(repo *gitpb.Repo) error {
|
||||||
return err
|
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
|
// 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}
|
cmd := []string{"git", "format-patch", "-o", repoDir, startBranch + ".." + endBranch}
|
||||||
r := repo.Run(cmd)
|
r := repo.Run(cmd)
|
||||||
if r.Error != nil {
|
if r.Error != nil {
|
||||||
|
@ -103,14 +149,16 @@ func (pset *Patchset) makePatchSetNew(repo *gitpb.Repo) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return pset.addPatchFiles(repo)
|
err = pset.addPatchFiles(repo)
|
||||||
|
pset.Ctime = timestamppb.New(time.Now())
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// process each file in pDir/
|
// process each file in pDir/
|
||||||
func (p *Patchset) addPatchFiles(repo *gitpb.Repo) error {
|
func (p *Patchset) addPatchFiles(repo *gitpb.Repo) error {
|
||||||
psetDir := repo.GetGoPath()
|
psetDir := repo.GetGoPath()
|
||||||
tmpDir := p.TmpDir
|
tmpDir := p.TmpDir
|
||||||
log.Info("ADD PATCH FILES ADDED DIR", tmpDir)
|
// log.Info("ADD PATCH FILES ADDED DIR", tmpDir)
|
||||||
fullDir := filepath.Join(tmpDir, psetDir)
|
fullDir := filepath.Join(tmpDir, psetDir)
|
||||||
var baderr error
|
var baderr error
|
||||||
filepath.Walk(fullDir, func(path string, info os.FileInfo, err error) 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() {
|
if info.IsDir() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
log.Info("IS THIS A FULL PATH ?", path)
|
// log.Info("IS THIS A FULL PATH ?", path)
|
||||||
log.Info("trim this from path ?", fullDir)
|
// log.Info("trim this from path ?", fullDir)
|
||||||
log.Info("trim this from path ?", psetDir)
|
// log.Info("trim this from path ?", psetDir)
|
||||||
log.Info("trim this from path ?", tmpDir)
|
// log.Info("trim this from path ?", tmpDir)
|
||||||
data, err := os.ReadFile(path)
|
data, err := os.ReadFile(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Info("addPatchFile() failed", path)
|
log.Info("addPatchFile() failed", path)
|
||||||
|
@ -139,8 +187,14 @@ func (p *Patchset) addPatchFiles(repo *gitpb.Repo) error {
|
||||||
patch.Data = data
|
patch.Data = data
|
||||||
patch.parseData()
|
patch.parseData()
|
||||||
patch.StartHash = repo.DevelHash()
|
patch.StartHash = repo.DevelHash()
|
||||||
|
patch.NewHash = "na"
|
||||||
|
patch.RepoNamespace = repo.GetGoPath()
|
||||||
|
if p.Patches == nil {
|
||||||
|
p.Patches = new(Patches)
|
||||||
|
}
|
||||||
p.Patches.Append(patch)
|
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 nil
|
||||||
})
|
})
|
||||||
return baderr
|
return baderr
|
||||||
|
@ -159,6 +213,8 @@ func (p *Patch) parseData() string {
|
||||||
switch fields[0] {
|
switch fields[0] {
|
||||||
case "From":
|
case "From":
|
||||||
p.CommitHash = fields[1]
|
p.CommitHash = fields[1]
|
||||||
|
case "Subject:":
|
||||||
|
p.Comment = line
|
||||||
case "diff":
|
case "diff":
|
||||||
p.Files = append(p.Files, line)
|
p.Files = append(p.Files, line)
|
||||||
}
|
}
|
||||||
|
@ -188,3 +244,29 @@ func onlyWalkDirs(pDir string) error {
|
||||||
})
|
})
|
||||||
return baderr
|
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";
|
syntax = "proto3";
|
||||||
|
|
||||||
package forgepb;
|
package forgepb;
|
||||||
|
|
||||||
import "google/protobuf/timestamp.proto"; // Import the well-known type for Timestamp
|
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 {
|
message Patch {
|
||||||
string filename = 1; // `autogenpb:unique` `autogenpb:sort`
|
string repoNamespace = 1; // the base repo git URL
|
||||||
bytes data = 2; //
|
bytes data = 2; // the raw data of the whole patch
|
||||||
string repoPath = 3; // path to the git repo
|
string gH = 3; // after some deliberation, I think I'll just try variable names
|
||||||
string branchName = 4; //
|
string gT = 4;
|
||||||
string branchHash = 5; //
|
string gP = 5;
|
||||||
google.protobuf.Timestamp ctime = 7; // the git commit timestamp of this patch
|
string gs = 6;
|
||||||
string commitHash = 8; // the git commit hash of this patch
|
string gaI = 7; // that exactly match what git uses.
|
||||||
string startHash = 9; // the start commit hash
|
string gan = 8;
|
||||||
repeated string Files = 10; // the filenames this patch changes
|
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`
|
message Patches { // this is a "PATCH: [1/x]" series `autogenpb:gui:Patch`
|
||||||
string uuid = 1; // `autogenpb:uuid:be926ad9-1111-484c-adf2-d96eeabf3079` // todo: add autogenpb support for this
|
string uuid = 1; // `autogenpb:uuid:be926ad9-1111-484c-adf2-d96eeabf3079`
|
||||||
string version = 2; // `autogenpb:version:v0.0.45` // todo: add autogenpb support for this
|
string version = 2; // `autogenpb:version:v0.0.45`
|
||||||
repeated Patch Patches = 3;
|
repeated Patch Patches = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
message Patchset { // `autogenpb:marshal`
|
message Patchset { // `autogenpb:marshal`
|
||||||
Patches patches = 1; // `autogenpb:unique` `autogenpb:sort`
|
Patches patches = 1; //
|
||||||
string name = 2; // `autogenpb:sort`
|
string name = 2; // `autogenpb:sort`
|
||||||
string comment = 3; //
|
string comment = 3; //
|
||||||
string gitAuthorName = 4; // `autogenpb:sort`
|
string gitAuthorName = 4; // `autogenpb:sort`
|
||||||
string gitAuthorEmail = 5; //
|
string gitAuthorEmail = 5; //
|
||||||
google.protobuf.Timestamp ctime = 6; // create time of this patchset
|
google.protobuf.Timestamp ctime = 6; // create time of the patchset
|
||||||
string tmpDir = 7; // temp dir
|
string tmpDir = 7; // temp dir
|
||||||
string startBranchName = 8; //
|
string startBranchName = 8; //
|
||||||
string endBranchName = 9; //
|
string endBranchName = 9; //
|
||||||
string startBranchHash = 10; //
|
string startBranchHash = 10; //
|
||||||
string endBranchHash = 11; //
|
string endBranchHash = 11; //
|
||||||
|
string state = 12; // the state of the patch
|
||||||
|
string uuid = 13; // `autogenpb:sort` `autogenpb:unique`
|
||||||
}
|
}
|
||||||
|
|
||||||
message Patchsets { // `autogenpb:marshal`
|
message Patchsets { // `autogenpb:marshal` `autogenpb:gui`
|
||||||
string uuid = 1; // `autogenpb:uuid:be926ad9-f07f-484c-adf2-d96eeabf3079` // todo: add autogenpb support for this
|
string uuid = 1; // `autogenpb:uuid:be926ad9-f07f-484c-adf2-d96eeabf3079`
|
||||||
string version = 2; // `autogenpb:version:v0.0.45` // todo: add autogenpb support for this
|
string version = 2; // `autogenpb:version:v0.0.45`
|
||||||
repeated Patchset Patchsets = 3;
|
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
|
package forgepb
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -13,11 +15,17 @@ import (
|
||||||
|
|
||||||
func (f *Forge) NewGoRepo(gopath string, url string) (*gitpb.Repo, error) {
|
func (f *Forge) NewGoRepo(gopath string, url string) (*gitpb.Repo, error) {
|
||||||
fullpath := filepath.Join(f.GetGoSrc(), gopath)
|
fullpath := filepath.Join(f.GetGoSrc(), gopath)
|
||||||
|
test := f.Repos.FindByFullPath(fullpath)
|
||||||
|
if test != nil {
|
||||||
|
return test, nil
|
||||||
|
}
|
||||||
repo, err := f.Repos.NewGoRepo(fullpath, gopath)
|
repo, err := f.Repos.NewGoRepo(fullpath, gopath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Info("WARNING. NEW FAILED", fullpath)
|
log.Info("WARNING. NEW FAILED", fullpath)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
// slices.Reverse(f.Repos.Repos)
|
||||||
|
|
||||||
repo.URL = url
|
repo.URL = url
|
||||||
f.VerifyBranchNames(repo)
|
f.VerifyBranchNames(repo)
|
||||||
if f.Config.IsReadOnly(repo.GetGoPath()) {
|
if f.Config.IsReadOnly(repo.GetGoPath()) {
|
||||||
|
@ -76,7 +84,7 @@ func (f *Forge) findMasterBranch(repo *gitpb.Repo) {
|
||||||
if strings.HasPrefix(s, "ref: ") {
|
if strings.HasPrefix(s, "ref: ") {
|
||||||
fields := strings.Fields(s)
|
fields := strings.Fields(s)
|
||||||
_, bname := filepath.Split(fields[1])
|
_, 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)
|
repo.SetMasterBranchName(bname)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -95,11 +103,13 @@ func (f *Forge) findMasterBranch(repo *gitpb.Repo) {
|
||||||
|
|
||||||
// TODO: figure out the name from git
|
// TODO: figure out the name from git
|
||||||
repo.SetMasterBranchName("master")
|
repo.SetMasterBranchName("master")
|
||||||
|
/* no longer checkout on Init()
|
||||||
if repo.CheckoutMaster() {
|
if repo.CheckoutMaster() {
|
||||||
} else {
|
} else {
|
||||||
cmd := []string{"git", "branch", "master"}
|
cmd := []string{"git", "branch", "master"}
|
||||||
repo.Run(cmd)
|
repo.Run(cmd)
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
// figure out what the name of the git devel branch is
|
// 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
|
// check the forge config first
|
||||||
if bname := f.Config.FindDevelBranch(repo.GetGoPath()); bname != "" {
|
if bname := f.Config.FindDevelBranch(repo.GetGoPath()); bname != "" {
|
||||||
repo.SetDevelBranchName(bname)
|
repo.SetDevelBranchName(bname)
|
||||||
|
/* no longer checkout on Init()
|
||||||
if repo.CheckoutDevel() {
|
if repo.CheckoutDevel() {
|
||||||
} else {
|
} else {
|
||||||
cmd := []string{"git", "branch", bname}
|
cmd := []string{"git", "branch", bname}
|
||||||
repo.Run(cmd)
|
repo.Run(cmd)
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,13 +133,14 @@ func (f *Forge) findDevelBranch(repo *gitpb.Repo) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: figure out the name from git
|
|
||||||
repo.SetDevelBranchName("devel")
|
repo.SetDevelBranchName("devel")
|
||||||
|
/* no longer checkout on Init()
|
||||||
if repo.CheckoutDevel() {
|
if repo.CheckoutDevel() {
|
||||||
} else {
|
} else {
|
||||||
cmd := []string{"git", "branch", "devel"}
|
cmd := []string{"git", "branch", "devel"}
|
||||||
repo.Run(cmd)
|
repo.Run(cmd)
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
// this is still in flux
|
// this is still in flux
|
||||||
|
@ -149,11 +162,6 @@ func (f *Forge) VerifyBranchNames(repo *gitpb.Repo) {
|
||||||
} else {
|
} else {
|
||||||
// forcing for now. todo: warn users
|
// forcing for now. todo: warn users
|
||||||
repo.SetUserBranchName(uname)
|
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
|
package forgepb
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/destel/rill"
|
"github.com/destel/rill"
|
||||||
"go.wit.com/lib/protobuf/gitpb"
|
"go.wit.com/lib/protobuf/gitpb"
|
||||||
"go.wit.com/log"
|
"go.wit.com/log"
|
||||||
|
@ -64,3 +66,90 @@ func (f *Forge) updateRepo(repo *gitpb.Repo) error {
|
||||||
}
|
}
|
||||||
return nil
|
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 (
|
import (
|
||||||
sync "sync"
|
sync "sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
"go.wit.com/lib/protobuf/gitpb"
|
"go.wit.com/lib/protobuf/gitpb"
|
||||||
"go.wit.com/lib/protobuf/zoopb"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// maybe an interface someday?
|
// maybe an interface someday?
|
||||||
type Forge struct {
|
type Forge struct {
|
||||||
// one-time initialized data
|
// one-time initialized data
|
||||||
initOnce sync.Once
|
initOnce sync.Once
|
||||||
initErr error // init error, if any
|
initErr error // init error, if any
|
||||||
|
goSrc string // the path to go/src
|
||||||
goSrc string // the path to go/src
|
configDir string // normally ~/.config/forge
|
||||||
goWork bool // means the user is currently using a go.work file
|
goWork bool // means the user is currently using a go.work file
|
||||||
Config *ForgeConfigs // config repos for readonly, private, etc
|
Config *ForgeConfigs // config repos for readonly, private, etc
|
||||||
Repos *gitpb.Repos
|
Repos *gitpb.Repos // the repo protobufs
|
||||||
Machine *zoopb.Machine
|
// Machine *zoopb.Machine // things for virtigo to track vm's
|
||||||
configSave bool
|
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 {
|
func (f *Forge) GetGoSrc() string {
|
||||||
return f.goSrc
|
return f.goSrc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *Forge) GetConfigDir() string {
|
||||||
|
return f.configDir
|
||||||
|
}
|
||||||
|
|
||||||
func (f *Forge) IsGoWork() bool {
|
func (f *Forge) IsGoWork() bool {
|
||||||
return f.goWork
|
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