Radish alpha
r
rad:z371PVmDHdjJucejRoRYJcDEvD5pp
Radicle website including documentation and guides
Radicle
Git
Refactor the install script to allow installation of any radicle component
Open levitte opened 1 year ago

The install script only installed the cli and node part of Radicle. Historically, it also installed radicle-httpd as well, but that was moved to become another component, which should be possible to install through this same script.

Thus, the install script is refactored to allow sets of components to be installed, together in any way the user desires. This refactoring makes the install script data driven, based on specially named variables and functions.

1 file changed +199 -84 e9673f44 bbcb599f
modified install
@@ -4,11 +4,58 @@
#
set -e

-
# SSH signing key for the release archives. This is currently cloudhead's key.
-
SIGNER="ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL460KIEccS4881p7PPpiiQBsxF+H5tgC6De6crw9rbU"
+
# Components are defined by the existence of a few variables, describing where to find them.
+
#
+
# {component}_NAME              - The title name
+
# {component}_BASEURL           - The base URL to find the binaries
+
# {component}_ROOTNAME          - The root file name of the component tarballs
+
# {component}_SIGNER            - The public key of the signer
+
# {component}_EXECUTABLES       - The comma-separated list of executables this component
+
#                                 installs in $RAD_PATH
+
# {component}_get_version       - A function to get the version that was actually installed
+
#
+
# or
+
#
+
# {component}_COMPOSED  - A comma separated list of other components
+

+
cli_NAME="Radicle"
+
cli_BASEURL="https://files.radicle.xyz/releases"
+
cli_ROOTNAME="radicle"
+
# This is currently cloudhead's key.
+
cli_SIGNER="cloudhead ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL460KIEccS4881p7PPpiiQBsxF+H5tgC6De6crw9rbU"
+
cli_EXECUTABLES="radicle-node,rad,git-remote-rad"
+
cli_get_version() {
+
  $RAD_PATH/rad --version | cut -f2 -d' ' -
+
}
+

+
backend_NAME="Radicle HTTPD backend"
+
backend_BASEURL="https://files.radicle.xyz/releases/radicle-httpd"
+
backend_ROOTNAME="radicle"
+
# This is currently sebastinez build server key.
+
backend_SIGNER="sebastinez ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKU7IHRsae2q1/qd8NaWxfGhPEFGHwK1dcxvSjNdttjb"
+
backend_EXECUTABLES="radicle-httpd"
+
backend_get_version() {
+
  $RAD_PATH/radicle-httpd --version | cut -f2 -d' ' -
+
}
+

+
# radicle-explorer doesn't have installation packages yet
+
#explorer_BASEURL="https://files.radicle.xyz/releases/radicle-explorer"
+
#explorer_ROOTNAME="radicle-explorer"
+

+
default_COMPOSED=cli=latest
+
seeder_COMPOSED=cli=latest,backend=latest
+
all_COMPOSED=cli=latest,backend=latest
+

+
# When each component is processed, all the component variables' values are copied to
+
# variables with {component}_ stripped off, and a variable COMPONENT is assigned the
+
# name of the component being processed.

url() {
-
  echo "https://files.radicle.xyz/releases/$1/radicle-$2.tar.xz"
+
  # $1  BASEURL
+
  # $2  ROOTNAME
+
  # $3  VERSION
+
  # $4  TARGET
+
  echo "$1/$3/$2-$4.tar.xz"
}

info() {
@@ -36,15 +83,19 @@ is_authed() {
}

success() {
-
  version="$1"
+
  component="$1"
+
  name="$2"
+
  version="$3"

-
  printf "\033[32m✓\033[0m Radicle \033[2m$1\033[0m was installed successfully.\n"
+
  printf "\033[32m✓\033[0m $name \033[2m$version\033[0m was installed successfully.\n"

-
  RAD_HOME=$(rad_home)
+
  if [ "$component" = "cli" ]; then
+
    RAD_HOME=$(rad_home)

-
  if [ -n "$RAD_HOME" ] && [ -S "$RAD_HOME/node/control.sock" ];  then
-
    printf "\n"
-
    printf "Please restart your node to complete the upgrade.\n"
+
    if [ -n "$RAD_HOME" ] && [ -S "$RAD_HOME/node/control.sock" ];  then
+
      printf "\n"
+
      printf "Please restart your node to complete the upgrade.\n"
+
    fi
  fi
}

@@ -63,7 +114,7 @@ usage() {
  echo "  $0 [<options>]"
  echo
  echo "  This script will install the Radicle binaries under '$RAD_PATH'".
-
  echo "  To change the location, set \$RAD_PATH to a different directory."
+
  echo "  To change the location, use --prefix."
  echo
  echo "  Your Radicle home is set to '$RAD_HOME'."
  echo "  To change it, set \$RAD_HOME to a different directory."
@@ -72,9 +123,15 @@ usage() {
  echo
  echo "  --no-modify-path    Do not modify the PATH environment variable"
  echo "  --version=VERSION   Install the given version of Radicle (default: latest)"
+
  echo "  --components=COMPONENTS"
+
  echo "                      comma-separated list of components, with optional version"
+
  echo "                      for each.  Component syntax: NAME or NAME=VERSION"
+
  echo "                      (default: cli=VERSION)"
  echo "  --prefix=PATH       Radicle install prefix (default: ~/.radicle)"
  echo "  --help, -h          Show this help message and exit"
  echo
+
  echo "Note: --version and --components don't mix"
+
  echo
  echo "Environment"
  echo
  echo "  RAD_HOME            Radicle home directory"
@@ -124,18 +181,17 @@ verify() {
  archive="$1"
  signers="$(dirname $archive)/signers"
  # Add the signer key to the allowed signers file we pass to ssh-keygen.
-
  printf "cloudhead $SIGNER\n" > $signers
+
  printf "$SIGNER\n" > $signers

  # Verify that `$archive` was signed by a key in `$signers`, identified by the
  # name "cloudhead", using the signature in `$archive.sig`.
-
  ssh-keygen -Y verify -f $signers -I cloudhead -n file -s "$archive.sig" < "$archive" || fatal "Invalid signature for $archive"
+
  ssh-keygen -Y verify -f $signers -I "${SIGNER%% *}" -n file -s "$archive.sig" < "$archive" || fatal "Invalid signature for $archive"
}

main() {
  PREFIX=${RAD_HOME:-"$HOME/.radicle"}
  SHELL_PATH=${SHELL:-"/bin/sh"}
  NO_MODIFY_PATH=false
-
  VERSION=latest

  if [ -n "$RAD_PATH" ]; then
    fatal "RAD_PATH is no longer supported; Use '--prefix' instead"
@@ -168,6 +224,9 @@ main() {
      --version=*)
        VERSION=${1#*=}
        ;;
+
      --components=*)
+
        COMPONENTS=${1#*=}
+
        ;;
      -h|--help)
        usage
        exit 0 ;;
@@ -180,8 +239,18 @@ main() {
    shift
  done

-
  if [ -z "$VERSION" ]; then
-
    fatal "Empty version string; use --version=VERSION"
+
  if [ -n "$VERSION" -a -n "$COMPONENTS" ]; then
+
    fatal "--version and --components are not allowed to mix"
+
  fi
+
  if [ -z "$VERSION" -a -z "$COMPONENTS" ]; then
+
    fatal "Empty version string and empty components list; use --version=VERSION"
+
  fi
+
  if [ -z "$COMPONENTS" ]; then
+
    if [ -n "$VERSION" ]; then
+
      COMPONENTS=cli=${VERSION}
+
    else
+
      COMPONENTS=cli
+
    fi
  fi

  if [ -z "$PREFIX" ]; then
@@ -189,6 +258,35 @@ main() {
  fi
  mkdir -p $PREFIX

+
  # Process the component list
+
  while true; do
+
    # Get rid of the commas
+
    COMPONENTS=$( IFS=,; for c in $COMPONENTS; do echo "$c"; done )
+
    # If any component is composed, then replace it with the composition
+
    COMPONENTS=$( for c in $COMPONENTS; do
+
                    if echo $c | grep -q '^[a-z]*$'; then
+
                      newc="$(eval echo '$'${c}_COMPOSED)"
+
                    fi
+
                    if [ -n "$newc" ]; then
+
                      echo $newc
+
                    else
+
                      echo $c
+
                    fi
+
                  done )
+
    # We're done when there are no commas left
+
    if ! ( echo "$COMPONENTS" | grep -q ',' ); then
+
      break
+
    fi
+
  done
+

+
  # Check that there are no duplicate components, especially with different
+
  # versions
+
  component_names=$( for c in $COMPONENTS; do echo ${c%%=*}; done | sort )
+
  component_uniq=$( for c in $component_names; do echo $c; done | uniq )
+
  if [ "$component_names" != "$component_uniq" ]; then
+
    fatal "The final set of components has conflicts: $COMPONENTS"
+
  fi
+

  echo
  echo "👾 Welcome to Radicle"
  echo
@@ -198,85 +296,102 @@ main() {

  info "Detecting operating system..."
  TARGET=$(target)
-
  ARCHIVE="$(mktemp -d)/radicle-$TARGET.tar.xz" # Nb. `-d` must be used on BSDs.
-
  URL="$(url "$VERSION" "$TARGET")"

-
  info "Downloading $URL..."
-
  curl --proto '=https' --fail --tlsv1.2 -# -L "$URL"     -o "$ARCHIVE"     || fatal "Failed to fetch $URL" # Nb. `--tlsv1.3` is not supported on macOS
-
  info "Downloading $URL.sig..."
-
  curl --proto '=https' --fail --tlsv1.2 -# -L "$URL.sig" -o "$ARCHIVE.sig" || fatal "Failed to fetch $URL.sig"
+
  for COMPONENT in $COMPONENTS; do
+
    VERSION=${COMPONENT#*=}
+
    if [ "$VERSION" = "$COMPONENT" ]; then VERSION=; fi
+
    COMPONENT=${COMPONENT%%=*}
+
    VERSION=${VERSION:-latest}

-
  info "Verifying $(basename $ARCHIVE)..."
-
  verify "$ARCHIVE"
+
    NAME=$(eval echo '$'${COMPONENT}_NAME)
+
    BASEURL=$(eval echo '$'${COMPONENT}_BASEURL)
+
    ROOTNAME=$(eval echo '$'${COMPONENT}_ROOTNAME)
+
    SIGNER=$(eval echo '$'${COMPONENT}_SIGNER)
+
    EXECUTABLES=$(eval echo '$'${COMPONENT}_EXECUTABLES)

-
  info "Installing Radicle into $PREFIX..."
-
  tar -xJf "$ARCHIVE" --strip-components=1 -C "$PREFIX"
+
    ARCHIVE="$(mktemp -d)/$ROOTNAME-$TARGET.tar.xz" # Nb. `-d` must be used on BSDs.
+
    URL="$(url "$BASEURL" "$ROOTNAME" "$VERSION" "$TARGET")"

-
  chmod +x \
-
    $RAD_PATH/radicle-node \
-
    $RAD_PATH/rad \
-
    $RAD_PATH/git-remote-rad
+
    info "----- $COMPONENT -----"
+
    info "Downloading $URL..."
+
    curl --proto '=https' --fail --tlsv1.2 -# -L "$URL"     -o "$ARCHIVE"     || fatal "Failed to fetch $URL" # Nb. `--tlsv1.3` is not supported on macOS
+
    info "Downloading $URL.sig..."
+
    curl --proto '=https' --fail --tlsv1.2 -# -L "$URL.sig" -o "$ARCHIVE.sig" || fatal "Failed to fetch $URL.sig"

-
  if ! command -v git >/dev/null 2>&1; then
-
    warn
-
    warn "Warning: a Git installation was not detected on your system."
-
    warn "Warning: please install Git for Radicle to work correctly."
-
  fi
-
  version="$($RAD_PATH/rad --version | cut -f2 -d' ' -)"
-

-
  # If radicle is not in $PATH, add it here.
-
  if $NO_MODIFY_PATH; then
-
    info "Not modifying shell path variable, as requested."
-
    get_started $version
-
  elif in_path $RAD_PATH; then
-
    info "Radicle is configured in shell already, not modifying."
-
    get_started $version
-
  else
-
    PROFILE=""
-

-
    case $SHELL_PATH in
-
      */zsh)
-
        PROFILE=$HOME/.zshenv ;;
-
      */bash)
-
        PROFILE=$HOME/.bashrc ;;
-
      */fish)
-
        PROFILE=$HOME/.config/fish/config.fish ;;
-
      */ash)
-
        PROFILE=$HOME/.profile ;;
-
      */csh)
-
        PROFILE=$HOME/.cshrc ;;
-
    esac
+
    info "Verifying $(basename $ARCHIVE)..."
+
    verify "$ARCHIVE"

-
    if [ -z "$PROFILE" ]; then
-
      warn "Warning: unable to update your PATH variable."
-
      warn "Warning: please manually add $RAD_PATH to your PATH."
-
      get_started $version
-
    else
-
      info "Configuring path variable in ~${PROFILE#$HOME}..."
-
      echo                                    >> "$PROFILE"
-
      echo "# Added by Radicle."              >> "$PROFILE"
-
      echo "export PATH=\"\$PATH:$RAD_PATH\"" >> "$PROFILE"
-
      echo
-

-
      success $version
-

-
      if command -v rad >/dev/null 2>&1; then
-
        EXISTING=$(command -v rad)
-
        printf "\n"
-
        warn "Warning: Pre-existing binaries found at $(dirname "$EXISTING")."
-
        warn "Warning: Installed new binaries in $RAD_PATH."
-
      fi
+
    info "Installing Radicle into $PREFIX..."
+
    tar -xJf "$ARCHIVE" --strip-components=1 -C "$PREFIX"

-
      printf "\n"
-
      printf "Before running Radicle for the first time,\n"
-
      printf "run \033[34m\`source ~${PROFILE#$HOME}\`\033[0m or open a new terminal.\n"
+
    chmod +x $( IFS=,; for x in ${EXECUTABLES}; do echo "$RAD_PATH/$x"; done )

-
      if ! is_authed; then
-
        printf "\n"
-
        printf "Then, create your Radicle key pair with \033[35m\`rad auth\`\033[0m.\n"
+
    version="$(${COMPONENT}_get_version)"
+

+
    if [ "$COMPONENT" = "cli" ]; then
+
      if ! command -v git >/dev/null 2>&1; then
+
        warn
+
        warn "Warning: a Git installation was not detected on your system."
+
        warn "Warning: please install Git for Radicle to work correctly."
      fi
+

+
      # If radicle is not in $PATH, add it here.
+
      if $NO_MODIFY_PATH; then
+
        info "Not modifying shell path variable, as requested."
+
        get_started $COMPONENT "$NAME" $version
+
      elif in_path $RAD_PATH; then
+
        info "Radicle is configured in shell already, not modifying."
+
        get_started $COMPONENT "$NAME" $version
+
      else
+
        PROFILE=""
+

+
        case $SHELL_PATH in
+
          */zsh)
+
            PROFILE=$HOME/.zshenv ;;
+
          */bash)
+
            PROFILE=$HOME/.bashrc ;;
+
          */fish)
+
            PROFILE=$HOME/.config/fish/config.fish ;;
+
          */ash)
+
            PROFILE=$HOME/.profile ;;
+
          */csh)
+
            PROFILE=$HOME/.cshrc ;;
+
        esac
+

+
        if [ -z "$PROFILE" ]; then
+
          warn "Warning: unable to update your PATH variable."
+
          warn "Warning: please manually add $RAD_PATH to your PATH."
+
          get_started $COMPONENT "$NAME" $version
+
        else
+
          info "Configuring path variable in ~${PROFILE#$HOME}..."
+
          echo                                    >> "$PROFILE"
+
          echo "# Added by Radicle."              >> "$PROFILE"
+
          echo "export PATH=\"\$PATH:$RAD_PATH\"" >> "$PROFILE"
+
          echo
+

+
          success $COMPONENT "$NAME" $version
+

+
          if command -v rad >/dev/null 2>&1; then
+
            EXISTING=$(command -v rad)
+
            printf "\n"
+
            warn "Warning: Pre-existing binaries found at $(dirname "$EXISTING")."
+
            warn "Warning: Installed new binaries in $RAD_PATH."
+
          fi
+

+
          printf "\n"
+
          printf "Before running Radicle for the first time,\n"
+
          printf "run \033[34m\`source ~${PROFILE#$HOME}\`\033[0m or open a new terminal.\n"
+

+
          if ! is_authed; then
+
            printf "\n"
+
            printf "Then, create your Radicle key pair with \033[35m\`rad auth\`\033[0m.\n"
+
          fi
+
        fi
+
      fi
+
    else
+
      success $COMPONENT "$NAME" $version
    fi
-
  fi
+
  done
}

main "$@"