You've already forked go-semantic-release
180 lines
3.9 KiB
Go
180 lines
3.9 KiB
Go
package assets
|
|
|
|
import (
|
|
"archive/zip"
|
|
"crypto/md5"
|
|
"crypto/sha1"
|
|
"crypto/sha256"
|
|
"crypto/sha512"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"hash"
|
|
"hash/crc32"
|
|
"io"
|
|
"io/ioutil"
|
|
"os"
|
|
"path"
|
|
"path/filepath"
|
|
|
|
"github.com/Nightapes/go-semantic-release/pkg/config"
|
|
"github.com/pkg/errors"
|
|
log "github.com/sirupsen/logrus"
|
|
)
|
|
|
|
// Asset struct
|
|
type Asset struct {
|
|
name string
|
|
path string
|
|
zippedPath string
|
|
algorithm string
|
|
isCompressed bool
|
|
}
|
|
|
|
//NewAsset from a config
|
|
func NewAsset(repository string, assetConfig config.Asset, algorithm string) (*Asset, error) {
|
|
|
|
filePath := assetConfig.Path
|
|
if assetConfig.Name != "" && assetConfig.Path == "" {
|
|
filePath = assetConfig.Name
|
|
log.Warn("Name is deprecated. Please update your config. See https://nightapes.github.io/go-semantic-release/")
|
|
}
|
|
|
|
realPath := path.Join(repository, filePath)
|
|
|
|
file, err := os.Open(realPath)
|
|
if err != nil {
|
|
file.Close()
|
|
return nil, errors.Wrapf(err, "Could not open file %s", realPath)
|
|
}
|
|
defer file.Close()
|
|
|
|
name := assetConfig.Rename
|
|
if assetConfig.Rename == "" {
|
|
info, _ := file.Stat()
|
|
name = info.Name()
|
|
}
|
|
|
|
asset := &Asset{
|
|
path: realPath,
|
|
name: name,
|
|
isCompressed: assetConfig.Compress,
|
|
algorithm: algorithm,
|
|
}
|
|
|
|
return asset, nil
|
|
}
|
|
|
|
func (a *Asset) getChecksum() (string, error) {
|
|
path, err := a.GetPath()
|
|
if err != nil {
|
|
return "", nil
|
|
}
|
|
log.Debugf("Calculating checksum for %s", path)
|
|
file, err := os.Open(path)
|
|
if err != nil {
|
|
return "", errors.Wrapf(err, "Failed to open file %s to calculate checksum", a.name)
|
|
}
|
|
defer file.Close() // nolint: errcheck
|
|
var hash hash.Hash
|
|
switch a.algorithm {
|
|
case "crc32":
|
|
hash = crc32.NewIEEE()
|
|
case "md5":
|
|
hash = md5.New()
|
|
case "sha1":
|
|
hash = sha1.New()
|
|
case "sha224":
|
|
hash = sha256.New224()
|
|
case "sha384":
|
|
hash = sha512.New384()
|
|
case "sha256":
|
|
hash = sha256.New()
|
|
case "sha512":
|
|
hash = sha512.New()
|
|
default:
|
|
hash = sha256.New()
|
|
}
|
|
_, err = io.Copy(hash, file)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return hex.EncodeToString(hash.Sum(nil)), nil
|
|
}
|
|
|
|
// GetPath where the file is located, if zipped true, it will compress it and give you the new location
|
|
func (a *Asset) GetPath() (string, error) {
|
|
if a.isCompressed {
|
|
return a.ZipFile()
|
|
}
|
|
return a.path, nil
|
|
}
|
|
|
|
// GetName of asset
|
|
func (a *Asset) GetName() string {
|
|
if a.isCompressed {
|
|
return fmt.Sprintf("%s.zip", a.name)
|
|
}
|
|
return a.name
|
|
}
|
|
|
|
// IsCompressed return true if file was zipped
|
|
func (a *Asset) IsCompressed() bool {
|
|
return a.isCompressed
|
|
}
|
|
|
|
// ZipFile compress given file in zip format
|
|
func (a *Asset) ZipFile() (string, error) {
|
|
|
|
if a.zippedPath != "" {
|
|
return a.zippedPath, nil
|
|
}
|
|
|
|
path := a.path
|
|
fileToZip, err := os.Open(path)
|
|
if err != nil {
|
|
return "", errors.Wrapf(err, "Could not open file %s", path)
|
|
}
|
|
defer fileToZip.Close()
|
|
|
|
zipFile, err := ioutil.TempFile(os.TempDir(), "asset.*.zip")
|
|
|
|
if err != nil {
|
|
return "", errors.Wrap(err, "Could not generate tmp file")
|
|
}
|
|
log.Debugf("Created zipfile %s", zipFile.Name())
|
|
|
|
fileToZipInfo, err := fileToZip.Stat()
|
|
if err != nil {
|
|
return "", errors.Wrap(err, "Could not read file infos")
|
|
}
|
|
|
|
zipWriter := zip.NewWriter(zipFile)
|
|
|
|
fileToZipHeader, err := zip.FileInfoHeader(fileToZipInfo)
|
|
if err != nil {
|
|
return "", errors.Wrap(err, "Could not add file infos to zip handler")
|
|
}
|
|
|
|
fileToZipHeader.Name = fileToZipInfo.Name()
|
|
|
|
fileToZipWriter, err := zipWriter.CreateHeader(fileToZipHeader)
|
|
if err != nil {
|
|
return "", errors.Wrap(err, "Could not create zip header")
|
|
}
|
|
|
|
if _, err = io.Copy(fileToZipWriter, fileToZip); err != nil {
|
|
return "", errors.Wrap(err, "Could not zip file")
|
|
}
|
|
|
|
if err := zipWriter.Close(); err != nil {
|
|
return "", errors.Wrap(err, fmt.Sprintf("Could not close zipwriter for zip %s", a.path))
|
|
}
|
|
|
|
if err := zipFile.Close(); err != nil {
|
|
return "", errors.Wrap(err, "Could not close file")
|
|
}
|
|
a.zippedPath, err = filepath.Abs(zipFile.Name())
|
|
|
|
return a.zippedPath, err
|
|
}
|