Skip to content

Arkanum-cli

About

The arkanum container image includes the arkanum-cli to manage the current instance and be able to install additional resources. To keep the base image as small as possible we decided not to include all possible frameworks. With this approach the user can decide which frameworks are needed and install it by yourself. This avoids growing the container image size.

For now the arkanum-cli is made with a simple bash script. But this could change whenever the complexity increases significantly.

Usage

To use the cli just open a terminal and call the arkanum command. We also added a bash-completion script for the cli.

bash
function showHelp() {
  cat << HELP
  🧙 arkanum ✨🌌☄️💥 is used to install optional tools for developing in a
  code-server container environment.

  Syntax: arkanum <flags> COMMAND OPTION ARGUMENT
  COMMAND
    config                 The config command is used to modify arkanum itself.
    git                    The git command is a wrapper for git helpers.
    install                The install command is used to add different tools
    help                   Shows this help text.

  OPTION
    config:
      disable-motd         Disables hint in new bash terminal.
      install-extensions   Installs predefined recommended extensions.
      reset-codesettings   Sets VS Code user setting with basic (Fira Code).

    git:
      setup                Takes two arguments to setup the git client:
                             1) Username
                             2) Email address

    install:
      docker-cli           Installs the latest docker-cli.
      dotnet               Installs latest LTS dotnet core sdk + runtime.
      gitea                Installs gitea tools like changelog and tea.
      golang               Installs golang 1.21.5.
      bun                  Installs latest bun version.
      nodejs               Installs latest NodeJs LTS version using Volta.
      volta                Installs Volta as NodeJS version manager.
      powershell           Installs latest PowerShell LTS version.
      lazygit              Installs latest Lazygit binary.

    session:
      save                 Adds items from the install command to the session config.
      restore              Restores the saved session.
      reset                Resets the session config.
      show                 Show currently defined session content.

  Example 1: arkanum git setup "my-name" "my-email"
  Example 2: arkanum install golang
  Example 3: arkanum config disable-motd
  Example 4: arkanum session save lazygit powershell gitea
HELP
}

The first thing you normally after starting your Arkanum instance is setting the git user and email:

arkanum git setup "foobar" "foobar@arkanum.dev"

Now you can simple add your needed tools and frameworks:

bash
arkanum install golang
arkanum install nodejs

Session Handling ^1.8.0

The session helper simplifies restoring your session after your instance was restarted. You can now save a global session config which contains your needed frameworks installed by arkanum install. This wraps multiple install calls and restores your session by running arkanum session restore.

For Example:

bash
# Create a new session config by adding items
arkanum session save lazygit gitea golang
# Shows your saved session
arkanum session show
# Restore your session
arkanum session restore
# optionally reset / delete your session config
arkanum session reset

WARNING

If your run arkanum session save multiple times and use the same arguments, they will also be added and installed multiple times!

Referenced Source Files

Dockerfile
ADD arkanum /usr/bin/
ADD arkanum-completion /etc/bash_completion.d/
RUN \
  chmod +x /usr/bin/arkanum && \
  chmod +x /etc/bash_completion.d/arkanum-completion && \
  echo 'source /etc/bash_completion.d/arkanum-completion' >> /etc/bash.bashrc && \
  touch "$HOME/enable_motd" && \
  echo "if [[ ! -e \"$HOME/data/User/settings.json\" ]]; then arkanum config install-extensions && arkanum config reset-codesettings && \
    echo -e \"🧙 \\e[32markanum\\e[0m: Please reload Arkanum to finalize the setup...\" && read foo; fi" >> /etc/bash.bashrc && \
  echo "if [[ -e \"$HOME/enable_motd\" ]]; then echo -e \"Use 🧙 \\e[32m'arkanum'\\e[0m to install missing runtimes like dotnet or NodeJs.\"; fi" >> /etc/bash.bashrc
bash
#!/bin/bash

set -e

# region usage
function showHelp() {
  cat << HELP
  🧙 arkanum ✨🌌☄️💥 is used to install optional tools for developing in a
  code-server container environment.

  Syntax: arkanum <flags> COMMAND OPTION ARGUMENT
  COMMAND
    config                 The config command is used to modify arkanum itself.
    git                    The git command is a wrapper for git helpers.
    install                The install command is used to add different tools
    help                   Shows this help text.

  OPTION
    config:
      disable-motd         Disables hint in new bash terminal.
      install-extensions   Installs predefined recommended extensions.
      reset-codesettings   Sets VS Code user setting with basic (Fira Code).

    git:
      setup                Takes two arguments to setup the git client:
                             1) Username
                             2) Email address

    install:
      docker-cli           Installs the latest docker-cli.
      dotnet               Installs latest LTS dotnet core sdk + runtime.
      gitea                Installs gitea tools like changelog and tea.
      golang               Installs golang 1.21.5.
      bun                  Installs latest bun version.
      nodejs               Installs latest NodeJs LTS version using Volta.
      volta                Installs Volta as NodeJS version manager.
      powershell           Installs latest PowerShell LTS version.
      lazygit              Installs latest Lazygit binary.

    session:
      save                 Adds items from the install command to the session config.
      restore              Restores the saved session.
      reset                Resets the session config.
      show                 Show currently defined session content.

  Example 1: arkanum git setup "my-name" "my-email"
  Example 2: arkanum install golang
  Example 3: arkanum config disable-motd
  Example 4: arkanum session save lazygit powershell gitea
HELP
}
# endregion usage

function disableMotd() {
  if [[ -e "$HOME/enable_motd" ]]; then
    say "Disabling 'arkanum' motd..." "disableMotd"
    rm -f "$HOME/enable_motd"
  else
    sayW "Arkanum Motd already disabled" "disableMotd"
  fi
}

function say() {
  if [[ -n "$2" ]]; then
    echo -e "🧙 \e[32markanum\e[0m \e[34m[⚒️ $2]\e[0m: $1"
  else
    echo -e "🧙 \e[32markanum\e[0m: $1"
  fi
}

function sayE() {
  if [[ -n "$2" ]]; then
    echo -e "🧙 \e[31markanum\e[0m \e[34m[⚒️ $2]\e[0m: $1" 1>&2
  else
    echo -e "🧙 \e[31markanum\e[0m: $1" 1>&2
  fi
}

function sayW() {
  if [[ -n "$2" ]]; then
    echo -e "🧙 \e[33markanum\e[0m \e[34m[⚒️ $2]\e[0m: $1" 1>&2
  else
    echo -e "🧙 \e[33markanum\e[0m: $1" 1>&2
  fi
}

function instDockerCLI() {
  say "Installing docker-cli..." "docker-cli"
  say "Getting requires packages..." "docker-cli"
  sudo -E apt-get update > /dev/null
  sudo -E apt-get install ca-certificates curl gnupg
  say "Setting up docker repository..." "docker-cli"
  sudo -E install -m 0755 -d /etc/apt/keyrings
  curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo -E gpg --dearmor -o /etc/apt/keyrings/docker.gpg
  sudo -E chmod a+r /etc/apt/keyrings/docker.gpg
  # shellcheck disable=SC2046,SC2027
  echo \
  "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
  say "Installing docker-ce-cli package" "docker-cli"
  sudo -E apt-get update > /dev/null
  sudo -E apt-get install --no-install-recommends -y \
    docker-ce-cli
  say "docker-cli done." "docker-cli"
}

function instDotNet() {
  say "Installing dotnet requirements..." "dotnet"
  sudo -E apt-get update > /dev/null
  sudo -E apt-get install --no-install-recommends -y \
    libicu74

  say "Downloading latest install script..." "dotnet"
  curl -#fSL https://dot.net/v1/dotnet-install.sh -o /tmp/dotnet-install.sh
  chmod +x /tmp/dotnet-install.sh

  say "Installing latest .NET Core LTS release..." "dotnet"
  /tmp/dotnet-install.sh --channel LTS
  # shellcheck disable=SC2016
  echo 'export PATH=$PATH:/config/.dotnet' | sudo tee -a /etc/bash.bashrc > /dev/null

  say "Cleaning up..." "dotnet"
  sudo -E apt-get clean
  sudo rm -rf \
    /tmp/* \
    /var/lib/apt/lists/* \
    /var/tmp/*
  say "dotnet done. " "dotnet"
}

function instGoLang() {
  if [[ -z "$1" ]]; then
    GOVERSION="1.23.2"
  else
    GOVERSION="$1"
  fi

  say "Downloading golang ($GOVERSION)..." "GoLang"
  curl -#fSL "https://go.dev/dl/go$GOVERSION.linux-amd64.tar.gz" -o /tmp/golang.tar.gz
  say "Installing golang ($GOVERSION)...." "GoLang"
  sudo rm -rf /usr/local/go
  sudo tar -C /usr/local -xzf /tmp/golang.tar.gz
  # shellcheck disable=SC2016
  echo 'export PATH=$PATH:/usr/local/go/bin' | sudo tee -a /etc/bash.bashrc > /dev/null
  say "Cleaning up..." "GoLang"
  rm -f /tmp/golang.tar.gz
  say "done." "GoLang"
  say "Please reload bash profile to finalize." "GoLang"
}

function instBun() {
  say "Installing Bun requirements..." "Bun"
  sudo -E apt-get update > /dev/null
  sudo -E apt-get install --no-install-recommends -y \
    unzip
  sudo -E apt-get clean
  say "Installing Bun binaries..." "Bun"
  curl -#fSL https://bun.sh/install | bash
  say "Adding bun binary to profile..." "Bun"
  echo 'export BUN_INSTALL=$HOME/.bun' | sudo tee -a /etc/bash.bashrc > /dev/null
  echo 'export PATH=$BUN_INSTALL/bin:$PATH' | sudo tee -a /etc/bash.bashrc > /dev/null
  say "done." "Bun"
  say "Please reload bash profile to finalize." "Bun"
}

function instNodeJs() {
  say "Installing NodeJS LTS via Volta..." "NodeJS"
  volta install node@lts
  say "done." "NodeJS"
}

function instVolta() {
  say "Installing Volta as NodeJS version manager..." "Volta"
  curl -#fSl https://get.volta.sh | bash
  # shellcheck disable=SC1090
  source ~/.profile
  say "done." "Volta"
}

function instPwsh() {
  say "Installing PowerShell requirements..." "PowerShell"
  sudo -E apt-get update > /dev/null
  sudo -E apt-get install --no-install-recommends -y \
    apt-transport-https \
    software-properties-common

  say "Adding powershell package sources..." "PowerShell"
  # Download the Microsoft repository GPG keys
  curl -#fSL "https://packages.microsoft.com/config/ubuntu/$(lsb_release -rs)/packages-microsoft-prod.deb" -o /tmp/packages-microsoft-prod.deb
  # Register the Microsoft repository GPG keys
  sudo dpkg -i /tmp/packages-microsoft-prod.deb
  # Update the list of packages after we added packages.microsoft.com
  sudo -E apt-get update

  say "Installing PowerShell..." "PowerShell"
  # Install PowerShell
  sudo -E apt-get install --no-install-recommends -y \
    powershell-lts

  say "done." "PowerShell"
}

function instGiteaTools() {
  TEA_VERSION="0.9.0"
  CHANGELOG_VERSION="main"
  say "Installing Gitea tools..." "Gitea"

  say "Downloading 'changelog' ($CHANGELOG_VERSION)..." "Gitea"
  sudo -E curl -#fSL "https://dl.gitea.io/changelog-tool/$CHANGELOG_VERSION/changelog-$CHANGELOG_VERSION-linux-amd64" -o /usr/bin/changelog
  sudo chmod +x /usr/bin/changelog
  say "'changelog' command installed." "Gitea"

  say "Downloading 'tea' ($TEA_VERSION)..." "Gitea"
  sudo -E curl -#fSL https://dl.gitea.io/tea/$TEA_VERSION/tea-$TEA_VERSION-linux-amd64 -o /usr/bin/tea
  sudo chmod +x /usr/bin/tea
  say "'tea' command installed." "Gitea"

  say "done." "Gitea"
}

function installLazyGit() {
  say "Installing latest lazygit version..." "Lazygit"
  LAZYGIT_VERSION=$(curl -s "https://api.github.com/repos/jesseduffield/lazygit/releases/latest" | grep -Po '"tag_name": "v\K[^"]*')
  sudo -E curl -#fSL "https://github.com/jesseduffield/lazygit/releases/latest/download/lazygit_${LAZYGIT_VERSION}_Linux_x86_64.tar.gz" -o /tmp/lazygit.tar.gz
  #mkdir -p /tmp/lazygit
  cd /tmp
  tar xf /tmp/lazygit.tar.gz lazygit
  say "Installing Lazygit binary" "Lazygit"
  sudo install /tmp/lazygit /usr/local/bin
  say "Removing lazygit cache files..." "Lazygit"
  sudo rm -f /tmp/lazygit.tar.gz
  rm -rf /tmp/lazygit
}

function instCodeExtension() {
  say "Installing default extensions...." "Extension"
  # Gitlens
  say "Installing 'gitlens'..." "Extension"
  install-extension eamodio.gitlens --force

  # OneDarkPro
  say "Installing 'One Dark Pro' theme..." "Extension"
  install-extension zhuangtongfa.material-theme --force

  # vscode-icons
  say "Installing 'vscode-icons' theme..." "Extension"
  install-extension vscode-icons-team.vscode-icons --force

  say "done." "Extension"
}

function setCodeSettings() {
  CODEFILE="$HOME/data/User/settings.json"
  #region code-settings
  # VSCode user settings file
  say "Setting VScode base settings.($CODEFILE)" "VSCode"
  cat <<EOF | tee "$CODEFILE"
{
  "window.menuBarVisibility": "compact",
  "workbench.colorTheme": "One Dark Pro Darker",
  "workbench.iconTheme": "vscode-icons",
  "editor.fontFamily": "'FiraCode', 'FiraCode Nerd Font', 'FiraCode NF', Consolas, 'Courier New', monospace",
  "terminal.integrated.fontFamily": "'FiraCode Mono', 'FiraCode Nerd Font Mono', 'FiraCode NFM', Consolas, monospace",
  "editor.fontLigatures": true,
  "editor.formatOnSave": true,
  "extensions.autoUpdate": false,
  "git.confirmSync": false,
  "telemetry.telemetryLevel": "off"
}
EOF
  #endregion code-settings
  say "done." "VSCode"
}

function setGitConfig() {
  #echo "function arg counter is; $#"
  #echo "function args:$@"

  if [[ "$#" != "4" ]]; then
    sayE "Invalid arguments given. Please provide '<user>' and '<email>'!" "Git"
    exit 1
  fi
  if [[ -z "$3" ]]; then
    sayE "Invalid or empty username given!" "Git"
    exit 1
  fi
  if [[ -z "$4" ]]; then
    sayE "Invalid or empty email given!" "Git"
    exit 1
  fi
  say "Setting global git config..." "Git"
  git config --global user.name "$3"
  git config --global user.email "$4"
  say "Returning global config:" "Git"
  git config --list --global
}

function saveSession() {
  SESSION_FILE="$HOME/arkanum-session"
  if [[ $# -ge 3 ]]; then
    for item in "${@:3}"; do
      say "Adding '$item' to your session config" "saveSession"
      echo "$item" |  tee -a "$SESSION_FILE" > /dev/null
    done
  else
    sayE "Unknown parameter count given" "saveSession"
    exit 1
  fi
}

function restoreSession() {
  SESSION_FILE="$HOME/arkanum-session"
  if [[ -e "$SESSION_FILE" ]]; then
    while read item; do
      say "Restoring '$item'..." "restoreSession"
      arkanum install "$item"
    done <"$SESSION_FILE"
    say "Arkanum session restore completed. 🏁" "restoreSession"
  else
    sayE "There is no arkanum session!" "restoreSession"
    exit 1
  fi
}

function showSession() {
  SESSION_FILE="$HOME/arkanum-session"
  say "Trying to read your session config '$SESSION_FILE':" "showSession"
  if [[ -e "$SESSION_FILE" ]]; then
    cat "$SESSION_FILE"
  else
    sayE "There is no session defined!" "showSession"
  fi
}

function resetSession() {
  SESSION_FILE="$HOME/arkanum-session"
  say "Deleting session file '$SESSION_FILE'..." "resetSession"
  rm "$SESSION_FILE"
}
function main() {
  if [[ "$#" == "0" ]]; then
    showHelp
    exit 0
  fi

  # Command filter
  if [[ "$1" =~ ^help|-h|--h$ ]]; then
    showHelp
    exit 0
  fi

  # CONFIG command
  if [[ "$1" == "config" ]]; then
    # disable-motd option
    if [[ "$2" == "disable-motd" ]]; then
      disableMotd
      exit 0
    # install-extensions option
    elif [[ "$2" == "install-extensions" ]]; then
      instCodeExtension
      exit 0
    # reset-codesetting option
    elif [[ "$2" == "reset-codesettings" ]]; then
      setCodeSettings
      exit 0
    else
      sayE "Unknown option ($2) given for command 'config'!"
    fi
  # GIT command
  elif [[ "$1" == "git" ]]; then
    # setup option
    if [[ "$2" == "setup" ]]; then
      setGitConfig "$@"
    else
      sayE "Unknown option ($2) given for command 'git'!"
    fi
  # INSTALL command
  elif [[ "$1" == "install" ]]; then
    # docker-cli option
    if [[ "$2" == "docker-cli" ]]; then
      instDockerCLI
    elif [[ "$2" == "dotnet" ]]; then
      instDotNet
    elif [[ "$2" == "golang" ]]; then
      instGoLang "$3"
    elif [[ "$2" == "bun" ]]; then
      instBun
    elif [[ "$2" == "nodejs" ]]; then
      instVolta
      instNodeJs
    elif [[ "$2" == "volta" ]]; then
      instVolta
    elif [[ "$2" == "powershell" ]]; then
      instPwsh
    elif [[ "$2" == "gitea" ]]; then
      instGiteaTools
    elif [[ "$2" == "lazygit" ]]; then
      installLazyGit
    else
      sayE "Unknown option ($2) given for command 'install'!"
    fi
  elif [[ "$1" == "session" ]]; then
    # session option
    if [[ "$2" == "save" ]]; then
      saveSession "$@"
      exit 0
    elif [[ "$2" == "restore" ]]; then
      restoreSession
      exit 0
    elif [[ "$2" == "show" ]]; then
      showSession
      exit 0
    elif [[ "$2" == "reset" ]]; then
      resetSession
      exit 0
    else
      sayE "Unknown option ($2) given for command 'session'!"
    fi
  else
      sayE "Unknown parameter value given!($1)."
      showHelp
      exit 1
  fi
}

main "$@"
bash
#!/bin/env bash

#complete -W "--disable-motd --install-extensions --reset-codesetting docker-cli dotnet gitea golang nodejs volta powershell -h" arkanum

function _command_completions() {
  local cur prev
  cur=${COMP_WORDS[COMP_CWORD]}
  prev=${COMP_WORDS[COMP_CWORD-1]}

  case ${COMP_CWORD} in
  1)
    # shellcheck disable=2207,SC2086
    COMPREPLY=($(compgen -W "config git install help session" -- ${cur}))
    ;;
  2)
    case ${prev} in
      config)
        # shellcheck disable=2207,SC2086
        COMPREPLY=($(compgen -W "disable-motd install-extensions reset-codesettings" -- ${cur}))
        ;;
      git)
        # shellcheck disable=2207,SC2086
        COMPREPLY=($(compgen -W "setup" -- ${cur}))
        ;;
      install)
        # shellcheck disable=2207,SC2086
        COMPREPLY=($(compgen -W "docker-cli dotnet golang bun nodejs volta powershell gitea lazygit" -- ${cur}))
        ;;
      session)
        # shellcheck disable=2207,SC2086
        COMPREPLY=($(compgen -W "save restore show reset" -- ${cur}))
        ;;
      help)
      ;;
    esac
    ;;
  *)
    COMPREPLY=()
    ;;
  esac
}

complete -F _command_completions arkanum

Released under the AGPLv3 License.