mirror of
https://github.com/goreleaser/goreleaser.git
synced 2025-02-05 13:15:26 +02:00
feat: Support custom command and extra files in snaps (#1553)
This commit is contained in:
parent
9af64723fc
commit
0c0063a5b4
@ -173,6 +173,21 @@ func create(ctx *context.Context, snap config.Snapcraft, arch string, binaries [
|
||||
return err
|
||||
}
|
||||
|
||||
for _, file := range snap.Files {
|
||||
if file.Destination == "" {
|
||||
file.Destination = file.Source
|
||||
}
|
||||
if file.Mode == 0 {
|
||||
file.Mode = 0644
|
||||
}
|
||||
if err := os.MkdirAll(filepath.Join(primeDir, filepath.Dir(file.Destination)), 0755); err != nil {
|
||||
return errors.Wrapf(err, "failed to link extra file '%s'", file.Source)
|
||||
}
|
||||
if err := link(file.Source, filepath.Join(primeDir, file.Destination), os.FileMode(file.Mode)); err != nil {
|
||||
return errors.Wrapf(err, "failed to link extra file '%s'", file.Source)
|
||||
}
|
||||
}
|
||||
|
||||
var file = filepath.Join(primeDir, "meta", "snap.yaml")
|
||||
log.WithField("file", file).Debug("creating snap metadata")
|
||||
|
||||
@ -231,11 +246,16 @@ func create(ctx *context.Context, snap config.Snapcraft, arch string, binaries [
|
||||
WithField("name", name).
|
||||
Debug("passed binary to snapcraft")
|
||||
|
||||
command := name
|
||||
if config.Command != "" {
|
||||
command = config.Command
|
||||
}
|
||||
|
||||
// TODO: test that the correct binary is used in Command
|
||||
// See https://github.com/goreleaser/goreleaser/pull/1449
|
||||
appMetadata := AppMetadata{
|
||||
Command: strings.TrimSpace(strings.Join([]string{
|
||||
name,
|
||||
command,
|
||||
config.Args,
|
||||
}, " ")),
|
||||
Plugs: config.Plugs,
|
||||
@ -314,3 +334,29 @@ func push(ctx *context.Context, snap *artifact.Artifact) error {
|
||||
ctx.Artifacts.Add(snap)
|
||||
return nil
|
||||
}
|
||||
|
||||
// walks the src, recreating dirs and hard-linking files.
|
||||
func link(src, dest string, mode os.FileMode) error {
|
||||
return filepath.Walk(src, func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// We have the following:
|
||||
// - src = "a/b"
|
||||
// - dest = "dist/linuxamd64/b"
|
||||
// - path = "a/b/c.txt"
|
||||
// So we join "a/b" with "c.txt" and use it as the destination.
|
||||
var dst = filepath.Join(dest, strings.Replace(path, src, "", 1))
|
||||
log.WithFields(log.Fields{
|
||||
"src": path,
|
||||
"dst": dst,
|
||||
}).Debug("extra file")
|
||||
if info.IsDir() {
|
||||
return os.MkdirAll(dst, info.Mode())
|
||||
}
|
||||
if err := os.Link(path, dst); err != nil {
|
||||
return err
|
||||
}
|
||||
return os.Chmod(dst, mode)
|
||||
})
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"syscall"
|
||||
"testing"
|
||||
|
||||
"github.com/goreleaser/goreleaser/internal/artifact"
|
||||
@ -327,6 +328,100 @@ func TestCompleter(t *testing.T) {
|
||||
assert.Equal(t, "testdata/mybin-completer.bash", metadata.Apps["mybin"].Completer)
|
||||
}
|
||||
|
||||
func TestCommand(t *testing.T) {
|
||||
folder, err := ioutil.TempDir("", "archivetest")
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(folder)
|
||||
var dist = filepath.Join(folder, "dist")
|
||||
require.NoError(t, os.Mkdir(dist, 0755))
|
||||
require.NoError(t, err)
|
||||
var ctx = context.New(config.Project{
|
||||
ProjectName: "testprojectname",
|
||||
Dist: dist,
|
||||
Snapcrafts: []config.Snapcraft{
|
||||
{
|
||||
NameTemplate: "foo_{{.Arch}}",
|
||||
Summary: "test summary",
|
||||
Description: "test description",
|
||||
Apps: map[string]config.SnapcraftAppMetadata{
|
||||
"mybin": {
|
||||
Daemon: "simple",
|
||||
Args: "",
|
||||
Command: "custom command",
|
||||
},
|
||||
},
|
||||
Builds: []string{"foo"},
|
||||
},
|
||||
},
|
||||
})
|
||||
ctx.Git.CurrentTag = "v1.2.3"
|
||||
ctx.Version = "v1.2.3"
|
||||
addBinaries(t, ctx, "foo", dist, "mybin")
|
||||
require.NoError(t, Pipe{}.Run(ctx))
|
||||
yamlFile, err := ioutil.ReadFile(filepath.Join(dist, "foo_amd64", "prime", "meta", "snap.yaml"))
|
||||
require.NoError(t, err)
|
||||
var metadata Metadata
|
||||
err = yaml.Unmarshal(yamlFile, &metadata)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "custom command", metadata.Apps["mybin"].Command)
|
||||
}
|
||||
|
||||
func TestExtraFile(t *testing.T) {
|
||||
folder, err := ioutil.TempDir("", "archivetest")
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(folder)
|
||||
var dist = filepath.Join(folder, "dist")
|
||||
require.NoError(t, os.Mkdir(dist, 0755))
|
||||
require.NoError(t, err)
|
||||
var ctx = context.New(config.Project{
|
||||
ProjectName: "testprojectname",
|
||||
Dist: dist,
|
||||
Snapcrafts: []config.Snapcraft{
|
||||
{
|
||||
NameTemplate: "foo_{{.Arch}}",
|
||||
Summary: "test summary",
|
||||
Description: "test description",
|
||||
Apps: map[string]config.SnapcraftAppMetadata{
|
||||
"mybin": {
|
||||
Daemon: "simple",
|
||||
Args: "",
|
||||
Command: "custom command",
|
||||
},
|
||||
},
|
||||
Files: []config.SnapcraftExtraFiles{
|
||||
{
|
||||
Source: "testdata/extra-file.txt",
|
||||
Destination: "a/b/c/extra-file.txt",
|
||||
Mode: 0755,
|
||||
},
|
||||
{
|
||||
Source: "testdata/extra-file-2.txt",
|
||||
},
|
||||
},
|
||||
Builds: []string{"foo"},
|
||||
},
|
||||
},
|
||||
})
|
||||
ctx.Git.CurrentTag = "v1.2.3"
|
||||
ctx.Version = "v1.2.3"
|
||||
addBinaries(t, ctx, "foo", dist, "mybin")
|
||||
require.NoError(t, Pipe{}.Run(ctx))
|
||||
|
||||
srcFile, err := os.Stat("testdata/extra-file.txt")
|
||||
require.NoError(t, err)
|
||||
destFile, err := os.Stat(filepath.Join(dist, "foo_amd64", "prime", "a", "b", "c", "extra-file.txt"))
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, inode(srcFile), inode(destFile))
|
||||
assert.Equal(t, destFile.Mode(), os.FileMode(0755))
|
||||
|
||||
srcFile, err = os.Stat("testdata/extra-file-2.txt")
|
||||
require.NoError(t, err)
|
||||
destFileWithDefaults, err := os.Stat(filepath.Join(dist, "foo_amd64", "prime", "testdata", "extra-file-2.txt"))
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, destFileWithDefaults.Mode(), os.FileMode(0644))
|
||||
assert.Equal(t, inode(srcFile), inode(destFileWithDefaults))
|
||||
}
|
||||
|
||||
func TestDefault(t *testing.T) {
|
||||
var ctx = context.New(config.Project{
|
||||
Builds: []config.Build{
|
||||
@ -439,3 +534,8 @@ func Test_isValidArch(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func inode(info os.FileInfo) uint64 {
|
||||
stat := info.Sys().(*syscall.Stat_t)
|
||||
return stat.Ino
|
||||
}
|
||||
|
1
internal/pipe/snapcraft/testdata/extra-file-2.txt
vendored
Normal file
1
internal/pipe/snapcraft/testdata/extra-file-2.txt
vendored
Normal file
@ -0,0 +1 @@
|
||||
test2
|
1
internal/pipe/snapcraft/testdata/extra-file.txt
vendored
Executable file
1
internal/pipe/snapcraft/testdata/extra-file.txt
vendored
Executable file
@ -0,0 +1 @@
|
||||
test
|
@ -329,6 +329,7 @@ type SnapcraftAppMetadata struct {
|
||||
Daemon string
|
||||
Args string
|
||||
Completer string `yaml:",omitempty"`
|
||||
Command string `yaml:"command"`
|
||||
}
|
||||
|
||||
// Snapcraft config.
|
||||
@ -348,6 +349,15 @@ type Snapcraft struct {
|
||||
Confinement string `yaml:",omitempty"`
|
||||
Apps map[string]SnapcraftAppMetadata `yaml:",omitempty"`
|
||||
Plugs map[string]interface{} `yaml:",omitempty"`
|
||||
|
||||
Files []SnapcraftExtraFiles `yaml:"extra_files,omitempty"`
|
||||
}
|
||||
|
||||
// SnapcraftExtraFiles config.
|
||||
type SnapcraftExtraFiles struct {
|
||||
Source string `yaml:"source"`
|
||||
Destination string `yaml:"destination,omitempty"`
|
||||
Mode uint32 `yaml:"mode,omitempty"`
|
||||
}
|
||||
|
||||
// Snapshot config.
|
||||
|
@ -88,6 +88,16 @@ snapcrafts:
|
||||
# Default is empty.
|
||||
base: core18
|
||||
|
||||
# Add extra files on the resulting snap. Useful for including wrapper
|
||||
# scripts or other useful static files. Source filenames are relative to the
|
||||
# project directory. Destination filenames are relative to the snap prime
|
||||
# directory.
|
||||
# Default is empty.
|
||||
extra_files:
|
||||
- source: drumroll.wrapper
|
||||
destination: bin/drumroll.wrapper
|
||||
mode: 0755
|
||||
|
||||
# Each binary built by GoReleaser is an app inside the snap. In this section
|
||||
# you can declare extra details for those binaries. It is optional.
|
||||
apps:
|
||||
@ -114,6 +124,10 @@ snapcrafts:
|
||||
# https://docs.snapcraft.io/tab-completion-for-snaps.
|
||||
completer: drumroll-completion.bash
|
||||
|
||||
# You can override the command name.
|
||||
# Defaults is the app name.
|
||||
command: bin/drumroll.wrapper
|
||||
|
||||
# Allows plugs to be configured. Plugs like system-files and personal-files
|
||||
# require this.
|
||||
# Default is empty.
|
||||
|
Loading…
x
Reference in New Issue
Block a user