From 48b19f1e70331fc6213a2e3a179e8b18a26aaecc Mon Sep 17 00:00:00 2001 From: Jeff Carr Date: Sat, 11 Jan 2025 05:55:42 -0600 Subject: new protobuf file --- Makefile | 5 +- configDefault.go | 8 +-- patch.Make.go | 190 --------------------------------------------------- patch.Send.go | 27 -------- patch.proto | 33 --------- patchset.HAMDMADE.go | 81 ++++++++++++++++++++++ patchset.Make.go | 190 +++++++++++++++++++++++++++++++++++++++++++++++++++ patchset.Send.go | 27 ++++++++ patchset.proto | 14 ++-- 9 files changed, 307 insertions(+), 268 deletions(-) delete mode 100644 patch.Make.go delete mode 100644 patch.Send.go delete mode 100644 patch.proto create mode 100644 patchset.HAMDMADE.go create mode 100644 patchset.Make.go create mode 100644 patchset.Send.go diff --git a/Makefile b/Makefile index cbcbf93..79ebccd 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ # go install -all: forgeConfig.pb.go uuid.pb.go patch.pb.go goimports vet +all: forgeConfig.pb.go patchset.pb.go goimports vet generate: clean go-mod-clean @@ -26,8 +26,5 @@ clean: forgeConfig.pb.go: forgeConfig.proto autogenpb --proto forgeConfig.proto -uuid.pb.go: uuid.proto - autogenpb --proto uuid.proto - patchset.pb.go: patchset.proto autogenpb --proto patchset.proto diff --git a/configDefault.go b/configDefault.go index 89e8ba8..3246798 100644 --- a/configDefault.go +++ b/configDefault.go @@ -2,8 +2,6 @@ package forgepb import ( "fmt" - - "go.wit.com/log" ) func (all *ForgeConfigs) sampleConfig() { @@ -11,11 +9,7 @@ func (all *ForgeConfigs) sampleConfig() { new1.GoPath = "go.wit.com" new1.Writable = true new1.Directory = true - if all.Append(new1) { - log.Info("added", new1.GoPath, "ok") - } else { - log.Info("added", new1.GoPath, "failed") - } + all.Append(new1) fmt.Println("first time user. adding an example config file with", len(all.ForgeConfigs), "repos") } diff --git a/patch.Make.go b/patch.Make.go deleted file mode 100644 index f43d9be..0000000 --- a/patch.Make.go +++ /dev/null @@ -1,190 +0,0 @@ -package forgepb - -import ( - "errors" - "fmt" - "os" - "path/filepath" - "strings" - - "go.wit.com/lib/protobuf/gitpb" - "go.wit.com/log" -) - -func (f *Forge) MakeDevelPatchSet() (*Patchs, error) { - pset := new(Patchs) - dir, err := os.MkdirTemp("", "forge") - if err != nil { - return nil, err - } - defer os.RemoveAll(dir) // clean up - pset.TmpDir = dir - - all := f.Repos.SortByFullPath() - for all.Scan() { - repo := all.Next() - userb := repo.GetUserBranchName() - develb := repo.GetDevelBranchName() - - if develb == "" { - continue - } - if userb == "" { - continue - } - pset.StartBranchName = develb - pset.EndBranchName = userb - err := pset.makePatchSetNew(repo) - if err != nil { - return nil, err - } - } - return pset, nil -} - -func (f *Forge) MakeMasterPatchSet() (*Patchs, error) { - pset := new(Patchs) - dir, err := os.MkdirTemp("", "forge") - if err != nil { - return nil, err - } - defer os.RemoveAll(dir) // clean up - pset.TmpDir = dir - - all := f.Repos.SortByFullPath() - for all.Scan() { - repo := all.Next() - startb := repo.GetMasterBranchName() - endb := repo.GetUserBranchName() - - if startb == "" { - continue - } - if endb == "" { - continue - } - // log.Info("repo", repo.GetGoPath(), startb, "..", endb) - pset.StartBranchName = startb - pset.EndBranchName = endb - err := pset.makePatchSetNew(repo) - if err != nil { - return nil, err - } - } - return pset, nil -} - -func (pset *Patchs) makePatchSetNew(repo *gitpb.Repo) error { - startBranch := pset.StartBranchName - endBranch := pset.EndBranchName - repoDir := filepath.Join(pset.TmpDir, repo.GetGoPath()) - err := os.MkdirAll(repoDir, 0755) - if err != nil { - return err - } - - // git format-patch branch1..branch2 - cmd := []string{"git", "format-patch", "-o", repoDir, startBranch + ".." + endBranch} - r := repo.Run(cmd) - if r.Error != nil { - log.Info("git format-patch", repo.FullPath) - log.Info("git format-patch", cmd) - log.Info("git format-patch error", r.Error) - return r.Error - } - if r.Exit != 0 { - log.Info("git format-patch", repo.FullPath) - log.Info("git format-patch", cmd) - log.Info("git format-patch exit", r.Exit) - return errors.New(fmt.Sprintf("git returned %d", r.Exit)) - } - if len(r.Stdout) == 0 { - // git created no files to add - return nil - } - - return pset.addPatchFiles(repo) -} - -// process each file in pDir/ -func (p *Patchs) addPatchFiles(repo *gitpb.Repo) error { - psetDir := repo.GetGoPath() - tmpDir := p.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 { - if err != nil { - // Handle possible errors, like permission issues - fmt.Fprintf(os.Stderr, "error accessing path %q: %v\n", path, err) - baderr = err - return err - } - - 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) - data, err := os.ReadFile(path) - if err != nil { - log.Info("addPatchFile() failed", path) - baderr = err - return err - } - patch := new(Patch) - patch.Filename, _ = filepath.Rel(p.TmpDir, path) - patch.Data = data - patch.parseData() - patch.StartHash = repo.DevelHash() - p.Patchs = append(p.Patchs, patch) - log.Info("ADDED PATCH FILE", path) - return nil - }) - return baderr -} - -// looks at the git format-patch output -// saves the commit Hash -// saves the diff lines -func (p *Patch) parseData() string { - lines := strings.Split(string(p.Data), "\n") - for _, line := range lines { - fields := strings.Fields(line) - if len(fields) < 2 { - continue - } - switch fields[0] { - case "From": - p.CommitHash = fields[1] - case "diff": - p.Files = append(p.Files, line) - } - } - return "" -} - -// just an example of how to walk only directories -func onlyWalkDirs(pDir string) error { - log.Info("DIR", pDir) - // var all []string - var baderr error - filepath.WalkDir(pDir, func(path string, d os.DirEntry, err error) error { - if err != nil { - // Handle possible errors, like permission issues - fmt.Fprintf(os.Stderr, "error accessing path %q: %v\n", path, err) - baderr = err - return err - } - - log.Info("TESTING DIR", path) - if d.IsDir() { - return filepath.SkipDir - } - log.Info("NEVER GETS HERE? WHAT IS THIS?", path) - return nil - }) - return baderr -} diff --git a/patch.Send.go b/patch.Send.go deleted file mode 100644 index 42585ea..0000000 --- a/patch.Send.go +++ /dev/null @@ -1,27 +0,0 @@ -package forgepb - -// functions to import and export the protobuf -// data to and from config files - -import ( - "errors" - "time" - - "go.wit.com/log" -) - -func (f *Forge) SendPatchSet(pset *Patchs) error { - var err error - data, err := pset.Marshal() - if err != nil { - log.Info("proto.Marshal() pset(len) error", len(data), err) - return err - } - now := time.Now() - timestamp := now.Format("2006.01.02.150405") // bummer. other date doesn't work? - cfgfile := "patchset/patchset." + timestamp + ".pb" - log.Info("proto.Marshal() pset(len)", len(data)) - configWrite(cfgfile, data) - - return errors.New("don't know how to send yet") -} diff --git a/patch.proto b/patch.proto deleted file mode 100644 index 5942924..0000000 --- a/patch.proto +++ /dev/null @@ -1,33 +0,0 @@ -syntax = "proto3"; - -package forgepb; - -import "google/protobuf/timestamp.proto"; // Import the well-known type for Timestamp - -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 -} - -message Patchs { // `autogenpb:marshal` - string uuid = 1; // `autogenpb:uuid:0703df95-6a38-4422-994b-c55d3d6001f9` // todo: add file support - string version = 2; // could be used for protobuf schema change violations? - repeated Patch Patchs = 3; - string name = 4; // - string comment = 5; // - string gitAuthorName = 6; // - string gitAuthorEmail = 7; // - google.protobuf.Timestamp ctime = 8; // create time of this patchset - string tmpDir = 9; // temp dir - string startBranchName = 10; // - string endBranchName = 11; // - string startBranchHash = 12; // - string endBranchHash = 13; // -} diff --git a/patchset.HAMDMADE.go b/patchset.HAMDMADE.go new file mode 100644 index 0000000..5f3124b --- /dev/null +++ b/patchset.HAMDMADE.go @@ -0,0 +1,81 @@ +// Code generated by go.wit.com/apps/autogenpb DO NOT EDIT. +// This file was autogenerated with autogenpb v0.0.40-19-gfed674d 2025.01.11_0448 +// go install go.wit.com/apps/autogenpb@latest +// +// define which structs (messages) you want to use in the .proto file +// Then sort.pb.go and marshal.pb.go files are autogenerated +// +// autogenpb uses it and has an example .proto file with instructions +// + +package forgepb + +import ( + "fmt" + "sort" + "sync" +) + +// DEFINE THE ITERATOR. Only one per Patch message + +// NewPatchsetIterator initializes a new iterator. +func NewPatchIterator(things []*Patch) *PatchIterator { + return &PatchIterator{things: things} +} + +// safely returns a slice of pointers to the Patchset protobufs +func (x *Patchset) all() []*Patch { + x.Lock.RLock() + defer x.Lock.RUnlock() + + // Create a new slice to hold pointers to each Patchset + var tmp []*Patch + tmp = make([]*Patch, len(x.Patches)) + for i, p := range x.Patches { + tmp[i] = p // Copy pointers for safe iteration + } + + return tmp +} + +type PatchIterator struct { + sync.RWMutex + + things []*Patch + index int +} + +func (it *PatchIterator) Scan() bool { + if it.index >= len(it.things) { + return false + } + it.index++ + return true +} + +// Next() returns the next thing in the array +func (it *PatchIterator) Next() *Patch { + if it.things[it.index-1] == nil { + fmt.Println("Next() error in PatchIterator", it.index) + } + return it.things[it.index-1] +} + +// END DEFINE THE ITERATOR + +// START sort by Filename (this is all you need once the Iterator is defined) +type PatchFilename []*Patch + +func (a PatchFilename) Len() int { return len(a) } +func (a PatchFilename) Less(i, j int) bool { return a[i].Filename < a[j].Filename } +func (a PatchFilename) Swap(i, j int) { a[i], a[j] = a[j], a[i] } + +func (x *Patchset) SortByFilename() *PatchIterator { + things := x.all() + + sort.Sort(PatchFilename(things)) + + iterator := NewPatchIterator(things) + return iterator +} +// END sort by Filename diff --git a/patchset.Make.go b/patchset.Make.go new file mode 100644 index 0000000..fd68efb --- /dev/null +++ b/patchset.Make.go @@ -0,0 +1,190 @@ +package forgepb + +import ( + "errors" + "fmt" + "os" + "path/filepath" + "strings" + + "go.wit.com/lib/protobuf/gitpb" + "go.wit.com/log" +) + +func (f *Forge) MakeDevelPatchSet() (*Patchset, error) { + pset := new(Patchset) + dir, err := os.MkdirTemp("", "forge") + if err != nil { + return nil, err + } + defer os.RemoveAll(dir) // clean up + pset.TmpDir = dir + + all := f.Repos.SortByFullPath() + for all.Scan() { + repo := all.Next() + userb := repo.GetUserBranchName() + develb := repo.GetDevelBranchName() + + if develb == "" { + continue + } + if userb == "" { + continue + } + pset.StartBranchName = develb + pset.EndBranchName = userb + err := pset.makePatchSetNew(repo) + if err != nil { + return nil, err + } + } + return pset, nil +} + +func (f *Forge) MakeMasterPatchSet() (*Patchset, error) { + pset := new(Patchset) + dir, err := os.MkdirTemp("", "forge") + if err != nil { + return nil, err + } + defer os.RemoveAll(dir) // clean up + pset.TmpDir = dir + + all := f.Repos.SortByFullPath() + for all.Scan() { + repo := all.Next() + startb := repo.GetMasterBranchName() + endb := repo.GetUserBranchName() + + if startb == "" { + continue + } + if endb == "" { + continue + } + // log.Info("repo", repo.GetGoPath(), startb, "..", endb) + pset.StartBranchName = startb + pset.EndBranchName = endb + err := pset.makePatchSetNew(repo) + if err != nil { + return nil, err + } + } + return pset, nil +} + +func (pset *Patchset) makePatchSetNew(repo *gitpb.Repo) error { + startBranch := pset.StartBranchName + endBranch := pset.EndBranchName + repoDir := filepath.Join(pset.TmpDir, repo.GetGoPath()) + err := os.MkdirAll(repoDir, 0755) + if err != nil { + return err + } + + // git format-patch branch1..branch2 + cmd := []string{"git", "format-patch", "-o", repoDir, startBranch + ".." + endBranch} + r := repo.Run(cmd) + if r.Error != nil { + log.Info("git format-patch", repo.FullPath) + log.Info("git format-patch", cmd) + log.Info("git format-patch error", r.Error) + return r.Error + } + if r.Exit != 0 { + log.Info("git format-patch", repo.FullPath) + log.Info("git format-patch", cmd) + log.Info("git format-patch exit", r.Exit) + return errors.New(fmt.Sprintf("git returned %d", r.Exit)) + } + if len(r.Stdout) == 0 { + // git created no files to add + return nil + } + + return pset.addPatchFiles(repo) +} + +// 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) + fullDir := filepath.Join(tmpDir, psetDir) + var baderr error + filepath.Walk(fullDir, func(path string, info os.FileInfo, err error) error { + if err != nil { + // Handle possible errors, like permission issues + fmt.Fprintf(os.Stderr, "error accessing path %q: %v\n", path, err) + baderr = err + return err + } + + 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) + data, err := os.ReadFile(path) + if err != nil { + log.Info("addPatchFile() failed", path) + baderr = err + return err + } + patch := new(Patch) + patch.Filename, _ = filepath.Rel(p.TmpDir, path) + patch.Data = data + patch.parseData() + patch.StartHash = repo.DevelHash() + p.Patches = append(p.Patches, patch) + log.Info("ADDED PATCH FILE", path) + return nil + }) + return baderr +} + +// looks at the git format-patch output +// saves the commit Hash +// saves the diff lines +func (p *Patch) parseData() string { + lines := strings.Split(string(p.Data), "\n") + for _, line := range lines { + fields := strings.Fields(line) + if len(fields) < 2 { + continue + } + switch fields[0] { + case "From": + p.CommitHash = fields[1] + case "diff": + p.Files = append(p.Files, line) + } + } + return "" +} + +// just an example of how to walk only directories +func onlyWalkDirs(pDir string) error { + log.Info("DIR", pDir) + // var all []string + var baderr error + filepath.WalkDir(pDir, func(path string, d os.DirEntry, err error) error { + if err != nil { + // Handle possible errors, like permission issues + fmt.Fprintf(os.Stderr, "error accessing path %q: %v\n", path, err) + baderr = err + return err + } + + log.Info("TESTING DIR", path) + if d.IsDir() { + return filepath.SkipDir + } + log.Info("NEVER GETS HERE? WHAT IS THIS?", path) + return nil + }) + return baderr +} diff --git a/patchset.Send.go b/patchset.Send.go new file mode 100644 index 0000000..00fe37e --- /dev/null +++ b/patchset.Send.go @@ -0,0 +1,27 @@ +package forgepb + +// functions to import and export the protobuf +// data to and from config files + +import ( + "errors" + "time" + + "go.wit.com/log" +) + +func (f *Forge) SendPatchSet(pset *Patchset) error { + var err error + data, err := pset.Marshal() + if err != nil { + log.Info("proto.Marshal() pset(len) error", len(data), err) + return err + } + now := time.Now() + timestamp := now.Format("2006.01.02.150405") // bummer. other date doesn't work? + cfgfile := "patchset/patchset." + timestamp + ".pb" + log.Info("proto.Marshal() pset(len)", len(data)) + configWrite(cfgfile, data) + + return errors.New("don't know how to send yet") +} diff --git a/patchset.proto b/patchset.proto index afb725a..00b7134 100644 --- a/patchset.proto +++ b/patchset.proto @@ -5,7 +5,7 @@ package forgepb; import "google/protobuf/timestamp.proto"; // Import the well-known type for Timestamp message Patch { - string filename = 1; // `autogenpb:unique` + string filename = 1; // `autogenpb:unique` `autogenpb:sort` bytes data = 2; // string repoPath = 3; // path to the git repo string branchName = 4; // @@ -17,10 +17,10 @@ message Patch { } message Patchset { // `autogenpb:marshal` - repeated Patch Patches = 1; - string name = 2; // + repeated Patch Patches = 1; // + string name = 2; // `autogenpb:sort` string comment = 3; // - string gitAuthorName = 4; // + string gitAuthorName = 4; // `autogenpb:sort` string gitAuthorEmail = 5; // google.protobuf.Timestamp ctime = 6; // create time of this patchset string tmpDir = 7; // temp dir @@ -30,8 +30,8 @@ message Patchset { // `autogenpb:marshal` string endBranchHash = 11; // } -message Patchsets { // `autogenpb:marshal` - string uuid = 1; // `autogenpb:uuid:be926ad9-f07f-484c-adf2-d96eeabf3079` // todo: add autogenpb support for this - string version = 2; // could be used for protobuf schema change violations? +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; } -- cgit v1.2.3