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
209 changes: 209 additions & 0 deletions install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
#!/bin/sh
set -e

# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

log_info() {
printf "${GREEN}[INFO]${NC} %s\n" "$1"
}

log_warn() {
printf "${YELLOW}[WARN]${NC} %s\n" "$1"
}

log_error() {
printf "${RED}[ERROR]${NC} %s\n" "$1"
}

# Detect OS
detect_os() {
case "$(uname -s)" in
Linux*) echo "linux";;
Darwin*) echo "darwin";;
CYGWIN*) echo "windows";;
MINGW*) echo "windows";;
*) echo "unsupported";;
esac
}

# Detect architecture
detect_arch() {
case "$(uname -m)" in
x86_64) echo "amd64";;
arm64|aarch64) echo "arm64";;
*) echo "amd64";;
esac
}

# Detect config directory (matches Go's os.UserConfigDir)
detect_config_dir() {
case "$(uname -s)" in
Darwin*) echo "$HOME/Library/Application Support";;
Linux*) echo "$HOME/.config";;
CYGWIN*|MINGW*) echo "$APPDATA";;
*) echo "$HOME/.config";;
esac
}

# Get latest version from GitHub
get_latest_version() {
curl -sL "https://api.github.com/repos/menloresearch/cli/releases/latest" | grep -o '"tag_name": "v[^"]*"' | cut -d'"' -f4 | cut -d'v' -f2
}

# Install menlo
install() {
OS=$(detect_os)
ARCH=$(detect_arch)

log_info "Detected OS: $OS, Arch: $ARCH"

# Get version (default to latest if not set)
VERSION="${VERSION:-$(get_latest_version)}"

if [ -z "$VERSION" ]; then
log_warn "Could not fetch latest version, using v0.0.4"
VERSION="v0.0.4"
fi

# Remove 'v' prefix if present
VERSION="${VERSION#v}"

# Binary name
BINARY_NAME="menlo"
if [ "$OS" = "windows" ]; then
BINARY_NAME="menlo.exe"
fi

# Download URL
DOWNLOAD_URL="https://github.com/menloresearch/cli/releases/download/v${VERSION}/${BINARY_NAME}_${VERSION}_${OS}_${ARCH}.tar.gz"

log_info "Downloading menlo v${VERSION}..."
log_info "URL: $DOWNLOAD_URL"

# Create temp directory
TEMP_DIR=$(mktemp -d)
cd "$TEMP_DIR"

# Download and extract
if curl -sL "$DOWNLOAD_URL" -o "menlo.tar.gz"; then
tar -xzf "menlo.tar.gz" || log_error "Failed to extract archive"
else
log_error "Failed to download menlo"
cd /
rm -rf "$TEMP_DIR"
exit 1
fi

# Check if binary exists
if [ ! -f "$BINARY_NAME" ]; then
# Try alternative naming pattern
DOWNLOAD_URL="https://github.com/menloresearch/cli/releases/download/v${VERSION}/menlo_${VERSION}_${OS}_${ARCH}.tar.gz"
log_info "Trying alternate URL: $DOWNLOAD_URL"

curl -sL "$DOWNLOAD_URL" -o "menlo.tar.gz" || {
log_error "Failed to download. Please check if version $VERSION exists."
cd /
rm -rf "$TEMP_DIR"
exit 1
}
tar -xzf "menlo.tar.gz"
fi

# Install to /usr/local/bin (may need sudo)
log_info "Installing to /usr/local/bin..."
if [ -w /usr/local/bin ]; then
cp "$BINARY_NAME" /usr/local/bin/menlo
chmod +x /usr/local/bin/menlo
else
log_warn "Need sudo to install to /usr/local/bin"
sudo cp "$BINARY_NAME" /usr/local/bin/menlo
sudo chmod +x /usr/local/bin/menlo
fi

# Write version to config (preserve existing config)
CONFIG_BASE_DIR=$(detect_config_dir)
CONFIG_DIR="$CONFIG_BASE_DIR/menlo"
mkdir -p "$CONFIG_DIR"
CONFIG_FILE="$CONFIG_DIR/config.yaml"
if [ -f "$CONFIG_FILE" ]; then
# Use awk to update version in YAML - replace existing or add new
awk -v ver="$VERSION" '
/^version:/ { print "version: \"" ver "\""; found=1; next }
{ print }
END { if (!found) print "version: \"" ver "\"" }
' "$CONFIG_FILE" > "$CONFIG_FILE.tmp" && mv "$CONFIG_FILE.tmp" "$CONFIG_FILE"
else
printf 'version: "%s"\n' "$VERSION" > "$CONFIG_FILE"
fi
log_info "Version $VERSION written to config"

# Install shell completions to config directory (not modifying user shell files)
COMPLETION_DIR="$CONFIG_DIR/completions"
mkdir -p "$COMPLETION_DIR"

# Detect current shell
SHELL_NAME="$(basename "$SHELL" 2>/dev/null || echo "bash")"

case "$SHELL_NAME" in
zsh)
"$BINARY_NAME" completion zsh > "$COMPLETION_DIR/zsh"
log_info "Zsh completion installed to $COMPLETION_DIR/zsh"
log_info "Add to your .zshrc: source $COMPLETION_DIR/zsh"
;;
fish)
"$BINARY_NAME" completion fish > "$COMPLETION_DIR/fish"
log_info "Fish completion installed to $COMPLETION_DIR/fish"
log_info "Add to your config.fish: source $COMPLETION_DIR/fish"
;;
bash)
"$BINARY_NAME" completion bash > "$COMPLETION_DIR/bash"
log_info "Bash completion installed to $COMPLETION_DIR/bash"
log_info "Add to your .bashrc: source $COMPLETION_DIR/bash"
;;
*)
# Install all completions
"$BINARY_NAME" completion bash > "$COMPLETION_DIR/bash" 2>/dev/null || true
"$BINARY_NAME" completion zsh > "$COMPLETION_DIR/zsh" 2>/dev/null || true
"$BINARY_NAME" completion fish > "$COMPLETION_DIR/fish" 2>/dev/null || true
log_info "Completions installed to $COMPLETION_DIR"
;;
esac

# Cleanup
cd /
rm -rf "$TEMP_DIR"

log_info "menlo v${VERSION} installed successfully!"
log_info "Run 'menlo init' to get started"
}

# Check if curl is installed
if ! command -v curl >/dev/null 2>&1; then
log_error "curl is required but not installed. Please install curl first."
exit 1
fi

# Parse arguments
while [ $# -gt 0 ]; do
case "$1" in
-h|--help)
echo "Usage: sh install.sh"
echo ""
echo "Options:"
echo " -h, --help Show this help message"
exit 0
;;
*)
log_error "Unknown option: $1"
echo "Use -h or --help for usage information"
exit 1
;;
esac
done

# Run install
install
73 changes: 73 additions & 0 deletions internal/commands/completion.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package commands

import (
"os"

"github.com/spf13/cobra"
)

var completionCmd = &cobra.Command{
Use: "completion [shell]",
Short: "Generate shell completion scripts",
Hidden: true,
Long: `Generate shell completion scripts for menlo.

To load completions:

Bash:

$ source <(menlo completion bash)

# To load completions for each session, execute once:
# Linux:
$ menlo completion bash > /etc/bash_completion.d/menlo
# macOS:
$ menlo completion bash > /usr/local/etc/bash_completion.d/menlo

Zsh:

# If shell completion is not already enabled in your environment,
# you will need to enable it. You can execute the following once:

$ echo "autoload -U compinit; compinit" >> ~/.zshrc

# To load completions for each session, execute once:
$ menlo completion zsh > "${fpath[1]}/_menlo"

# You will need to start a new shell for this setup to take effect.

Fish:

$ menlo completion fish | source

# To load completions for each session, execute once:
$ menlo completion fish > ~/.config/fish/completions/menlo.fish

PowerShell:

PS> menlo completion powershell | Out-String | Invoke-Expression

# To load completions for every session, add the output of the previous
# command to your powershell profile.
`,
DisableFlagsInUseLine: true,
ValidArgs: []string{"bash", "zsh", "fish", "powershell"},
Args: cobra.MatchAll(cobra.ExactArgs(1), cobra.OnlyValidArgs),
RunE: func(cmd *cobra.Command, args []string) error {
switch args[0] {
case "bash":
return rootCmd.GenBashCompletion(os.Stdout)
case "zsh":
return rootCmd.GenZshCompletion(os.Stdout)
case "fish":
return rootCmd.GenFishCompletion(os.Stdout, true)
case "powershell":
return rootCmd.GenPowerShellCompletionWithDesc(os.Stdout)
}
return nil
},
}

func init() {
rootCmd.AddCommand(completionCmd)
}
30 changes: 12 additions & 18 deletions internal/commands/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,30 @@ package commands

import (
"fmt"
"os"

"github.com/menloresearch/cli/internal/config"
"github.com/spf13/cobra"
)

var (
version = "dev"
commit = "none"
date = "unknown"
builtBy = "goreleaser"
)

var versionCmd = &cobra.Command{
Use: "version",
Short: "Print the version number",
Run: func(cmd *cobra.Command, args []string) {
cfg, err := config.Load()
if err != nil {
// If no config, use default
cfg = config.DefaultConfig()
}

version := cfg.Version
if version == "" {
version = "dev"
}

fmt.Printf("menlo %s\n", version)
fmt.Printf(" commit: %s\n", commit)
fmt.Printf(" date: %s\n", date)
fmt.Printf(" built by: %s\n", builtBy)
},
}

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

func init() {
// Allow overriding version via ldflags
if v := os.Getenv("MENLO_CLI_VERSION"); v != "" {
version = v
}
}
1 change: 1 addition & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type Config struct {
APIKey string `yaml:"api_key"`
PlatformURL string `yaml:"platform_url"`
DefaultRobotID string `yaml:"default_robot_id"`
Version string `yaml:"version"`
}

func (c *Config) SetDefaults() {
Expand Down
Loading
Loading