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  }