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
20 changes: 16 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,13 @@ brew install brevdev/homebrew-brev/brev
### Linux

```bash
sudo bash -c "$(curl -fsSL https://raw.githubusercontent.com/brevdev/brev-cli/main/bin/install-latest.sh)"
curl -fsSL https://raw.githubusercontent.com/brevdev/brev-cli/main/bin/install-latest.sh | bash
```

Installs to `~/.local/bin`. If it's not on your `PATH`, add this to your shell profile:

```bash
export PATH="$HOME/.local/bin:$PATH"
```

### Windows
Expand All @@ -27,10 +33,16 @@ Brev is supported on windows currently through the Windows Subsystem for Linux (
- Virtualization enabled in your BIOS
- Ubuntu >=22.04 installed from the Microsoft Store

Once you have WSL installed and configured, you can install Brev by running the following command in your terminal:
Once WSL is set up, install Brev with:

```bash
sudo bash -c "$(curl -fsSL https://raw.githubusercontent.com/brevdev/brev-cli/main/bin/install-latest.sh)"
```bash
curl -fsSL https://raw.githubusercontent.com/brevdev/brev-cli/main/bin/install-latest.sh | bash
```

Installs to `~/.local/bin`. If it's not on your `PATH`, add this to your shell profile:

```bash
export PATH="$HOME/.local/bin:$PATH"
```

### From conda-forge
Expand Down
21 changes: 17 additions & 4 deletions bin/install-latest.sh
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,21 @@ trap 'rm -rf "${TMP_DIR}"' EXIT
curl -sL "${DOWNLOAD_URL}" -o "${TMP_DIR}/brev.tar.gz"
tar -xzf "${TMP_DIR}/brev.tar.gz" -C "${TMP_DIR}"

# Install the binary to system location
sudo mv "${TMP_DIR}/brev" /usr/local/bin/brev
sudo chmod +x /usr/local/bin/brev
# Install the binary to the user's local bin
INSTALL_DIR="${HOME}/.local/bin"
mkdir -p "${INSTALL_DIR}"
mv "${TMP_DIR}/brev" "${INSTALL_DIR}/brev"
chmod +x "${INSTALL_DIR}/brev"

echo "Successfully installed brev CLI to /usr/local/bin/brev"
echo "Successfully installed brev CLI to ${INSTALL_DIR}/brev"

case ":${PATH}:" in
*":${INSTALL_DIR}:"*) ;;
*)
echo
echo "Warning: ${INSTALL_DIR} is not in your PATH." >&2
echo "Add it by appending the following line to your shell profile (e.g. ~/.bashrc, ~/.zshrc):" >&2
echo " export PATH=\"\${HOME}/.local/bin:\${PATH}\"" >&2
echo "Then restart your shell or run 'source' on the profile to pick up the change." >&2
;;
esac
2 changes: 1 addition & 1 deletion pkg/cmd/upgrade/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func (SystemUpgrader) UpgradeViaBrew(t *terminal.Terminal) error {
return nil
}

// UpgradeViaInstallScript runs the upstream install-latest.sh script via sudo.
// UpgradeViaInstallScript runs the upstream install-latest.sh script.
func (SystemUpgrader) UpgradeViaInstallScript(t *terminal.Terminal) error {
t.Vprintf("Running: bash -c \"$(curl -fsSL %s)\"\n", installScriptURL)
t.Vprint("")
Expand Down
39 changes: 33 additions & 6 deletions pkg/cmd/upgrade/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ package upgrade
import (
"fmt"
"os"
"path/filepath"

"github.com/brevdev/brev-cli/pkg/cmd/agentskill"
"github.com/brevdev/brev-cli/pkg/cmd/register"
"github.com/brevdev/brev-cli/pkg/cmd/version"
"github.com/brevdev/brev-cli/pkg/store"
"github.com/brevdev/brev-cli/pkg/sudo"
"github.com/brevdev/brev-cli/pkg/terminal"

"github.com/spf13/cobra"
Expand Down Expand Up @@ -43,7 +43,6 @@ type upgradeDeps struct {
detector Detector
upgrader Upgrader
confirmer terminal.Confirmer
gater sudo.Gater
skillInstaller SkillInstaller
}

Expand All @@ -52,7 +51,6 @@ func defaultUpgradeDeps() upgradeDeps {
detector: SystemDetector{},
upgrader: SystemUpgrader{},
confirmer: register.TerminalPrompter{},
gater: sudo.Default,
skillInstaller: defaultSkillInstaller{},
}
}
Expand Down Expand Up @@ -146,11 +144,12 @@ func upgradeViaBrew(t *terminal.Terminal, deps upgradeDeps) (bool, error) {

func upgradeViaDirect(t *terminal.Terminal, deps upgradeDeps) (bool, error) {
t.Vprint("Detected install method: direct binary install")
t.Vprint("This will download the latest release and install it to /usr/local/bin/brev")
t.Vprint("This will download the latest release and install it to ~/.local/bin/brev.")
t.Vprint("")

if err := deps.gater.Gate(t, deps.confirmer, "Upgrade", false); err != nil {
return false, fmt.Errorf("sudo issue: %w", err)
if !deps.confirmer.ConfirmYesNo("Proceed with upgrade?") {
t.Vprint("Upgrade canceled.")
return false, nil
}

t.Vprint("")
Expand All @@ -160,5 +159,33 @@ func upgradeViaDirect(t *terminal.Terminal, deps upgradeDeps) (bool, error) {

t.Vprint("")
t.Vprint(t.Green("Upgrade complete."))

if stale := detectStaleSystemInstall(); stale != "" {
t.Vprint("")
t.Vprintf(" The new brev binary was installed at ~/.local/bin/brev,\n")
t.Vprintf(" but an older binary still exists at %s.\n", stale)
t.Vprint(" If that path appears earlier in your PATH, your shell will keep running the old version.")
t.Vprintf(" Remove it with: sudo rm %s\n", stale)
}
return true, nil
}

// detectStaleSystemInstall returns the path of the currently-running binary
// when it lives in a system bin directory left over from a pre-~/.local/bin
// install. Returns "" if the running binary is already in ~/.local/bin or in
// any other non-system location.
func detectStaleSystemInstall() string {
exe, err := os.Executable()
if err != nil {
return ""
}
resolved, err := filepath.EvalSymlinks(exe)
if err != nil {
resolved = exe
}
switch filepath.Dir(resolved) {
case "/usr/local/bin", "/usr/bin":
return resolved
}
return ""
}
8 changes: 0 additions & 8 deletions pkg/cmd/upgrade/upgrade_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (

"github.com/brevdev/brev-cli/pkg/cmd/version"
"github.com/brevdev/brev-cli/pkg/store"
"github.com/brevdev/brev-cli/pkg/sudo"
"github.com/brevdev/brev-cli/pkg/terminal"
)

Expand Down Expand Up @@ -65,7 +64,6 @@ func Test_runUpgrade_AlreadyUpToDate(t *testing.T) {
detector: mockDetector{method: InstallMethodBrew},
upgrader: upgrader,
confirmer: mockConfirmer{confirm: true},
gater: sudo.CachedGater{},
skillInstaller: skill,
}

Expand Down Expand Up @@ -94,7 +92,6 @@ func Test_runUpgrade_BrewPath(t *testing.T) {
detector: mockDetector{method: InstallMethodBrew},
upgrader: upgrader,
confirmer: mockConfirmer{confirm: true},
gater: sudo.CachedGater{},
skillInstaller: skill,
}

Expand Down Expand Up @@ -126,7 +123,6 @@ func Test_runUpgrade_DirectPath(t *testing.T) {
detector: mockDetector{method: InstallMethodDirect},
upgrader: upgrader,
confirmer: mockConfirmer{confirm: true},
gater: sudo.CachedGater{},
skillInstaller: skill,
}

Expand Down Expand Up @@ -158,7 +154,6 @@ func Test_runUpgrade_UserCancels(t *testing.T) {
detector: mockDetector{method: InstallMethodBrew},
upgrader: upgrader,
confirmer: mockConfirmer{confirm: false},
gater: sudo.CachedGater{},
skillInstaller: skill,
}

Expand All @@ -181,7 +176,6 @@ func Test_runUpgrade_VersionCheckFails(t *testing.T) {
detector: mockDetector{method: InstallMethodBrew},
upgrader: &mockUpgrader{},
confirmer: mockConfirmer{confirm: true},
gater: sudo.CachedGater{},
skillInstaller: &mockSkillInstaller{},
}

Expand All @@ -204,7 +198,6 @@ func Test_runUpgrade_UpgraderFails(t *testing.T) {
detector: mockDetector{method: InstallMethodBrew},
upgrader: upgrader,
confirmer: mockConfirmer{confirm: true},
gater: sudo.CachedGater{},
skillInstaller: skill,
}

Expand All @@ -230,7 +223,6 @@ func Test_runUpgrade_SkillInstallFailure_DoesNotFailUpgrade(t *testing.T) {
detector: mockDetector{method: InstallMethodBrew},
upgrader: upgrader,
confirmer: mockConfirmer{confirm: true},
gater: sudo.CachedGater{},
skillInstaller: skill,
}

Expand Down
Loading