#!/bin/sh MODERNE_BASE_URL="https://app.moderne.io" # # Moderne CLI installer. # Downloads the modw wrapper script and places it on PATH. # # Usage: # curl -fsSL "https://app.moderne.io/cli" | bash # # When served through a tenant proxy, MODERNE_BASE_URL is baked in at the top # of this script by the proxy via string substitution. When running the raw # script from GitHub, MODERNE_BASE_URL is unset and no tenant configuration # is performed. # # Environment variables: # MODERNE_CLI_HOME - Override install location (default: ~/.moderne/cli) # MODERNE_BASE_URL - Moderne tenant URL (set by proxy, not by user) # MODERNE_WRAPPER_DISTRIBUTION_USERNAME - Basic auth username for distribution downloads # MODERNE_WRAPPER_DISTRIBUTION_PASSWORD - Basic auth password for distribution downloads # MODERNE_WRAPPER_DISTRIBUTION_TOKEN - Bearer token for distribution downloads # set -e MODERNE_CLI_HOME="${MODERNE_CLI_HOME:-$HOME/.moderne/cli}" BIN_DIR="$MODERNE_CLI_HOME/bin" DIST_DIR="$MODERNE_CLI_HOME/dist" MAVEN_CENTRAL="https://repo1.maven.org/maven2" # Customized by the /cli REST endpoint to point at a customer's internal artifact repository. DISTRIBUTION_URL="" DISTRIBUTION_URL_EARLY_ACCESS="" # --- Authentication --- DIST_USERNAME="${MODERNE_WRAPPER_DISTRIBUTION_USERNAME:-}" DIST_PASSWORD="${MODERNE_WRAPPER_DISTRIBUTION_PASSWORD:-}" DIST_TOKEN="${MODERNE_WRAPPER_DISTRIBUTION_TOKEN:-}" # Token takes precedence over username/password if [ -n "$DIST_TOKEN" ]; then DIST_USERNAME="" DIST_PASSWORD="" fi # --- HTTP helpers --- http_get() { if command -v curl >/dev/null 2>&1; then if [ -n "$DIST_TOKEN" ]; then curl -fsSL -H "Authorization: Bearer $DIST_TOKEN" -o "$2" "$1" elif [ -n "$DIST_USERNAME" ]; then curl -fsSL --user "$DIST_USERNAME:$DIST_PASSWORD" -o "$2" "$1" else curl -fsSL -o "$2" "$1" fi elif command -v wget >/dev/null 2>&1; then if [ -n "$DIST_TOKEN" ]; then wget -q --header="Authorization: Bearer $DIST_TOKEN" -O "$2" "$1" elif [ -n "$DIST_USERNAME" ]; then wget -q --user="$DIST_USERNAME" --password="$DIST_PASSWORD" -O "$2" "$1" else wget -q -O "$2" "$1" fi else echo "ERROR: Neither curl nor wget found." >&2 exit 1 fi } http_get_stdout() { if command -v curl >/dev/null 2>&1; then if [ -n "$DIST_TOKEN" ]; then curl -fsSL -H "Authorization: Bearer $DIST_TOKEN" "$1" elif [ -n "$DIST_USERNAME" ]; then curl -fsSL --user "$DIST_USERNAME:$DIST_PASSWORD" "$1" else curl -fsSL "$1" fi elif command -v wget >/dev/null 2>&1; then if [ -n "$DIST_TOKEN" ]; then wget -q --header="Authorization: Bearer $DIST_TOKEN" -O - "$1" elif [ -n "$DIST_USERNAME" ]; then wget -q --user="$DIST_USERNAME" --password="$DIST_PASSWORD" -O - "$1" else wget -q -O - "$1" fi else echo "ERROR: Neither curl nor wget found." >&2 exit 1 fi } # --- Version resolution --- resolve_version_from_maven() { METADATA_URL="$1/io/moderne/moderne-cli/maven-metadata.xml" METADATA="$(http_get_stdout "$METADATA_URL" 2>/dev/null)" || return 1 echo "$METADATA" | sed -n 's/.*\(.*\)<\/release>.*/\1/p' } # --- Main --- echo "Installing Moderne CLI..." REPO_BASE="${DISTRIBUTION_URL:-$MAVEN_CENTRAL}" MOD_VERSION="$(resolve_version_from_maven "$REPO_BASE" 2>/dev/null)" || true if [ -z "$MOD_VERSION" ]; then echo "ERROR: Could not resolve Moderne CLI version." >&2 exit 1 fi # Download modw MODW_URL="$REPO_BASE/io/moderne/moderne-cli/$MOD_VERSION/moderne-cli-$MOD_VERSION-modw.sh" mkdir -p "$BIN_DIR" "$DIST_DIR" echo "Downloading modw $MOD_VERSION..." http_get "$MODW_URL" "$BIN_DIR/modw" chmod +x "$BIN_DIR/modw" # Create mod symlink ln -sf modw "$BIN_DIR/mod" # Write wrapper properties mkdir -p "$DIST_DIR" echo "version=RELEASE" > "$DIST_DIR/moderne-wrapper.properties" if [ -n "$DISTRIBUTION_URL" ]; then echo "distributionUrl=$DISTRIBUTION_URL/io/moderne/moderne-cli-\${platform}/\${version}/moderne-cli-\${platform}-\${version}.\${extension}" >> "$DIST_DIR/moderne-wrapper.properties" fi if [ -n "$DISTRIBUTION_URL_EARLY_ACCESS" ]; then echo "distributionUrlEarlyAccess=$DISTRIBUTION_URL_EARLY_ACCESS" >> "$DIST_DIR/moderne-wrapper.properties" fi if [ -n "$DIST_USERNAME" ]; then echo "distributionUsername=$DIST_USERNAME" >> "$DIST_DIR/moderne-wrapper.properties" fi if [ -n "$DIST_PASSWORD" ]; then echo "distributionPassword=$DIST_PASSWORD" >> "$DIST_DIR/moderne-wrapper.properties" fi if [ -n "$DIST_TOKEN" ]; then echo "distributionToken=$DIST_TOKEN" >> "$DIST_DIR/moderne-wrapper.properties" fi # Add to PATH and shell completion if not already present SHELL_NAME="$(basename "${SHELL:-/bin/sh}")" case "$SHELL_NAME" in zsh) RC_FILE="$HOME/.zshrc" ;; fish) RC_FILE="$HOME/.config/fish/config.fish" ;; *) RC_FILE="$HOME/.bashrc" ;; esac if [ -n "$RC_FILE" ]; then case "$PATH" in *".moderne/cli/bin"*) ;; *) echo "export PATH=\"\$PATH:\$HOME/.moderne/cli/bin\"" >> "$RC_FILE" echo "Added ~/.moderne/cli/bin to PATH in $RC_FILE" PATH_UPDATED=1 ;; esac COMPLETION_SOURCE='[ -f "$HOME/.moderne/cli/completion.bash" ] && source "$HOME/.moderne/cli/completion.bash"' if ! grep -qF "moderne/cli/completion.bash" "$RC_FILE" 2>/dev/null; then echo "$COMPLETION_SOURCE" >> "$RC_FILE" echo "Added shell completion to $RC_FILE" fi # Source the rc file so mod is available immediately # shellcheck disable=SC1090 . "$RC_FILE" 2>/dev/null || true fi # Configure tenant if MODERNE_BASE_URL is set (baked in by proxy) if [ -n "$MODERNE_BASE_URL" ]; then "$BIN_DIR/mod" config moderne edit "$MODERNE_BASE_URL" 2>/dev/null || true "$BIN_DIR/mod" login 2>/dev/null || true fi echo "" echo "Moderne CLI installed successfully!" if [ -n "$PATH_UPDATED" ]; then echo "Your PATH was updated in $RC_FILE, but this terminal won't pick it up yet." echo "Run 'source $RC_FILE' or open a new terminal, then run 'mod --version' to verify." else echo "Run 'mod --version' to verify." fi