github.phpd.cn/goreleaser/goreleaser@v0.92.0/internal/artifact/artifact.go (about)

     1  // Package artifact provides the core artifact storage for goreleaser
     2  package artifact
     3  
     4  import (
     5  	"crypto/sha256"
     6  	"encoding/hex"
     7  	"io"
     8  	"os"
     9  	"sync"
    10  
    11  	"github.com/apex/log"
    12  	"github.com/pkg/errors"
    13  )
    14  
    15  // Type defines the type of an artifact
    16  type Type int
    17  
    18  const (
    19  	// UploadableArchive a tar.gz/zip archive to be uploaded
    20  	UploadableArchive Type = iota
    21  	// UploadableBinary is a binary file to be uploaded
    22  	UploadableBinary
    23  	// Binary is a binary (output of a gobuild)
    24  	Binary
    25  	// LinuxPackage is a linux package generated by nfpm
    26  	LinuxPackage
    27  	// PublishableSnapcraft is a snap package yet to be published
    28  	PublishableSnapcraft
    29  	// Snapcraft is a published snap package
    30  	Snapcraft
    31  	// PublishableDockerImage is a Docker image yet to be published
    32  	PublishableDockerImage
    33  	// DockerImage is a published Docker image
    34  	DockerImage
    35  	// Checksum is a checksums file
    36  	Checksum
    37  	// Signature is a signature file
    38  	Signature
    39  )
    40  
    41  func (t Type) String() string {
    42  	switch t {
    43  	case UploadableArchive:
    44  		return "Archive"
    45  	case UploadableBinary:
    46  	case Binary:
    47  		return "Binary"
    48  	case LinuxPackage:
    49  		return "Linux Package"
    50  	case DockerImage:
    51  	case PublishableDockerImage:
    52  		return "Docker Image"
    53  	case Checksum:
    54  		return "Checksum"
    55  	case Signature:
    56  		return "Signature"
    57  	}
    58  	return "unknown"
    59  }
    60  
    61  // Artifact represents an artifact and its relevant info
    62  type Artifact struct {
    63  	Name   string
    64  	Path   string
    65  	Goos   string
    66  	Goarch string
    67  	Goarm  string
    68  	Type   Type
    69  	Extra  map[string]string
    70  }
    71  
    72  // Checksum calculates the SHA256 checksum of the artifact.
    73  func (a Artifact) Checksum() (string, error) {
    74  	log.Debugf("calculating sha256sum for %s", a.Path)
    75  	file, err := os.Open(a.Path)
    76  	if err != nil {
    77  		return "", errors.Wrap(err, "failed to checksum")
    78  	}
    79  	defer file.Close() // nolint: errcheck
    80  	var hash = sha256.New()
    81  	_, err = io.Copy(hash, file)
    82  	if err != nil {
    83  		return "", errors.Wrap(err, "failed to checksum")
    84  	}
    85  	return hex.EncodeToString(hash.Sum(nil)), nil
    86  }
    87  
    88  // Artifacts is a list of artifacts
    89  type Artifacts struct {
    90  	items []Artifact
    91  	lock  *sync.Mutex
    92  }
    93  
    94  // New return a new list of artifacts
    95  func New() Artifacts {
    96  	return Artifacts{
    97  		items: []Artifact{},
    98  		lock:  &sync.Mutex{},
    99  	}
   100  }
   101  
   102  // List return the actual list of artifacts
   103  func (artifacts Artifacts) List() []Artifact {
   104  	return artifacts.items
   105  }
   106  
   107  // GroupByPlatform groups the artifacts by their platform
   108  func (artifacts Artifacts) GroupByPlatform() map[string][]Artifact {
   109  	var result = map[string][]Artifact{}
   110  	for _, a := range artifacts.items {
   111  		plat := a.Goos + a.Goarch + a.Goarm
   112  		result[plat] = append(result[plat], a)
   113  	}
   114  	return result
   115  }
   116  
   117  // Add safely adds a new artifact to an artifact list
   118  func (artifacts *Artifacts) Add(a Artifact) {
   119  	artifacts.lock.Lock()
   120  	defer artifacts.lock.Unlock()
   121  	log.WithFields(log.Fields{
   122  		"name": a.Name,
   123  		"path": a.Path,
   124  		"type": a.Type,
   125  	}).Debug("added new artifact")
   126  	artifacts.items = append(artifacts.items, a)
   127  }
   128  
   129  // Filter defines an artifact filter which can be used within the Filter
   130  // function
   131  type Filter func(a Artifact) bool
   132  
   133  // ByGoos is a predefined filter that filters by the given goos
   134  func ByGoos(s string) Filter {
   135  	return func(a Artifact) bool {
   136  		return a.Goos == s
   137  	}
   138  }
   139  
   140  // ByGoarch is a predefined filter that filters by the given goarch
   141  func ByGoarch(s string) Filter {
   142  	return func(a Artifact) bool {
   143  		return a.Goarch == s
   144  	}
   145  }
   146  
   147  // ByGoarm is a predefined filter that filters by the given goarm
   148  func ByGoarm(s string) Filter {
   149  	return func(a Artifact) bool {
   150  		return a.Goarm == s
   151  	}
   152  }
   153  
   154  // ByType is a predefined filter that filters by the given type
   155  func ByType(t Type) Filter {
   156  	return func(a Artifact) bool {
   157  		return a.Type == t
   158  	}
   159  }
   160  
   161  // Or performs an OR between all given filters
   162  func Or(filters ...Filter) Filter {
   163  	return func(a Artifact) bool {
   164  		for _, f := range filters {
   165  			if f(a) {
   166  				return true
   167  			}
   168  		}
   169  		return false
   170  	}
   171  }
   172  
   173  // And performs an AND between all given filters
   174  func And(filters ...Filter) Filter {
   175  	return func(a Artifact) bool {
   176  		for _, f := range filters {
   177  			if !f(a) {
   178  				return false
   179  			}
   180  		}
   181  		return true
   182  	}
   183  }
   184  
   185  // Filter filters the artifact list, returning a new instance.
   186  // There are some pre-defined filters but anything of the Type Filter
   187  // is accepted.
   188  // You can compose filters by using the And and Or filters.
   189  func (artifacts *Artifacts) Filter(filter Filter) Artifacts {
   190  	var result = New()
   191  	for _, a := range artifacts.items {
   192  		if filter(a) {
   193  			result.items = append(result.items, a)
   194  		}
   195  	}
   196  	return result
   197  }