save GoDeps at the time of publication to pkg.go.dev

This commit is contained in:
Jeff Carr 2024-12-01 10:46:32 -06:00
parent 455ea31d70
commit 8e9ec30b29
8 changed files with 195 additions and 19 deletions

View File

@ -36,10 +36,10 @@ clean:
# refs.proto
gitTag.pb.go: gitTag.proto
autogenpb --proto gitTag.proto --no-marshal
autogenpb --proto gitTag.proto --mutex
goDep.pb.go: goDep.proto
autogenpb --proto goDep.proto --no-marshal
autogenpb --proto goDep.proto --mutex
repo.pb.go: repo.proto
autogenpb --proto repo.proto
autogenpb --proto repo.proto --mutex

103
config.go Normal file
View File

@ -0,0 +1,103 @@
package gitpb
// functions to import and export the protobuf
// data to and from config files
import (
"errors"
"os"
"path/filepath"
"go.wit.com/log"
)
// write to ~/.config/forge/ unless ENV{FORGE_HOME} is set
func (all *Repos) ConfigSave() error {
if os.Getenv("FORGE_HOME") == "" {
homeDir, _ := os.UserHomeDir()
fullpath := filepath.Join(homeDir, ".config/forge")
os.Setenv("FORGE_HOME", fullpath)
}
if all == nil {
log.Warn("gitpb all == nil")
panic("why is this nil?")
}
data, err := all.Marshal()
if err != nil {
log.Info("gitpb proto.Marshal() failed len", len(data), err)
return err
}
log.Info("gitpb.ConfigSave() repos.Marshal() worked len", len(data))
configWrite("repos.pb", data)
return nil
}
// load the ~/.config/forge/ files
func (all *Repos) ConfigLoad() error {
if os.Getenv("FORGE_HOME") == "" {
homeDir, _ := os.UserHomeDir()
fullpath := filepath.Join(homeDir, ".config/forge")
os.Setenv("FORGE_HOME", fullpath)
}
var data []byte
var err error
if data, err = loadFile("repos.pb"); err != nil {
// something went wrong loading the file
return err
}
if data != nil {
// this means the forge.pb file exists and was read
if len(data) == 0 {
// todo: error out if the file is empty?
// try forge.text & forge.json?
}
if err = all.Unmarshal(data); err != nil {
log.Warn("broken forge.pb config file")
return err
}
log.Info("found", len(all.Repos), "repos in ~/.config/forge/repos.pb")
return nil
}
return nil
}
func loadFile(filename string) ([]byte, error) {
fullname := filepath.Join(os.Getenv("FORGE_HOME"), filename)
data, err := os.ReadFile(fullname)
if errors.Is(err, os.ErrNotExist) {
// if file does not exist, just return nil. this
// will cause ConfigLoad() to try the next config file like "forge.text"
// because the user might want to edit the .config by hand
return nil, nil
}
if err != nil {
// log.Info("open config file :", err)
return nil, err
}
return data, nil
}
func configWrite(filename string, data []byte) error {
fullname := filepath.Join(os.Getenv("FORGE_HOME"), filename)
cfgfile, err := os.OpenFile(fullname, os.O_RDWR|os.O_CREATE, 0666)
defer cfgfile.Close()
if err != nil {
log.Warn("open config file :", err)
return err
}
if filename == "forge.text" {
// add header
cfgfile.Write([]byte("# this file is automatically re-generated from forge.pb, however,\n"))
cfgfile.Write([]byte("# if you want to edit it by hand, you can:\n"))
cfgfile.Write([]byte("# stop forge; remove forge.pb; edit forge.text; start forge\n"))
cfgfile.Write([]byte("# this will cause the default behavior to fallback to parsing this file for the config\n"))
cfgfile.Write([]byte("\n"))
cfgfile.Write([]byte("# this file is intended to be used to customize settings on what\n"))
cfgfile.Write([]byte("# git repos you have write access to. That is, where you can run 'git push'\n"))
}
cfgfile.Write(data)
return nil
}

View File

@ -4,7 +4,7 @@ package gitpb;
import "google/protobuf/timestamp.proto"; // Import the well-known type for Timestamp
message GitTag {
message GitTag { // `autogenpb:marshal`
string refname = 1; // `autogenpb:unique` // tag name. treated as unique
google.protobuf.Timestamp creatordate = 2; // git creatordate
google.protobuf.Timestamp authordate = 3; // git author date
@ -12,7 +12,7 @@ message GitTag {
string subject = 5; // git tag subject
}
message GitTags {
message GitTags { // `autogenpb:marshal`
string uuid = 1; // I guess why not just have this on each file
string version = 2; // maybe can be used for protobuf schema change violations
repeated GitTag gitTags = 3;

View File

@ -12,8 +12,7 @@ import (
// Update repo.Refs from .git/
func (repo *Repo) UpdateGitTags() error {
// delete the old hash
// r.DeleteByHash(hash)
// todo: look for changes in the tags?
repo.Tags = new(GitTags)
tags := []string{"%(objectname)", "%(creatordate)", "%(*authordate)", "%(refname)", "%(subject)"}

View File

@ -6,7 +6,7 @@ package gitpb;
import "google/protobuf/timestamp.proto"; // Import the well-known type for Timestamp
message GoDep {
message GoDep { // `autogenpb:marshal`
string hash = 1; // `autogenpb:unique` // md5sum/hash value from the go.sum file
google.protobuf.Timestamp ctime = 2; // get the go date from 'go list' ?
string version = 3; // v1.2.2
@ -14,7 +14,7 @@ message GoDep {
string goVersion = 5; // version of golang the developer used to make this package version
}
message GoDeps {
message GoDeps { // `autogenpb:marshal`
string uuid = 1; // I guess why not just have this on each file
string version = 2; // maybe can be used for protobuf schema change violations
repeated GoDep goDeps = 3;

View File

@ -138,3 +138,67 @@ func (repo *Repo) RepoType() string {
output = strings.Trim(output, "'")
return output
}
// reads and parses the go.sum file
func (repo *Repo) UpdatePublished() (bool, error) {
// empty out what was there before
repo.Published = nil
tmp := filepath.Join(repo.FullPath, "go.sum")
gosum, err := os.Open(tmp)
if err != nil {
log.Warn("missing go.sum", repo.FullPath)
return false, err
}
defer gosum.Close()
scanner := bufio.NewScanner(gosum)
log.Info("gosum:", tmp)
for scanner.Scan() {
line := strings.TrimSpace(scanner.Text())
parts := strings.Split(line, " ")
if len(parts) == 3 {
godep := strings.TrimSpace(parts[0])
version := strings.TrimSpace(parts[1])
if strings.HasSuffix(version, "/go.mod") {
version = strings.TrimSuffix(version, "/go.mod")
}
new1 := GoDep{
GoPath: godep,
Version: version,
}
if repo.Published == nil {
repo.Published = new(GoDeps)
}
repo.Published.AppendUniqueGoPath(&new1)
/*
found := repo.FindGoDepByPath(godep)
if found == nil {
currentversion, ok := deps[godep]
if ok {
// only use the first value found in the file?
// this shouldn't have been possible. this function should
// only be called from MakeRedomod()
// todo: make go things a seperate package so this function
// isn't exported?
if version != currentversion {
log.Warn("\tgo.sum ", godep, "had both", version, currentversion)
}
} else {
deps[godep] = version
log.Info("\t", godep, "=", version)
}
*/
} else {
// I've never seen this happen yet
panic(errors.New("go.sum invalid: " + line))
// return false, errors.New("go.sum invalid: " + line)
}
}
if err := scanner.Err(); err != nil {
repo.Published = nil
return false, err
}
return true, nil
}

View File

@ -33,8 +33,18 @@ func (all *Repos) NewGoPath(basepath string, gopath string) (*Repo, error) {
FullPath: filepath.Join(basepath, gopath),
GoPath: gopath,
}
newr.Tags = new(GitTags)
// newr.UpdateGit()
newr.UpdateGitTags()
newr.GoDeps = new(GoDeps)
// newr.RedoGoMod()
switch newr.RepoType() {
case "library":
newr.GoLibrary = true
case "binary":
newr.GoBinary = true
}
all.AppendUniqueGoPath(&newr)
return &newr, nil

View File

@ -15,16 +15,16 @@ message Repo { // `autogenpb:marshal`
string masterBranchName = 3; // git 'main' or 'master' branch name
string develBranchName = 4; // whatever the git 'devel' branch name is
string userBranchName = 5; // whatever your username branch is
GitTags tags = 6;
// things specific to golang projects
string goPath = 7; // `autogenpb:unique` // the logical path as used by golang: 'go.wit.com/apps/helloworld'
bool goLibrary = 8; // if this is a golang library
bool goPrimitive = 9; // if this is a golang primitive
GoDeps goDeps = 10;
google.protobuf.Timestamp lastGoDep = 11; // last time go.sum was processed
bool dirty = 12; // if git says things have been changed
GitTags tags = 6; // known tags
string goPath = 7; // `autogenpb:unique` // the logical path as used by golang: 'go.wit.com/apps/helloworld'
bool goLibrary = 8; // is this a golang library?
bool goBinary = 9; // is this a golang binary?
bool goPrimitive = 10; // if this is a golang primitive (only has go.mod)
bool goPlugin = 11; // is this a golang plugin?
GoDeps goDeps = 12; // what is in the go.sum file
google.protobuf.Timestamp lastGoDep = 13; // last time go.sum was processed
bool dirty = 14; // if git says things have been changed
GoDeps published = 15; // the last published go.mod/go.sum
}
message Repos { // `autogenpb:marshal`