Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions docs/cli-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,7 @@ Print detailed build information.

### `--update`

Update fetch binary in place.
Update fetch binary in place. Use with `--dry-run` to check for updates without installing.

### `--complete SHELL`

Expand All @@ -469,10 +469,11 @@ fetch --complete fish > ~/.config/fish/completions/fetch.fish

### `--dry-run`

Print request information without sending.
Print request information without sending. When used with `--update`, checks for the latest version without installing.

```sh
fetch --dry-run -m POST -j '{"test": true}' example.com
fetch --update --dry-run
```

## Environment Variables
Expand Down
23 changes: 23 additions & 0 deletions integration/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1191,6 +1191,29 @@ func TestMain(t *testing.T) {
res = runFetch(t, fetchPath, "--version")
assertExitCode(t, 0, res)

// Test dry-run update when already on latest version.
newVersion.Store(&version)
dryRunModTime := getModTime(t, fetchPath)
res = runFetch(t, fetchPath, server.URL, "--update", "--dry-run")
assertExitCode(t, 0, res)
assertBufContains(t, res.stderr, "Already using the latest version")
if !getModTime(t, fetchPath).Equal(dryRunModTime) {
t.Fatal("binary was modified during dry-run update (same version)")
}

// Test dry-run update when a new version is available.
newVersion.Store(&newStr)
dryRunModTime = getModTime(t, fetchPath)
res = runFetch(t, fetchPath, server.URL, "--update", "--dry-run")
assertExitCode(t, 0, res)
assertBufContains(t, res.stderr, "Update available")
assertBufContains(t, res.stderr, newStr)
assertBufNotContains(t, res.stderr, "Updated fetch:")
assertBufNotContains(t, res.stderr, "Downloading")
if !getModTime(t, fetchPath).Equal(dryRunModTime) {
t.Fatal("binary was modified during dry-run update")
}

// Test the auto-update functionality.
res = runFetch(t, fetchPath, "--version", "--auto-update", "0s")
assertExitCode(t, 0, res)
Expand Down
24 changes: 19 additions & 5 deletions internal/update/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ import (

// Update checks the API for the latest fetch version and upgrades the current
// executable in-place, returning the exit code to use.
func Update(ctx context.Context, p *core.Printer, timeout time.Duration, silent bool) int {
err := update(ctx, p, timeout, silent)
func Update(ctx context.Context, p *core.Printer, timeout time.Duration, silent bool, dryRun bool) int {
err := update(ctx, p, timeout, silent, dryRun)
if err == nil {
return 0
}
Expand All @@ -31,7 +31,7 @@ func Update(ctx context.Context, p *core.Printer, timeout time.Duration, silent
return 1
}

func update(ctx context.Context, p *core.Printer, timeout time.Duration, silent bool) error {
func update(ctx context.Context, p *core.Printer, timeout time.Duration, silent bool, dryRun bool) error {
if timeout > 0 {
// Ensure the context is cancelled after the provided timeout.
var cancel context.CancelFunc
Expand Down Expand Up @@ -61,10 +61,10 @@ func update(ctx context.Context, p *core.Printer, timeout time.Duration, silent
}()

// Perform the update.
return updateInner(ctx, p, silent)
return updateInner(ctx, p, silent, dryRun)
}

func updateInner(ctx context.Context, p *core.Printer, silent bool) error {
func updateInner(ctx context.Context, p *core.Printer, silent bool, dryRun bool) error {
c := client.NewClient(client.ClientConfig{})

// Get the current executable path and verify that we have write
Expand Down Expand Up @@ -104,6 +104,20 @@ func updateInner(ctx context.Context, p *core.Printer, silent bool) error {
return nil
}

if dryRun {
if !silent {
p.WriteString("Update available: ")
p.WriteString(version)
p.WriteString(" -> ")
p.Set(core.Bold)
p.WriteString(latest.TagName)
p.Reset()
p.WriteString("\n")
p.Flush()
}
return nil
}

// Look for the artifact URL for our OS and architecture.
artifactURL := getArtifactURL(latest)
if artifactURL == "" {
Expand Down
2 changes: 1 addition & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ func main() {
if app.Update {
p := handle.Stderr()
timeout := getValue(app.Cfg.Timeout)
status := update.Update(ctx, p, timeout, verbosity == core.VSilent)
status := update.Update(ctx, p, timeout, verbosity == core.VSilent, app.DryRun)
os.Exit(status)
}

Expand Down