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 ot include all possible frameworks. This decision also helps to give the use the ability to manage the needed framework versions like for NodeJS or Golang.

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.

  Example 1: arkanum git setup "my-name" "my-email"
  Example 2: arkanum install golang
  Example 3: arkanum config disable-motd
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

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.

  Example 1: arkanum git setup "my-name" "my-email"
  Example 2: arkanum install golang
  Example 3: arkanum config disable-motd
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 \
    libicu70

  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 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
    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" -- ${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}))
        ;;
      help)
      ;;
    esac
    ;;
  *)
    COMPREPLY=()
    ;;
  esac
}

complete -F _command_completions arkanum

Released under the AGPLv3 License.