1
1
mirror of https://github.com/goreleaser/nfpm synced 2024-11-19 03:25:08 +01:00
nfpm/files/files.go
Carlos Alexandro Becker 17af87eda2
fix: race condition and remove unused code (#273)
* refactor: small code improvements

Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com>

* refactor: small code improvements

Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com>

* fix: test

Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com>

* test: race condition

Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com>

* fix: race

Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com>

* test: fix invalid file

Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com>

* docs: fix synlinks/indent

Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com>

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2020-12-30 19:15:16 +00:00

163 lines
3.8 KiB
Go

package files
import (
"os"
"path/filepath"
"sort"
"time"
"github.com/goreleaser/fileglob"
"github.com/goreleaser/nfpm/v2/internal/glob"
)
// Content describes the source and destination
// of one file to copy into a package.
type Content struct {
Source string `yaml:"src,omitempty"`
Destination string `yaml:"dst,omitempty"`
Type string `yaml:"type,omitempty"`
Packager string `yaml:"packager,omitempty"`
FileInfo *ContentFileInfo `yaml:"file_info,omitempty"`
}
type ContentFileInfo struct {
Owner string `yaml:"owner,omitempty"`
Group string `yaml:"group"`
Mode os.FileMode `yaml:"mode,omitempty"`
MTime time.Time `yaml:"mtime,omitempty"`
Size int64 `yaml:"-"`
}
// Contents list of Content to process.
type Contents []*Content
func (c Contents) Len() int {
return len(c)
}
func (c Contents) Swap(i, j int) {
c[i], c[j] = c[j], c[i]
}
func (c Contents) Less(i, j int) bool {
a, b := c[i], c[j]
if a.Type != b.Type {
return len(a.Type) < len(b.Type)
}
if a.Source != b.Source {
return a.Source < b.Source
}
return a.Destination < b.Destination
}
func (c *Content) WithFileInfoDefaults() *Content {
var cc = &Content{
Source: c.Source,
Destination: c.Destination,
Type: c.Type,
Packager: c.Packager,
FileInfo: c.FileInfo,
}
if cc.FileInfo == nil {
cc.FileInfo = &ContentFileInfo{}
}
if cc.FileInfo.Owner == "" {
cc.FileInfo.Owner = "root"
}
if cc.FileInfo.Group == "" {
cc.FileInfo.Group = "root"
}
info, err := os.Stat(cc.Source)
if err == nil {
cc.FileInfo.MTime = info.ModTime()
cc.FileInfo.Mode = info.Mode()
cc.FileInfo.Size = info.Size()
}
if cc.FileInfo.MTime.IsZero() {
cc.FileInfo.MTime = time.Now().UTC()
}
return cc
}
// Name to part of the os.FileInfo interface
func (c *Content) Name() string {
return c.Source
}
// Size to part of the os.FileInfo interface
func (c *Content) Size() int64 {
return c.FileInfo.Size
}
// Mode to part of the os.FileInfo interface
func (c *Content) Mode() os.FileMode {
return c.FileInfo.Mode
}
// ModTime to part of the os.FileInfo interface
func (c *Content) ModTime() time.Time {
return c.FileInfo.MTime
}
// IsDir to part of the os.FileInfo interface
func (c *Content) IsDir() bool {
return false
}
// Sys to part of the os.FileInfo interface
func (c *Content) Sys() interface{} {
return nil
}
// ExpandContentGlobs gathers all of the real files to be copied into the package.
func ExpandContentGlobs(filesSrcDstMap Contents, disableGlobbing bool) (files Contents, err error) {
for _, f := range filesSrcDstMap {
var globbed map[string]string
if disableGlobbing {
f.Source = fileglob.QuoteMeta(f.Source)
}
switch f.Type {
case "ghost", "symlink":
// Ghost and symlink files need to be in the list, but dont glob them because they do not really exist
files = append(files, f.WithFileInfoDefaults())
continue
}
globbed, err = glob.Glob(f.Source, f.Destination)
if err != nil {
return nil, err
}
files = appendGlobbedFiles(globbed, f, files)
}
// sort the files for reproducibility and general cleanliness
sort.Sort(files)
return files, nil
}
func appendGlobbedFiles(globbed map[string]string, origFile *Content, incFiles Contents) (files Contents) {
files = append(files, incFiles...)
for src, dst := range globbed {
newFile := &Content{
Destination: ToNixPath(dst),
Source: ToNixPath(src),
Type: origFile.Type,
FileInfo: origFile.FileInfo,
Packager: origFile.Packager,
}
files = append(files, newFile.WithFileInfoDefaults())
}
return files
}
// ToNixPath converts the given path to a nix-style path.
//
// Windows-style path separators are considered escape
// characters by some libraries, which can cause issues.
func ToNixPath(path string) string {
return filepath.ToSlash(filepath.Clean(path))
}