github.com/benchkram/bob@v0.0.0-20240314204020-b7a57f2f9be9/bobtask/buildinfo/buildinfo.go (about) 1 package buildinfo 2 3 import ( 4 "bytes" 5 "fmt" 6 "sort" 7 8 "github.com/benchkram/bob/bobtask/buildinfo/protos" 9 ) 10 11 type I struct { 12 // Meta holds data about the creator/origin of this object. 13 Meta Meta 14 15 // Target aggregates buildinfos of multiple files or docker images 16 Target Targets 17 } 18 19 func New() *I { 20 return &I{ 21 Target: MakeTargets(), 22 } 23 } 24 25 func (i *I) Describe() string { 26 buf := bytes.NewBufferString("") 27 28 fmt.Fprintln(buf, "Meta:") 29 fmt.Fprintln(buf, "\ttask:", i.Meta.Task) 30 fmt.Fprintln(buf, "\tinput hash", i.Meta.InputHash) 31 32 fmt.Fprintln(buf, "Filesystem-Targets:") 33 fmt.Fprintln(buf, "\thash of all files", i.Target.Filesystem.Hash) 34 fmt.Fprintln(buf, "\t# of files", len(i.Target.Filesystem.Files)) 35 fmt.Fprintln(buf, "\tfiles:") 36 37 sortedFiles := []string{} 38 for filename := range i.Target.Filesystem.Files { 39 sortedFiles = append(sortedFiles, filename) 40 } 41 sort.Strings(sortedFiles) 42 43 for _, filename := range sortedFiles { 44 v := i.Target.Filesystem.Files[filename] 45 fmt.Fprintln(buf, "\t", filename, v.Size, v.Hash) 46 } 47 48 return buf.String() 49 } 50 51 type Targets struct { 52 Filesystem BuildInfoFiles `yaml:"file"` 53 Docker map[string]BuildInfoDocker `yaml:"docker"` 54 } 55 56 func NewTargets() *Targets { 57 return &Targets{ 58 Filesystem: MakeBuildInfoFiles(), 59 Docker: make(map[string]BuildInfoDocker), 60 } 61 } 62 63 func MakeTargets() Targets { 64 return *NewTargets() 65 } 66 67 type BuildInfoFiles struct { 68 // Hash contains the hash of all files 69 Hash string `yaml:"hash"` 70 // Files contains modtime & size of each file 71 Files map[string]BuildInfoFile `yaml:"file"` 72 } 73 74 func NewBuildInfoFiles() *BuildInfoFiles { 75 return &BuildInfoFiles{ 76 Files: make(map[string]BuildInfoFile), 77 } 78 } 79 func MakeBuildInfoFiles() BuildInfoFiles { 80 return *NewBuildInfoFiles() 81 } 82 83 type BuildInfoFile struct { 84 // Size of a file 85 Size int64 `yaml:"size"` 86 // Hash of file contents 87 Hash string `yaml:"hash"` 88 } 89 90 type BuildInfoDocker struct { 91 Hash string `yaml:"hash"` 92 } 93 94 // Creator information 95 type Meta struct { 96 // Task usually the taskname 97 Task string `yaml:"task"` 98 99 // InputHash used for target creation 100 InputHash string `yaml:"input_hash"` 101 } 102 103 func (i *I) ToProto(inputHash string) *protos.BuildInfo { 104 filesystem := &protos.BuildInfoFiles{ 105 Targets: make(map[string]*protos.BuildInfoFile, len(i.Target.Filesystem.Files)), 106 } 107 filesystem.Hash = i.Target.Filesystem.Hash 108 for k, v := range i.Target.Filesystem.Files { 109 filesystem.Targets[k] = &protos.BuildInfoFile{Size: v.Size, Hash: v.Hash} 110 } 111 112 docker := make(map[string]*protos.BuildInfoDocker) 113 for k, v := range i.Target.Docker { 114 docker[k] = &protos.BuildInfoDocker{Hash: v.Hash} 115 } 116 117 return &protos.BuildInfo{ 118 Meta: &protos.Meta{ 119 Task: i.Meta.Task, 120 InputHash: inputHash, 121 }, 122 Target: &protos.Targets{ 123 Filesystem: filesystem, 124 Docker: docker, 125 }, 126 } 127 } 128 129 func FromProto(p *protos.BuildInfo) *I { 130 if p == nil { 131 return nil 132 } 133 134 bi := New() 135 136 if p.Meta != nil { 137 bi.Meta.Task = p.Meta.Task 138 bi.Meta.InputHash = p.Meta.InputHash 139 } 140 141 if p.Target != nil { 142 if p.Target.Filesystem != nil { 143 bi.Target.Filesystem.Hash = p.Target.Filesystem.Hash 144 for k, v := range p.Target.Filesystem.Targets { 145 bi.Target.Filesystem.Files[k] = BuildInfoFile{Size: v.Size, Hash: v.Hash} 146 } 147 } 148 149 for k, v := range p.Target.Docker { 150 bi.Target.Docker[k] = BuildInfoDocker{Hash: v.Hash} 151 } 152 } 153 154 return bi 155 }