mirror of
https://github.com/lukaszraczylo/harness-sync.git
synced 2026-10-14 00:57:49 +00:00
feat(cli): add update subcommand for in-place self-update
This commit is contained in:
@@ -36,6 +36,7 @@ func main() {
|
|||||||
root.AddCommand(cli.NewProfile(reg))
|
root.AddCommand(cli.NewProfile(reg))
|
||||||
root.AddCommand(cli.NewRollback())
|
root.AddCommand(cli.NewRollback())
|
||||||
root.AddCommand(cli.NewAdapter(reg))
|
root.AddCommand(cli.NewAdapter(reg))
|
||||||
|
root.AddCommand(cli.NewUpdate())
|
||||||
|
|
||||||
if err := root.Execute(); err != nil {
|
if err := root.Execute(); err != nil {
|
||||||
fmt.Fprintln(os.Stderr, err)
|
fmt.Fprintln(os.Stderr, err)
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
package cli
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
const installURL = "https://raw.githubusercontent.com/lukaszraczylo/harness-sync/main/install.sh"
|
||||||
|
|
||||||
|
// NewUpdate returns the `update` subcommand. It downloads and installs the
|
||||||
|
// latest harness-sync release into the same directory the running binary
|
||||||
|
// lives in.
|
||||||
|
func NewUpdate() *cobra.Command {
|
||||||
|
var (
|
||||||
|
dryRun bool
|
||||||
|
dir string
|
||||||
|
)
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "update",
|
||||||
|
Short: "Download and install the latest harness-sync release in place",
|
||||||
|
RunE: func(cmd *cobra.Command, _ []string) error {
|
||||||
|
if dir == "" {
|
||||||
|
exe, err := os.Executable()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("resolve current binary path: %w", err)
|
||||||
|
}
|
||||||
|
resolved, err := filepath.EvalSymlinks(exe)
|
||||||
|
if err == nil {
|
||||||
|
exe = resolved
|
||||||
|
}
|
||||||
|
dir = filepath.Dir(exe)
|
||||||
|
}
|
||||||
|
pipeline := fmt.Sprintf("curl -fsSL %q | INSTALL_DIR=%q bash", installURL, dir)
|
||||||
|
if _, err := fmt.Fprintf(cmd.OutOrStdout(), "Installing latest harness-sync into %s\n", dir); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if dryRun {
|
||||||
|
_, err := fmt.Fprintln(cmd.OutOrStdout(), pipeline)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
sh := exec.Command("/bin/bash", "-c", pipeline)
|
||||||
|
sh.Stdout = cmd.OutOrStdout()
|
||||||
|
sh.Stderr = cmd.ErrOrStderr()
|
||||||
|
return sh.Run()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
cmd.Flags().BoolVar(&dryRun, "dry-run", false, "print the install command without executing it")
|
||||||
|
cmd.Flags().StringVar(&dir, "install-dir", "", "override install directory (default: dir of running binary)")
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package cli
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestUpdateDryRunPrintsCommand(t *testing.T) {
|
||||||
|
cmd := NewUpdate()
|
||||||
|
var buf bytes.Buffer
|
||||||
|
cmd.SetOut(&buf)
|
||||||
|
cmd.SetErr(&buf)
|
||||||
|
cmd.SetArgs([]string{"--dry-run", "--install-dir", "/tmp/test-dir"})
|
||||||
|
require.NoError(t, cmd.Execute())
|
||||||
|
|
||||||
|
out := buf.String()
|
||||||
|
assert.Contains(t, out, "Installing latest harness-sync into /tmp/test-dir")
|
||||||
|
assert.Contains(t, out, "curl -fsSL")
|
||||||
|
assert.Contains(t, out, "install.sh")
|
||||||
|
assert.Contains(t, out, "INSTALL_DIR=")
|
||||||
|
// Should NOT have run anything
|
||||||
|
assert.False(t, strings.Contains(out, "[INFO]"), "dry run must not invoke install.sh")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUpdateResolvesCurrentBinaryDirByDefault(t *testing.T) {
|
||||||
|
cmd := NewUpdate()
|
||||||
|
var buf bytes.Buffer
|
||||||
|
cmd.SetOut(&buf)
|
||||||
|
cmd.SetArgs([]string{"--dry-run"})
|
||||||
|
require.NoError(t, cmd.Execute())
|
||||||
|
|
||||||
|
// Should mention SOME absolute path (the test binary's directory)
|
||||||
|
out := buf.String()
|
||||||
|
assert.Contains(t, out, "Installing latest harness-sync into /")
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user