Skip to content

Commit 2734802

Browse files
committed
Allow configuring a name for the archived binary
This will default to the existing behavior: using the name of the currently running executable. Fixes #42
1 parent 04a545f commit 2734802

3 files changed

Lines changed: 72 additions & 16 deletions

File tree

selfupdate/update.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@ import (
1515
"github.com/inconshreveable/go-update"
1616
)
1717

18-
func uncompressAndUpdate(src io.Reader, assetURL, cmdPath string) error {
19-
_, cmd := filepath.Split(cmdPath)
20-
asset, err := UncompressCommand(src, assetURL, cmd)
18+
func uncompressAndUpdate(src io.Reader, assetURL, cmdPath string, binaryName string) error {
19+
if binaryName == "" {
20+
_, binaryName = filepath.Split(cmdPath)
21+
}
22+
asset, err := UncompressCommand(src, assetURL, binaryName)
2123
if err != nil {
2224
return err
2325
}
@@ -76,7 +78,7 @@ func (up *Updater) UpdateTo(rel *Release, cmdPath string) error {
7678
}
7779

7880
if up.validator == nil {
79-
return uncompressAndUpdate(bytes.NewReader(data), rel.AssetURL, cmdPath)
81+
return uncompressAndUpdate(bytes.NewReader(data), rel.AssetURL, cmdPath, up.binaryName)
8082
}
8183

8284
validationSrc, validationRedirectURL, err := up.api.Repositories.DownloadReleaseAsset(up.apiCtx, rel.RepoOwner, rel.RepoName, rel.ValidationAssetID, &client)
@@ -102,7 +104,7 @@ func (up *Updater) UpdateTo(rel *Release, cmdPath string) error {
102104
return fmt.Errorf("Failed validating asset content: %v", err)
103105
}
104106

105-
return uncompressAndUpdate(bytes.NewReader(data), rel.AssetURL, cmdPath)
107+
return uncompressAndUpdate(bytes.NewReader(data), rel.AssetURL, cmdPath, up.binaryName)
106108
}
107109

108110
// UpdateCommand updates a given command binary to the latest version.
@@ -165,7 +167,7 @@ func UpdateTo(assetURL, cmdPath string) error {
165167
return err
166168
}
167169
defer src.Close()
168-
return uncompressAndUpdate(src, assetURL, cmdPath)
170+
return uncompressAndUpdate(src, assetURL, cmdPath, up.binaryName)
169171
}
170172

171173
// UpdateCommand updates a given command binary to the latest version.

selfupdate/update_test.go

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,29 @@ import (
1111
"github.com/blang/semver"
1212
)
1313

14-
func setupTestBinary() {
15-
if err := exec.Command("go", "build", "./testdata/github-release-test/").Run(); err != nil {
14+
func setupTestBinary(name ...string) {
15+
var options []string
16+
if len(name) == 0 {
17+
options = []string{"build", "./testdata/github-release-test/"}
18+
} else {
19+
options = []string{"build", "-o", name[0], "./testdata/github-release-test/"}
20+
}
21+
22+
if err := exec.Command("go", options...).Run(); err != nil {
1623
panic(err)
1724
}
1825
}
1926

20-
func teardownTestBinary() {
21-
bin := "github-release-test"
27+
func teardownTestBinary(name ...string) {
28+
var bin string
29+
if len(name) == 0 {
30+
bin = "github-release-test"
31+
} else {
32+
bin = name[0]
33+
}
34+
2235
if runtime.GOOS == "windows" {
23-
bin = "github-release-test.exe"
36+
bin += ".exe"
2437
}
2538
if err := os.Remove(bin); err != nil {
2639
panic(err)
@@ -64,6 +77,41 @@ func TestUpdateCommand(t *testing.T) {
6477
}
6578
}
6679

80+
func TestUpdateWithDifferentBinaryName(t *testing.T) {
81+
setupTestBinary("gh-release-test")
82+
defer teardownTestBinary("gh-release-test")
83+
latest := semver.MustParse("1.2.3")
84+
prev := semver.MustParse("1.2.2")
85+
86+
_, err := UpdateCommand("gh-release-test", prev, "rhysd-test/test-release-zip")
87+
if err == nil {
88+
t.Fatal("Error should occur for broken package")
89+
}
90+
if !strings.Contains(err.Error(), "the command is not found") {
91+
t.Fatal("Unexpected error:", err)
92+
}
93+
94+
up, err := NewUpdater(Config{BinaryName: "github-release-test", Filters: []string{"github-release-test"}})
95+
if err != nil {
96+
t.Fatal(err)
97+
}
98+
rel, err := up.UpdateCommand("gh-release-test", prev, "rhysd-test/test-release-zip")
99+
if err != nil {
100+
t.Fatal(err)
101+
}
102+
if rel.Version.NE(latest) {
103+
t.Error("Version is not latest", rel.Version)
104+
}
105+
bytes, err := exec.Command(filepath.FromSlash("./gh-release-test")).Output()
106+
if err != nil {
107+
t.Fatal("Failed to run test binary after update:", err)
108+
}
109+
out := string(bytes)
110+
if out != "v1.2.3\n" {
111+
t.Error("Output from test binary after update is unexpected:", out)
112+
}
113+
}
114+
67115
func TestUpdateViaSymlink(t *testing.T) {
68116
if testing.Short() {
69117
t.Skip("skip tests in short mode.")

selfupdate/updater.go

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,11 @@ import (
1515
// Updater is responsible for managing the context of self-update.
1616
// It contains GitHub client and its context.
1717
type Updater struct {
18-
api *github.Client
19-
apiCtx context.Context
20-
validator Validator
21-
filters []*regexp.Regexp
18+
api *github.Client
19+
apiCtx context.Context
20+
validator Validator
21+
filters []*regexp.Regexp
22+
binaryName string
2223
}
2324

2425
// Config represents the configuration of self-update.
@@ -37,6 +38,10 @@ type Config struct {
3738
// An asset is selected if it matches any of those, in addition to the regular tag, os, arch, extensions.
3839
// Please make sure that your filter(s) uniquely match an asset.
3940
Filters []string
41+
42+
// BinaryName represents the name of the binary extracted from the archive downloaded from GitHub.
43+
// If unset, the current executable's name will be used to match.
44+
BinaryName string
4045
}
4146

4247
func newHTTPClient(ctx context.Context, token string) *http.Client {
@@ -82,7 +87,8 @@ func NewUpdater(config Config) (*Updater, error) {
8287
if err != nil {
8388
return nil, err
8489
}
85-
return &Updater{api: client, apiCtx: ctx, validator: config.Validator, filters: filtersRe}, nil
90+
91+
return &Updater{api: client, apiCtx: ctx, validator: config.Validator, filters: filtersRe, binaryName: config.BinaryName}, nil
8692
}
8793

8894
// DefaultUpdater creates a new updater instance with default configuration.

0 commit comments

Comments
 (0)