github.com/abergmeier/buildkit_ex@v0.0.0-20220613202848-1145f3866588/pkg/digest/digest.go (about) 1 package digest 2 3 import ( 4 "fmt" 5 "io" 6 "os" 7 "strings" 8 "sync" 9 10 "crypto/sha512" 11 12 "github.com/abergmeier/buildkit_ex/internal" 13 internalio "github.com/abergmeier/buildkit_ex/internal/io" 14 "github.com/abergmeier/buildkit_ex/pkg/digest/options" 15 "github.com/moby/buildkit/frontend/dockerfile/instructions" 16 ) 17 18 type sourceContentWithIndex struct { 19 i int 20 sc instructions.SourceContent 21 } 22 23 func DigestOfFileAndAllInputs(filename string, opts ...options.Option) ([sha512.Size]byte, error) { 24 25 digest := [sha512.Size]byte{} 26 27 dt, err := os.ReadFile(filename) 28 if err != nil { 29 return digest, fmt.Errorf("Reading Containerfile failed: %w", err) 30 } 31 32 filesToHash := make(chan internalio.OpenedFile, 1024) 33 var herr error 34 digestReady := sync.WaitGroup{} 35 digestReady.Add(1) 36 go func() { 37 defer digestReady.Done() 38 var h []byte 39 h, herr = hashFiles(filesToHash) 40 if herr != nil { 41 return 42 } 43 copy(digest[:], h) 44 }() 45 46 filesToHash <- internalio.OpenedFile{ 47 LateReader: func() (io.ReadCloser, error) { 48 return io.NopCloser(strings.NewReader(string(dt))), nil 49 }, 50 Filename: filename, 51 } 52 53 rf := &internal.ReferencedFiles{} 54 55 for _, opt := range opts { 56 opt.InitReferencedFiles(rf) 57 } 58 59 err = rf.CollectSortedFileHashes(dt, filesToHash) 60 if err != nil { 61 return digest, err 62 } 63 64 close(filesToHash) 65 66 digestReady.Wait() 67 return digest, herr 68 } 69 70 func hashFiles(files <-chan internalio.OpenedFile) (sum []byte, firstErr error) { 71 hash := sha512.New() 72 73 for f := range files { 74 reader, err := f.LateReader() 75 if err != nil { 76 break 77 } 78 _, err = io.Copy(hash, reader) 79 reader.Close() 80 if err != nil { 81 break 82 } 83 } 84 85 sum = hash.Sum(nil) 86 return 87 }