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
2 changes: 1 addition & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ func checkVersion(cmd *cobra.Command) error {
message := fmt.Sprintf("%s %s",
warningStyle.Render("There's a new version of major available."),
fmt.Sprintf("Run %s to get the newest version.",
commandStyle.Render("brew update && brew upgrade major")))
commandStyle.Render("major update")))

cmd.Println(message)
cmd.Println() // Add a blank line for spacing
Expand Down
131 changes: 131 additions & 0 deletions cmd/update.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
package cmd

import (
"fmt"
"os"
"os/exec"
"runtime"
"strings"

"github.com/charmbracelet/lipgloss"
"github.com/spf13/cobra"
)

var updateCmd = &cobra.Command{
Use: "update",
Short: "Update the major CLI to the latest version",
Long: `Automatically detects your installation method (brew or direct install) and updates to the latest version.`,
Run: func(cmd *cobra.Command, args []string) {
if err := runUpdate(cmd); err != nil {
errorStyle := lipgloss.NewStyle().
Bold(true).
Foreground(lipgloss.Color("#FF0000"))

cmd.Println(errorStyle.Render(fmt.Sprintf("✗ Update failed: %s", err.Error())))
os.Exit(1)
}
},
}

func init() {
rootCmd.AddCommand(updateCmd)
}

func runUpdate(cmd *cobra.Command) error {
titleStyle := lipgloss.NewStyle().
Bold(true).
Foreground(lipgloss.Color("#87D7FF"))

stepStyle := lipgloss.NewStyle().
Foreground(lipgloss.Color("#87D7FF"))

successStyle := lipgloss.NewStyle().
Bold(true).
Foreground(lipgloss.Color("#00FF00"))

cmd.Println(titleStyle.Render("🔄 Updating Major CLI..."))
cmd.Println()

// Detect installation method
installMethod := detectInstallMethod()

cmd.Println(stepStyle.Render(fmt.Sprintf("▸ Detected installation method: %s", installMethod)))

switch installMethod {
case "brew":
return updateViaBrew(cmd, stepStyle, successStyle)
case "direct":
return updateViaDirect(cmd, stepStyle, successStyle)
default:
return fmt.Errorf("could not detect installation method")
}
}

func detectInstallMethod() string {
// Check if installed via brew
if runtime.GOOS == "darwin" || runtime.GOOS == "linux" {
// Check if brew is available
if _, err := exec.LookPath("brew"); err == nil {
// Check if major is installed via brew
brewListCmd := exec.Command("brew", "list", "major")
if err := brewListCmd.Run(); err == nil {
return "brew"
}
}
}

// Otherwise assume direct install
return "direct"
}

func updateViaBrew(cmd *cobra.Command, stepStyle, successStyle lipgloss.Style) error {
cmd.Println(stepStyle.Render("▸ Updating via Homebrew..."))

// Update brew first
updateCmd := exec.Command("brew", "update")
updateCmd.Stdout = os.Stdout
updateCmd.Stderr = os.Stderr
if err := updateCmd.Run(); err != nil {
return fmt.Errorf("failed to update Homebrew: %w", err)
}

// Upgrade major
upgradeCmd := exec.Command("brew", "upgrade", "major")
upgradeCmd.Stdout = os.Stdout
upgradeCmd.Stderr = os.Stderr

if err := upgradeCmd.Run(); err != nil {
// Check if it's already up to date
if strings.Contains(err.Error(), "already installed") {
cmd.Println()
cmd.Println(successStyle.Render("✓ Major CLI is already up to date!"))
return nil
}
return fmt.Errorf("failed to upgrade major: %w", err)
}

cmd.Println()
cmd.Println(successStyle.Render("✓ Successfully updated Major CLI!"))
return nil
}

func updateViaDirect(cmd *cobra.Command, stepStyle, successStyle lipgloss.Style) error {
cmd.Println(stepStyle.Render("▸ Downloading latest version..."))

// Use the install script
installScriptURL := "https://raw.githubusercontent.com/major-technology/cli/main/install.sh"

// Download and execute the install script
curlCmd := exec.Command("bash", "-c", fmt.Sprintf("curl -fsSL %s | bash", installScriptURL))
curlCmd.Stdout = os.Stdout
curlCmd.Stderr = os.Stderr
curlCmd.Stdin = os.Stdin // Allow password prompt for sudo

if err := curlCmd.Run(); err != nil {
return fmt.Errorf("failed to download and install update: %w", err)
}

cmd.Println()
cmd.Println(successStyle.Render("✓ Successfully updated Major CLI!"))
return nil
}