github.com/Benchkram/bob@v0.0.0-20220321080157-7c8f3876e225/bobtask/artifact_inspect.go (about) 1 package bobtask 2 3 import ( 4 "archive/tar" 5 "context" 6 "errors" 7 "fmt" 8 "io" 9 "io/fs" 10 "io/ioutil" 11 "strings" 12 13 "github.com/Benchkram/bob/bobtask/hash" 14 "github.com/Benchkram/bob/pkg/usererror" 15 "github.com/Benchkram/errz" 16 "github.com/mholt/archiver/v3" 17 "gopkg.in/yaml.v3" 18 ) 19 20 var ErrArtifactDoesNotExist = fmt.Errorf("artifact does not exist") 21 22 func (t *Task) ArtifactInspect(artifactNames ...hash.In) (ai ArtifactInfo, err error) { 23 24 var artifactName hash.In 25 if len(artifactNames) > 0 { 26 artifactName = artifactNames[0] 27 } else { 28 artifactName, err = t.HashIn() 29 errz.Fatal(err) 30 } 31 32 artifact, err := t.local.GetArtifact(context.TODO(), artifactName.String()) 33 if err != nil { 34 _, ok := err.(*fs.PathError) 35 if ok { 36 return ai, usererror.Wrap(ErrArtifactDoesNotExist) 37 } 38 errz.Fatal(err) 39 } 40 defer artifact.Close() 41 42 archiveReader := newArchiveReader() 43 err = archiveReader.Open(artifact, 0) 44 errz.Fatal(err) 45 defer archiveReader.Close() 46 47 info, err := artifactInspect(archiveReader) 48 errz.Fatal(err) 49 50 return info, nil 51 } 52 53 // ArtifactInspectFromPath opens a artifact from a io reader and returns 54 // a string containing compact information about a target. 55 func ArtifactInspectFromReader(reader io.ReadCloser) (_ ArtifactInfo, err error) { 56 defer errz.Recover(&err) 57 58 archiveReader := newArchiveReader() 59 err = archiveReader.Open(reader, 0) 60 errz.Fatal(err) 61 defer archiveReader.Close() 62 63 return artifactInspect(archiveReader) 64 } 65 66 func artifactInspect(archiveReader archiver.Reader) (_ *artifactInfo, err error) { 67 defer errz.Recover(&err) 68 69 info := newArtifactInfo() 70 for { 71 archiveFile, err := archiveReader.Read() 72 if err != nil { 73 if errors.Is(err, io.EOF) { 74 break 75 } 76 errz.Fatal(err) 77 } 78 79 header, ok := archiveFile.Header.(*tar.Header) 80 if !ok { 81 return nil, ErrInvalidTarHeaderType 82 } 83 84 if strings.HasPrefix(header.Name, __targets) { 85 info.targets = append(info.targets, header.Name) 86 } else if strings.HasPrefix(header.Name, __metadata) { 87 bin, err := ioutil.ReadAll(archiveFile) 88 errz.Fatal(err) 89 90 metadata := NewArtifactMetadata() 91 err = yaml.Unmarshal(bin, metadata) 92 errz.Fatal(err) 93 94 info.metadata = metadata 95 } 96 97 } 98 99 return info, nil 100 }