1
0
mirror of https://github.com/goreleaser/goreleaser.git synced 2025-01-10 03:47:03 +02:00
goreleaser/internal/artifact/artifact.go

575 lines
14 KiB
Go
Raw Normal View History

// Package artifact provides the core artifact storage for goreleaser.
package artifact
// nolint: gosec
2017-12-17 20:31:06 +02:00
import (
"bytes"
"crypto/md5"
"crypto/sha1"
2018-08-21 20:55:35 +02:00
"crypto/sha256"
"crypto/sha512"
2018-08-21 20:55:35 +02:00
"encoding/hex"
"encoding/json"
"fmt"
"hash"
"hash/crc32"
2018-08-21 20:55:35 +02:00
"io"
"os"
"path/filepath"
"strings"
2017-12-17 20:31:06 +02:00
"sync"
2017-12-17 20:59:54 +02:00
"github.com/caarlos0/log"
2017-12-17 20:31:06 +02:00
)
// Type defines the type of an artifact.
type Type int
const (
// UploadableArchive a tar.gz/zip archive to be uploaded.
UploadableArchive Type = iota + 1
// UploadableBinary is a binary file to be uploaded.
2017-12-17 20:10:40 +02:00
UploadableBinary
// UploadableFile is any file that can be uploaded.
UploadableFile
// Binary is a binary (output of a gobuild).
Binary
// UniversalBinary is a binary that contains multiple binaries within.
UniversalBinary
// LinuxPackage is a linux package generated by nfpm.
2017-12-17 21:11:08 +02:00
LinuxPackage
// PublishableSnapcraft is a snap package yet to be published.
2018-10-20 19:25:46 +02:00
PublishableSnapcraft
// Snapcraft is a published snap package.
2018-10-20 19:25:46 +02:00
Snapcraft
// PublishableDockerImage is a Docker image yet to be published.
2018-10-20 18:45:31 +02:00
PublishableDockerImage
// DockerImage is a published Docker image.
DockerImage
// DockerManifest is a published Docker manifest.
DockerManifest
// Checksum is a checksums file.
Checksum
// Signature is a signature file.
2017-12-17 21:25:04 +02:00
Signature
// Certificate is a signing certificate file
Certificate
// UploadableSourceArchive is the archive with the current commit source code.
UploadableSourceArchive
feat: improve output and pipe skipping (#2480) * refactor: improve middleware Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: upload tests Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: twitter tests Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: source tests Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: snapshot tests Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * test: improved some tests Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: snapcraft skip Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip slack Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip sign Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip scoop Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip reddit Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip discord Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip publish Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip nfpm Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip milestone Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip custompublishers Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip checksums Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip changelog Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip brew Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip blob Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip before Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip artifactory Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip announce Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip defaults Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: cmds Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip docker Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * chore: todo Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: go.mod Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip release Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: remove old skip pipe errors Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip teams Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip brew Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix/test: skip smtp Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: lint issues Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip docker Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip brew and scoop Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip docker Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip http/artifactory Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * test: increase coverage Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * test: fix Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com>
2021-09-18 15:21:29 +02:00
// BrewTap is an uploadable homebrew tap recipe file.
BrewTap
// Nixpkg is an uploadable nix package.
Nixpkg
// WingetInstaller winget installer file.
WingetInstaller
// WingetDefaultLocale winget default locale file.
WingetDefaultLocale
// WingetVersion winget version file.
WingetVersion
feat: arch user repository integration (#2838) * feat: aur PKGBUILD integration Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * feat: guess install, improve formatting Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: more deterministic Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * feat: binary releases, push, more tests Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * feat: accept key as text Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * feat: improvements Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * feat: srcinfo Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: compile Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: everything Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: lint Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * feat: renames, docs, etc Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * docs: link to docs Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: go mod tidy, title Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: srcinfo tmpl Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: missing close quote Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: templates Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: always defaults conflicts and provides Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: ssh command Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: maintainers can be a list Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: ensure -bin suffix, more tests and docs Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: this will never happen Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: whitespaces Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: goreleaser config Signed-off-by: Carlos A Becker <caarlos0@gmail.com>
2022-01-20 19:59:39 +02:00
// PkgBuild is an Arch Linux AUR PKGBUILD file.
PkgBuild
// SrcInfo is an Arch Linux AUR .SRCINFO file.
SrcInfo
// KrewPluginManifest is a krew plugin manifest file.
KrewPluginManifest
feat: improve output and pipe skipping (#2480) * refactor: improve middleware Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: upload tests Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: twitter tests Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: source tests Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: snapshot tests Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * test: improved some tests Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: snapcraft skip Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip slack Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip sign Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip scoop Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip reddit Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip discord Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip publish Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip nfpm Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip milestone Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip custompublishers Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip checksums Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip changelog Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip brew Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip blob Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip before Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip artifactory Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip announce Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip defaults Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: cmds Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip docker Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * chore: todo Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: go.mod Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip release Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: remove old skip pipe errors Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip teams Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip brew Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix/test: skip smtp Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: lint issues Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip docker Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip brew and scoop Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip docker Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip http/artifactory Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * test: increase coverage Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * test: fix Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com>
2021-09-18 15:21:29 +02:00
// ScoopManifest is an uploadable scoop manifest file.
ScoopManifest
// SBOM is a Software Bill of Materials file.
SBOM
// PublishableChocolatey is a chocolatey package yet to be published.
PublishableChocolatey
// Header is a C header file, generated for CGo library builds.
Header
// CArchive is a C static library, generated via a CGo build with buildmode=c-archive.
CArchive
// CShared is a C shared library, generated via a CGo build with buildmode=c-shared.
CShared
)
2018-09-15 23:53:59 +02:00
func (t Type) String() string {
switch t {
case UploadableArchive:
return "Archive"
case UploadableFile:
return "File"
case UploadableBinary, Binary, UniversalBinary:
2018-09-15 23:53:59 +02:00
return "Binary"
case LinuxPackage:
2018-10-20 18:45:31 +02:00
return "Linux Package"
feat: add digest to artifacts info of published docker images (#3540) Extract the digest (sha256) of docker images from the `docker push` command for dockers published to the docker registry. Outputting the digest is required to avoid a race condition when referencing the image, where the image tag is being modified before the reference is done. See this [blog post](https://github.com/goreleaser/goreleaser/issues/3496) for more info. This PR fixes https://github.com/goreleaser/goreleaser/issues/3496. Note that the 'publish' pipe now must run before the 'metadata' pipe, so that the information extracted during the 'publish' pipe would appear in the metadata. Previously, the published docker images metadata wasn't printed (because of the order). It made sense because the content of the published image was just a subset of the local one. Now that it is printed to the metadata, it should have a different name to avoid confusion. As I mentioned, it wasn't printed before - so there shouldn't be any backward-compatibility issues. --- Local tests: ``` go test -v . === RUN TestVersion === RUN TestVersion/only_version === RUN TestVersion/version_and_date === RUN TestVersion/version,_date,_built_by === RUN TestVersion/all_empty === RUN TestVersion/complete --- PASS: TestVersion (0.00s) --- PASS: TestVersion/only_version (0.00s) --- PASS: TestVersion/version_and_date (0.00s) --- PASS: TestVersion/version,_date,_built_by (0.00s) --- PASS: TestVersion/all_empty (0.00s) --- PASS: TestVersion/complete (0.00s) PASS ok github.com/goreleaser/goreleaser 0.764s ``` Output example: ``` { "name": "gallegit/hello-world:latest", "path": "gallegit/hello-world:latest", "goos": "linux", "goarch": "amd64", "internal_type": 10, "type": "Published Docker Image", "extra": { "digest": "sha256:c3f7dd196a046dc061236d3c6ae1e2946269e90da30b0a959240ca799750e632" } } ``` Signed-off-by: Carlos A Becker <caarlos0@users.noreply.github.com> Co-authored-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>
2022-11-12 19:51:53 +02:00
case PublishableDockerImage:
2018-10-20 18:45:31 +02:00
return "Docker Image"
feat: add digest to artifacts info of published docker images (#3540) Extract the digest (sha256) of docker images from the `docker push` command for dockers published to the docker registry. Outputting the digest is required to avoid a race condition when referencing the image, where the image tag is being modified before the reference is done. See this [blog post](https://github.com/goreleaser/goreleaser/issues/3496) for more info. This PR fixes https://github.com/goreleaser/goreleaser/issues/3496. Note that the 'publish' pipe now must run before the 'metadata' pipe, so that the information extracted during the 'publish' pipe would appear in the metadata. Previously, the published docker images metadata wasn't printed (because of the order). It made sense because the content of the published image was just a subset of the local one. Now that it is printed to the metadata, it should have a different name to avoid confusion. As I mentioned, it wasn't printed before - so there shouldn't be any backward-compatibility issues. --- Local tests: ``` go test -v . === RUN TestVersion === RUN TestVersion/only_version === RUN TestVersion/version_and_date === RUN TestVersion/version,_date,_built_by === RUN TestVersion/all_empty === RUN TestVersion/complete --- PASS: TestVersion (0.00s) --- PASS: TestVersion/only_version (0.00s) --- PASS: TestVersion/version_and_date (0.00s) --- PASS: TestVersion/version,_date,_built_by (0.00s) --- PASS: TestVersion/all_empty (0.00s) --- PASS: TestVersion/complete (0.00s) PASS ok github.com/goreleaser/goreleaser 0.764s ``` Output example: ``` { "name": "gallegit/hello-world:latest", "path": "gallegit/hello-world:latest", "goos": "linux", "goarch": "amd64", "internal_type": 10, "type": "Published Docker Image", "extra": { "digest": "sha256:c3f7dd196a046dc061236d3c6ae1e2946269e90da30b0a959240ca799750e632" } } ``` Signed-off-by: Carlos A Becker <caarlos0@users.noreply.github.com> Co-authored-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>
2022-11-12 19:51:53 +02:00
case DockerImage:
return "Published Docker Image"
case DockerManifest:
return "Docker Manifest"
case PublishableSnapcraft, Snapcraft:
return "Snap"
2018-09-15 23:53:59 +02:00
case Checksum:
return "Checksum"
case Signature:
return "Signature"
case Certificate:
return "Certificate"
case UploadableSourceArchive:
return "Source"
feat: improve output and pipe skipping (#2480) * refactor: improve middleware Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: upload tests Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: twitter tests Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: source tests Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: snapshot tests Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * test: improved some tests Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: snapcraft skip Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip slack Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip sign Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip scoop Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip reddit Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip discord Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip publish Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip nfpm Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip milestone Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip custompublishers Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip checksums Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip changelog Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip brew Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip blob Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip before Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip artifactory Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip announce Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip defaults Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: cmds Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip docker Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * chore: todo Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: go.mod Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip release Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: remove old skip pipe errors Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip teams Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip brew Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix/test: skip smtp Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: lint issues Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip docker Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip brew and scoop Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip docker Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip http/artifactory Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * test: increase coverage Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * test: fix Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com>
2021-09-18 15:21:29 +02:00
case BrewTap:
return "Brew Tap"
case KrewPluginManifest:
return "Krew Plugin Manifest"
feat: improve output and pipe skipping (#2480) * refactor: improve middleware Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: upload tests Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: twitter tests Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: source tests Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: snapshot tests Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * test: improved some tests Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: snapcraft skip Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip slack Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip sign Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip scoop Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip reddit Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip discord Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip publish Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip nfpm Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip milestone Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip custompublishers Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip checksums Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip changelog Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip brew Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip blob Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip before Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip artifactory Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip announce Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip defaults Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: cmds Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip docker Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * chore: todo Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: go.mod Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip release Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: remove old skip pipe errors Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip teams Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip brew Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix/test: skip smtp Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: lint issues Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip docker Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip brew and scoop Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip docker Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip http/artifactory Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * test: increase coverage Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * test: fix Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com>
2021-09-18 15:21:29 +02:00
case ScoopManifest:
return "Scoop Manifest"
case SBOM:
return "SBOM"
feat: arch user repository integration (#2838) * feat: aur PKGBUILD integration Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * feat: guess install, improve formatting Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: more deterministic Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * feat: binary releases, push, more tests Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * feat: accept key as text Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * feat: improvements Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * feat: srcinfo Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: compile Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: everything Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: lint Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * feat: renames, docs, etc Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * docs: link to docs Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: go mod tidy, title Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: srcinfo tmpl Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: missing close quote Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: templates Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: always defaults conflicts and provides Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: ssh command Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: maintainers can be a list Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: ensure -bin suffix, more tests and docs Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: this will never happen Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: whitespaces Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: goreleaser config Signed-off-by: Carlos A Becker <caarlos0@gmail.com>
2022-01-20 19:59:39 +02:00
case PkgBuild:
return "PKGBUILD"
case SrcInfo:
return "SRCINFO"
case PublishableChocolatey:
return "Chocolatey"
case Header:
return "C Header"
case CArchive:
return "C Archive Library"
case CShared:
return "C Shared Library"
case WingetInstaller, WingetDefaultLocale, WingetVersion:
return "Winget Manifest"
default:
return "unknown"
2018-09-15 23:53:59 +02:00
}
}
const (
ExtraID = "ID"
ExtraBinary = "Binary"
ExtraExt = "Ext"
ExtraBuilds = "Builds" // deprecated
ExtraFormat = "Format"
ExtraWrappedIn = "WrappedIn"
ExtraBinaries = "Binaries"
ExtraRefresh = "Refresh"
ExtraReplaces = "Replaces"
ExtraDigest = "Digest"
ExtraSize = "Size"
)
// Extras represents the extra fields in an artifact.
type Extras map[string]any
func (e Extras) MarshalJSON() ([]byte, error) {
m := map[string]any{}
for k, v := range e {
if k == ExtraRefresh {
// refresh is a func, so we can't serialize it.
continue
}
m[k] = v
}
return json.Marshal(m)
}
// Artifact represents an artifact and its relevant info.
type Artifact struct {
Name string `json:"name,omitempty"`
Path string `json:"path,omitempty"`
Goos string `json:"goos,omitempty"`
Goarch string `json:"goarch,omitempty"`
Goarm string `json:"goarm,omitempty"`
Gomips string `json:"gomips,omitempty"`
Goamd64 string `json:"goamd64,omitempty"`
Type Type `json:"internal_type,omitempty"`
TypeS string `json:"type,omitempty"`
Extra Extras `json:"extra,omitempty"`
}
func (a Artifact) String() string {
return a.Name
}
// Extra tries to get the extra field with the given name, returning either
// its value, the default value for its type, or an error.
//
// If the extra value cannot be cast into the given type, it'll try to convert
// it to JSON and unmarshal it into the correct type after.
//
// If that fails as well, it'll error.
func Extra[T any](a Artifact, key string) (T, error) {
ex := a.Extra[key]
if ex == nil {
return *(new(T)), nil
}
t, ok := ex.(T)
if ok {
return t, nil
}
bts, err := json.Marshal(ex)
if err != nil {
return t, err
}
decoder := json.NewDecoder(bytes.NewReader(bts))
decoder.DisallowUnknownFields()
err = decoder.Decode(&t)
return t, err
}
// ExtraOr returns the Extra field with the given key or the or value specified
// if it is nil.
func ExtraOr[T any](a Artifact, key string, or T) T {
if a.Extra[key] == nil {
return or
}
return a.Extra[key].(T)
}
// Checksum calculates the checksum of the artifact.
// nolint: gosec
func (a Artifact) Checksum(algorithm string) (string, error) {
log.Debugf("calculating checksum for %s", a.Path)
2018-08-21 20:55:35 +02:00
file, err := os.Open(a.Path)
if err != nil {
return "", fmt.Errorf("failed to checksum: %w", err)
2018-08-21 20:55:35 +02:00
}
defer file.Close()
var h hash.Hash
switch algorithm {
case "crc32":
h = crc32.NewIEEE()
case "md5":
h = md5.New()
case "sha224":
h = sha256.New224()
case "sha384":
h = sha512.New384()
case "sha256":
h = sha256.New()
case "sha1":
h = sha1.New()
case "sha512":
h = sha512.New()
default:
return "", fmt.Errorf("invalid algorithm: %s", algorithm)
}
feat: improve output and pipe skipping (#2480) * refactor: improve middleware Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: upload tests Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: twitter tests Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: source tests Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: snapshot tests Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * test: improved some tests Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: snapcraft skip Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip slack Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip sign Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip scoop Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip reddit Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip discord Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip publish Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip nfpm Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip milestone Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip custompublishers Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip checksums Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip changelog Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip brew Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip blob Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip before Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip artifactory Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip announce Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip defaults Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: cmds Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip docker Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * chore: todo Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: go.mod Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip release Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: remove old skip pipe errors Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip teams Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip brew Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix/test: skip smtp Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: lint issues Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip docker Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip brew and scoop Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip docker Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * fix: skip http/artifactory Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * test: increase coverage Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * test: fix Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com>
2021-09-18 15:21:29 +02:00
if _, err := io.Copy(h, file); err != nil {
return "", fmt.Errorf("failed to checksum: %w", err)
2018-08-21 20:55:35 +02:00
}
return hex.EncodeToString(h.Sum(nil)), nil
2018-08-21 20:55:35 +02:00
}
var noRefresh = func() error { return nil }
// Refresh executes a Refresh extra function on artifacts, if it exists.
func (a Artifact) Refresh() error {
// for now lets only do it for checksums, as we know for a fact that
// they are the only ones that support this right now.
if a.Type != Checksum {
return nil
}
if err := ExtraOr(a, ExtraRefresh, noRefresh)(); err != nil {
return fmt.Errorf("failed to refresh %q: %w", a.Name, err)
}
return nil
}
// ID returns the artifact ID if it exists, empty otherwise.
func (a Artifact) ID() string {
return ExtraOr(a, ExtraID, "")
}
// Format returns the artifact Format if it exists, empty otherwise.
func (a Artifact) Format() string {
return ExtraOr(a, ExtraFormat, "")
}
// Artifacts is a list of artifacts.
type Artifacts struct {
items []*Artifact
lock *sync.Mutex
}
// New return a new list of artifacts.
func New() *Artifacts {
return &Artifacts{
items: []*Artifact{},
lock: &sync.Mutex{},
}
}
// List return the actual list of artifacts.
func (artifacts *Artifacts) List() []*Artifact {
artifacts.lock.Lock()
defer artifacts.lock.Unlock()
2017-12-17 19:50:09 +02:00
return artifacts.items
}
feat: arch user repository integration (#2838) * feat: aur PKGBUILD integration Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * feat: guess install, improve formatting Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: more deterministic Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * feat: binary releases, push, more tests Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * feat: accept key as text Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * feat: improvements Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * feat: srcinfo Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: compile Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: everything Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: lint Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * feat: renames, docs, etc Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * docs: link to docs Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: go mod tidy, title Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: srcinfo tmpl Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: missing close quote Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: templates Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: always defaults conflicts and provides Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: ssh command Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: maintainers can be a list Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: ensure -bin suffix, more tests and docs Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: this will never happen Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: whitespaces Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: goreleaser config Signed-off-by: Carlos A Becker <caarlos0@gmail.com>
2022-01-20 19:59:39 +02:00
// GroupByID groups the artifacts by their ID.
func (artifacts *Artifacts) GroupByID() map[string][]*Artifact {
feat: arch user repository integration (#2838) * feat: aur PKGBUILD integration Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * feat: guess install, improve formatting Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: more deterministic Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * feat: binary releases, push, more tests Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * feat: accept key as text Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * feat: improvements Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * feat: srcinfo Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: compile Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: everything Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: lint Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * feat: renames, docs, etc Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * docs: link to docs Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: go mod tidy, title Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: srcinfo tmpl Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: missing close quote Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: templates Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: always defaults conflicts and provides Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: ssh command Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: maintainers can be a list Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: ensure -bin suffix, more tests and docs Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: this will never happen Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: whitespaces Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: goreleaser config Signed-off-by: Carlos A Becker <caarlos0@gmail.com>
2022-01-20 19:59:39 +02:00
result := map[string][]*Artifact{}
for _, a := range artifacts.List() {
2022-01-24 04:49:40 +02:00
id := a.ID()
if id == "" {
continue
}
feat: arch user repository integration (#2838) * feat: aur PKGBUILD integration Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * feat: guess install, improve formatting Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: more deterministic Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * feat: binary releases, push, more tests Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * feat: accept key as text Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * feat: improvements Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * feat: srcinfo Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: compile Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: everything Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: lint Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * feat: renames, docs, etc Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * docs: link to docs Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: go mod tidy, title Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: srcinfo tmpl Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: missing close quote Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: templates Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: always defaults conflicts and provides Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: ssh command Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: maintainers can be a list Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: ensure -bin suffix, more tests and docs Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: this will never happen Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: whitespaces Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: goreleaser config Signed-off-by: Carlos A Becker <caarlos0@gmail.com>
2022-01-20 19:59:39 +02:00
result[a.ID()] = append(result[a.ID()], a)
}
return result
}
// GroupByPlatform groups the artifacts by their platform.
func (artifacts *Artifacts) GroupByPlatform() map[string][]*Artifact {
result := map[string][]*Artifact{}
for _, a := range artifacts.List() {
plat := a.Goos + a.Goarch + a.Goarm + a.Gomips + a.Goamd64
2017-12-18 13:19:02 +02:00
result[plat] = append(result[plat], a)
2017-12-17 19:50:09 +02:00
}
return result
}
func relPath(a *Artifact) (string, error) {
cwd, err := os.Getwd()
if err != nil {
return "", err
}
if !strings.HasPrefix(a.Path, cwd) {
return "", nil
}
return filepath.Rel(cwd, a.Path)
}
func shouldRelPath(a *Artifact) bool {
switch a.Type {
case DockerImage, DockerManifest, PublishableDockerImage:
return false
default:
return filepath.IsAbs(a.Path)
}
}
// Add safely adds a new artifact to an artifact list.
func (artifacts *Artifacts) Add(a *Artifact) {
artifacts.lock.Lock()
defer artifacts.lock.Unlock()
if shouldRelPath(a) {
rel, err := relPath(a)
if rel != "" && err == nil {
a.Path = rel
}
}
log.WithField("name", a.Name).
WithField("type", a.Type).
WithField("path", a.Path).
Debug("added new artifact")
artifacts.items = append(artifacts.items, a)
}
// Remove removes artifacts that match the given filter from the original artifact list.
func (artifacts *Artifacts) Remove(filter Filter) error {
if filter == nil {
return nil
}
artifacts.lock.Lock()
defer artifacts.lock.Unlock()
result := New()
for _, a := range artifacts.items {
if filter(a) {
log.WithField("name", a.Name).
WithField("type", a.Type).
WithField("path", a.Path).
Debug("removing")
} else {
result.items = append(result.items, a)
}
}
artifacts.items = result.items
return nil
}
// Filter defines an artifact filter which can be used within the Filter
// function.
type Filter func(a *Artifact) bool
// OnlyReplacingUnibins removes universal binaries that did not replace the single-arch ones.
//
// This is useful specially on homebrew et al, where you'll want to use only either the single-arch or the universal binaries.
func OnlyReplacingUnibins(a *Artifact) bool {
return ExtraOr(*a, ExtraReplaces, true)
}
// ByGoos is a predefined filter that filters by the given goos.
func ByGoos(s string) Filter {
return func(a *Artifact) bool {
return a.Goos == s
}
}
// ByGoarch is a predefined filter that filters by the given goarch.
func ByGoarch(s string) Filter {
return func(a *Artifact) bool {
return a.Goarch == s
}
}
// ByGoarm is a predefined filter that filters by the given goarm.
func ByGoarm(s string) Filter {
return func(a *Artifact) bool {
return a.Goarm == s
}
}
// ByGoamd64 is a predefined filter that filters by the given goamd64.
func ByGoamd64(s string) Filter {
return func(a *Artifact) bool {
return a.Goamd64 == s
}
}
// ByType is a predefined filter that filters by the given type.
func ByType(t Type) Filter {
return func(a *Artifact) bool {
return a.Type == t
}
}
// ByFormats filters artifacts by a `Format` extra field.
func ByFormats(formats ...string) Filter {
filters := make([]Filter, 0, len(formats))
for _, format := range formats {
format := format
filters = append(filters, func(a *Artifact) bool {
return a.Format() == format
})
}
return Or(filters...)
}
// ByIDs filter artifacts by an `ID` extra field.
func ByIDs(ids ...string) Filter {
filters := make([]Filter, 0, len(ids))
for _, id := range ids {
id := id
filters = append(filters, func(a *Artifact) bool {
// checksum and source archive are always for all artifacts, so return always true.
return a.Type == Checksum ||
a.Type == UploadableSourceArchive ||
a.ID() == id
})
}
return Or(filters...)
}
// ByExt filter artifact by their 'Ext' extra field.
func ByExt(exts ...string) Filter {
filters := make([]Filter, 0, len(exts))
for _, ext := range exts {
ext := ext
filters = append(filters, func(a *Artifact) bool {
return ExtraOr(*a, ExtraExt, "") == ext
})
}
return Or(filters...)
}
// ByBinaryLikeArtifacts filter artifacts down to artifacts that are Binary, UploadableBinary, or UniversalBinary,
// deduplicating artifacts by path (preferring UploadableBinary over all others). Note: this filter is unique in the
// sense that it cannot act in isolation of the state of other artifacts; the filter requires the whole list of
// artifacts in advance to perform deduplication.
func ByBinaryLikeArtifacts(arts *Artifacts) Filter {
// find all of the paths for any uploadable binary artifacts
uploadableBins := arts.Filter(ByType(UploadableBinary)).List()
uploadableBinPaths := map[string]struct{}{}
for _, a := range uploadableBins {
uploadableBinPaths[a.Path] = struct{}{}
}
// we want to keep any matching artifact that is not a binary that already has a path accounted for
// by another uploadable binary. We always prefer uploadable binary artifacts over binary artifacts.
deduplicateByPath := func(a *Artifact) bool {
if a.Type == UploadableBinary {
return true
}
_, ok := uploadableBinPaths[a.Path]
return !ok
}
return And(
// allow all of the binary-like artifacts as possible...
Or(
ByType(Binary),
ByType(UploadableBinary),
ByType(UniversalBinary),
),
// ... but remove any duplicates found
deduplicateByPath,
)
}
// Or performs an OR between all given filters.
2017-12-17 20:59:54 +02:00
func Or(filters ...Filter) Filter {
return func(a *Artifact) bool {
2017-12-17 20:59:54 +02:00
for _, f := range filters {
if f(a) {
return true
}
}
return false
}
}
// And performs an AND between all given filters.
2017-12-17 20:59:54 +02:00
func And(filters ...Filter) Filter {
return func(a *Artifact) bool {
2017-12-17 20:59:54 +02:00
for _, f := range filters {
if !f(a) {
return false
}
}
return true
}
}
// Filter filters the artifact list, returning a new instance.
// There are some pre-defined filters but anything of the Type Filter
// is accepted.
2017-12-17 20:59:54 +02:00
// You can compose filters by using the And and Or filters.
func (artifacts *Artifacts) Filter(filter Filter) *Artifacts {
if filter == nil {
return artifacts
}
result := New()
for _, a := range artifacts.List() {
2017-12-17 20:59:54 +02:00
if filter(a) {
2017-12-17 22:01:58 +02:00
result.items = append(result.items, a)
}
}
return result
}
// Paths returns the artifact.Path of the current artifact list.
func (artifacts *Artifacts) Paths() []string {
var result []string
for _, artifact := range artifacts.List() {
result = append(result, artifact.Path)
}
return result
}
// VisitFn is a function that can be executed against each artifact in a list.
type VisitFn func(a *Artifact) error
// Visit executes the given function for each artifact in the list.
func (artifacts *Artifacts) Visit(fn VisitFn) error {
for _, artifact := range artifacts.List() {
if err := fn(artifact); err != nil {
return err
}
}
return nil
}