From 44caec2e7fc59697ef01835aacf8a03171a42bea Mon Sep 17 00:00:00 2001 From: Jeff Carr Date: Tue, 26 Nov 2024 05:34:26 -0600 Subject: [PATCH] take a stab at a protobuf for the go deps --- Makefile | 7 ++- godep.proto | 21 +++++++ godep.sort.go | 149 ++++++++++++++++++++++++++++++++++++++++++++++++++ refs.sort.go | 41 ++------------ 4 files changed, 181 insertions(+), 37 deletions(-) create mode 100644 godep.proto create mode 100644 godep.sort.go diff --git a/Makefile b/Makefile index fb5d194..191b07b 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ # go install -all: refs.pb.go vet +all: refs.pb.go godep.pb.go vet vet: lint GO111MODULE=off go vet @@ -31,3 +31,8 @@ refs.pb.go: refs.proto cd ~/go/src && protoc --go_out=. --proto_path=go.wit.com/lib/protobuf/gitpb \ --go_opt=Mrefs.proto=go.wit.com/lib/protobuf/gitpb \ refs.proto + +godep.pb.go: godep.proto + cd ~/go/src && protoc --go_out=. --proto_path=go.wit.com/lib/protobuf/gitpb \ + --go_opt=Mgodep.proto=go.wit.com/lib/protobuf/gitpb \ + godep.proto diff --git a/godep.proto b/godep.proto new file mode 100644 index 0000000..3b4333b --- /dev/null +++ b/godep.proto @@ -0,0 +1,21 @@ +syntax = "proto3"; + +// store go dependancies + +package gitpb; + +import "google/protobuf/timestamp.proto"; // Import the well-known type for Timestamp + +message GoDep { + string hash = 1; // 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 + string goPath = 4; // "go.wit.com/lib/foo" + string goVersion = 5; // version of golang the developer used to make this package version +} + +message GoDeps { + 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; +} diff --git a/godep.sort.go b/godep.sort.go new file mode 100644 index 0000000..edba531 --- /dev/null +++ b/godep.sort.go @@ -0,0 +1,149 @@ +package gitpb + +// this is becoming a standard format +// todo: autogenerate this from the .proto file? + +import ( + "fmt" + "os" + "sort" + sync "sync" + "time" +) + +// bad global lock until I figure out some other plan +var godeplock sync.RWMutex + +type GoDepIterator struct { + sync.RWMutex + + packs []*GoDep + index int +} + +// NewGoDepGoDepIterator initializes a new iterator. +func NewGoDepIterator(packs []*GoDep) *GoDepIterator { + return &GoDepIterator{packs: packs} +} + +// Scan moves to the next element and returns false if there are no more packs. +func (it *GoDepIterator) Scan() bool { + if it.index >= len(it.packs) { + return false + } + it.index++ + return true +} + +// GoDep returns the current repo. +func (it *GoDepIterator) GoDep() *GoDep { + if it.packs[it.index-1] == nil { + for i, d := range it.packs { + fmt.Println("i =", i, d) + } + fmt.Println("len =", len(it.packs)) + fmt.Println("repo == nil", it.index, it.index-1) + os.Exit(-1) + } + return it.packs[it.index-1] +} + +// Use Scan() in a loop, similar to a while loop +// +// for iterator.Scan() { +// d := iterator.GoDep() +// fmt.Println("GoDep UUID:", d.Uuid) +// } + +func (r *GoDeps) All() *GoDepIterator { + repoPointers := r.selectAllGoDeps() + + iterator := NewGoDepIterator(repoPointers) + return iterator +} + +func (r *GoDeps) SortByName() *GoDepIterator { + packs := r.selectAllGoDeps() + + sort.Sort(GoDepByPath(packs)) + + iterator := NewGoDepIterator(packs) + return iterator +} + +// enforces no duplicate package names +func (r *GoDeps) Append(newP *GoDep) bool { + refslock.Lock() + defer refslock.Unlock() + + for _, p := range r.GoDeps { + if p.GoPath == newP.GoPath { + return false + } + } + + r.GoDeps = append(r.GoDeps, newP) + return true +} + +// returns time.Duration since last Update() +func (r *GoDep) Age(newP *GoDep) time.Duration { + t := time.Since(r.Ctime.AsTime()) + return t +} + +// find a dependancy by the go path +func (r *GoDeps) FindByPath(gopath string) *GoDep { + refslock.RLock() + defer refslock.RUnlock() + + for _, p := range r.GoDeps { + if p.GoPath == gopath { + return p + } + } + + return nil +} + +func (r *GoDeps) Len() int { + refslock.RLock() + defer refslock.RUnlock() + + return len(r.GoDeps) +} + +type GoDepByPath []*GoDep + +func (a GoDepByPath) Len() int { return len(a) } +func (a GoDepByPath) Less(i, j int) bool { return a[i].GoPath < a[j].GoPath } +func (a GoDepByPath) Swap(i, j int) { a[i], a[j] = a[j], a[i] } + +// safely returns a slice of pointers to the GoDep protobufs +func (r *GoDeps) selectAllGoDeps() []*GoDep { + refslock.RLock() + defer refslock.RUnlock() + + // Create a new slice to hold pointers to each GoDep + var allPacks []*GoDep + allPacks = make([]*GoDep, len(r.GoDeps)) + for i, p := range r.GoDeps { + allPacks[i] = p // Copy pointers for safe iteration + } + + return allPacks +} + +func (all *GoDeps) DeleteByHash(hash string) *GoDep { + refslock.Lock() + defer refslock.Unlock() + + for i, _ := range all.GoDeps { + if all.GoDeps[i].Hash == hash { + all.GoDeps[i] = all.GoDeps[len(all.GoDeps)-1] + all.GoDeps = all.GoDeps[:len(all.GoDeps)-1] + return nil + } + } + return nil +} diff --git a/refs.sort.go b/refs.sort.go index 8d8a9ea..94d3124 100644 --- a/refs.sort.go +++ b/refs.sort.go @@ -65,7 +65,7 @@ func (r *Refs) All() *RefIterator { func (r *Refs) SortByName() *RefIterator { packs := r.selectAllRefs() - sort.Sort(ByName(packs)) + sort.Sort(RefsByName(packs)) iterator := NewRefIterator(packs) return iterator @@ -113,11 +113,11 @@ func (r *Refs) Len() int { return len(r.Refs) } -type ByName []*Ref +type RefsByName []*Ref -func (a ByName) Len() int { return len(a) } -func (a ByName) Less(i, j int) bool { return a[i].RefName < a[j].RefName } -func (a ByName) Swap(i, j int) { a[i], a[j] = a[j], a[i] } +func (a RefsByName) Len() int { return len(a) } +func (a RefsByName) Less(i, j int) bool { return a[i].RefName < a[j].RefName } +func (a RefsByName) Swap(i, j int) { a[i], a[j] = a[j], a[i] } // safely returns a slice of pointers to the Ref protobufs func (r *Refs) selectAllRefs() []*Ref { @@ -147,34 +147,3 @@ func (all *Refs) DeleteByHash(hash string) *Ref { } return nil } - -/* -func (r *Refs) UnmergedRefRepos() *RefRepoIterator { - repoPointers := r.selectUnmergedRefRepos() - - sort.Sort(ByName(repoPointers)) - - iterator := NewRefRepoIterator(repoPointers) - - return iterator -} -*/ - -/* -// this sort doesn't really work. I think it forgets to sort the last two -// todo: sort this out. literally -// SelectRefPointers safely returns a slice of pointers to Ref records. -func (r *Refs) selectUnmergedRefs() []*RefRow { - r.RLock() - defer r.RUnlock() - - // Create a new slice to hold pointers to each Ref - // repoPointers := make([]*Ref, len(c.E.Refs)) - var repoPointers []*RefRow - for _, repo := range me.allrepos { - repoPointers = append(repoPointers, repo) // Copy pointers for safe iteration - } - - return repoPointers -} -*/