Setup runcom

Table of Contents

Headers

Legend

Brackets

  • Square []: optional parts: W[orld]H[ealth]O[rganisation]
  • Angular <>: instructions to fill: <a global organisation>
  • Curly, following a dollar ${}: environment variable ${HOME}
  • Round, with bar separator: (WHO|UNO) = WHO or UNO

Requirements

Knowledge

  • Linux shell commands. We shall try to be POSIX-compliant
  • Knowledge of Linux, “dot-files”
  • super user (sudo) permissions (only for package installation)

Avoid sudo as much as possible.

Dependencies

  • A GNU/Linux distribution. I use arch btw.
  • GNU coreutils: Basic OS utilities.
  • curl for proxy authentication.
  • GNU stow: dot-file management
  • git: git it.

For Alpine Linux, enable the community repository.

  • If you are using Alpine, you MUST know how.

Bootstrap installation of dependencies

For automated installation of dependencies, run the dependencies script with elevated privileges.

curl -sLf "https://pradyparanjpe.gitlab.io/runcom/setup/dependencies.sh" | sudo sh

Inspecting scripts before running them (especially with sudo) is always a good idea. The dependencies script is tangled (with automation wrappers) from the code below. If you feel an urge to inspect it or if it fails, install dependencies manually instead, that’s all it does.

Guide for manual installation of dependencies.

Use suitable package manager (apt|apk|dnf|pacman|zypper) to install coreutils, curl, git, stow. It may be useful to update existing packages and repository database before installing packages.

  • dnf: Fedora, RockyLinux, RHEL, CentOS
    dnf -y update || return 65
    dnf -y install coreutils curl git stow || return 66
    
  • apk: Alpine Linux
    apk update || return 65
    apk --virtual runcom add coreutils curl git stow || return 66
    
  • apt: Debian, Ubuntu
    apt update || return 65
    apt install -y coreutils curl git stow || return 66
    
  • zypper: OpenSuSE, SuSE
    zypper ref || return 65
    zypper -n install coreutils curl git stow || return 66
    
  • pacman: Arch, Manjaro
    pacman --noconfirm -Syu coreutils curl git stow || return 65
    
  • brew: Mac (untested)
    brew update || return 65
    brew install coreutils curl git stow || return 66
    

Set-up

Do NOT use sudo during set-up.

The next steps require you to delete all stowed dotfiles. We shall copy them in a directory named ${XDG_CACHE_HOME:-${HOME}/.cache}/OLD_CONFIG before proceeding. Preserve this backup, you will need this during undoing set-up.

  • You HAVE BEEN warned.

Bootstrap set-up using script

Set-up may be bootstrapped by running the setup script.

curl -sLf "https://pradyparanjpe.gitlab.io/runcom/setup/setup.sh" | sh

Inspecting scripts before running them is generally a good idea. The set-up script is tangled (with automation wrappers) from the code below. If you feel an urge to inspect it or if it fails, follow manual set-up instructions with modifications instead.

Guide for manual set-up.

Clone the repository and place at ${RUNCOMDIR}

RUNCOMDIR="${HOME}/.runcom"
git clone --recurse-submodules \
    "https://gitlab.com/pradyparanjpe/runcom" \
    "${RUNCOMDIR}" || exit 1

Stow dot-files

  • Optionally, edit stow’s local ignore file

    Use following as a template and place it at dotfiles/.stow-local-ignore.

    ## Stow ignore
    ## See runcom's 'Unsubscription from configuration'
    ## See https://www.gnu.org/software/stow/manual/html_node/Ignore-Lists.html
    #
    ## Uncomment appropriate lines to unsubscribe. (remove the '# ')
    ## Comment for subscribe.
    #
    ## Configuration
    \.config/
    # \.config/qt5ct
    #
    ## local bin
    # \.local/bin
    #
    ## profile
    # \.profile\.d
    # \.profile\.d/auth
    #
    ## shrc
    # \.shrc\.d
    # \.shrc\.d/alternatives
    # \.shrc\.d/
    

    Or copy it. This ignore-file, being gitignored, will not be altered upon upstream edits.

    cp --update=none "${RUNCOMDIR}/setup/dot-stow-local-ignore" \
       "${RUNCOMDIR}/dotfiles/.stow-local-ignore"
    

    Before going ahead, edit the file ${RUNCOMDIR}/dotfiles/.stow-local-ignore to unsubscribe some files.

    • My configuration .config is ignored by default; because opt-In is better than opt-out. To subscribe to some of my personal configuration, comment out the \.config/ entry.
    • Read GNU stow’s ignore-list for fine-grained control
  • Preserve ’current’ configuration
    # RUNCOM backup
    This directory contains a backup of configuration that existed before runcom was setup.
    Files in this directory may be merged to their respective place after inspection.
    A corresponding entry should be added to the `RUNCOMDIR/dotfiles/.stow-local-ignore`.
    I recommend that this directory should **NOT** be deleted.
    It will be required to undo the setup.
    
    See [Runcom setup](https://pradyparanjpe.github.io/runcom/setup.html).
    

    Create a directory to store current configuration in a visible folder in ${XDG_CACHE_HOME}. Place the above README.md that describes this directory.

    presence="${XDG_CACHE_HOME:-${HOME}/.cache}/OLD_CONFIG"
    mkdir -p "${presence}"
    cp --update=none "${RUNCOMDIR}/setup/backup.md" "${presence}/README.md"
    
  • Move conflicting files to OLD_CONFIG.
    stow --simulate --no-folding --dotfiles --verbose --stow \
         -t "${HOME}" \
         -d "${RUNCOMDIR}/" \
         dotfiles 2>&1 >/dev/null \
        | grep -o 'target \+\S\+\? ' \
        | cut -d' ' -f2 \
        | xargs -I{} mv {} "${presence}"/{}
    
  • Use GNU stow to create symlinked structure for all contents in ${RUNCOMDIR}/dotfiles in ${HOME}.

    With the following options, if stow finds a pre-existing directory, symlinks are created inside that directory. If stow finds a pre-existing file (non-directory), it throws error.

    if stow --no-folding --dotfiles -v --restow \
            -t "${HOME}" \
            -d "${RUNCOMDIR}" \
            dotfiles ; then
    
        # Engrave RUNCOMDIR path
        mkdir -p "${HOME}/.profile.d/base_path"
        printf "RUNCOMDIR=\"%s\"\nexport RUNCOMDIR\n" "${RUNCOMDIR}" \
               > "${HOME}/.profile.d/00-base-path"
    else
        # stow threw error
        stow_error="$?"
        printf "Fix above errors and try again."
        exit "${stow_error}"
    fi
    

Set up HOMEs for Languages

Cargo (RUST), GO clutter ${HOME} with its data. Put it at the right place. Cargo’s binaries, GOBIN should be installed in ${XDG_DATA_HOME}/../bin like python3.

# @description
# Move root of LANGuage named as (HOME/$1) to XDG_DATA_HOME/$1. e.g. ".cargo"
#  Any leading dots are stripped to unhide.
# Set Language ROOT Variable ($2) to point to that location. e.g. "CARGO_HOME"
# Symlink ($3) bin location relative to ROOT to "XDG_DATA_HOME/../bin/".
#   E.g. bin: ROOT/bin -> "XDG_DATA_HOME/../bin/". Default: bin
# Set BINVAR ($4) to point to "XDG_DATA_HOME/../bin/". e.g. GOBIN.
move_roots () {
    local_bin="$(realpath "${XDG_DATA_HOME:-${HOME}/.local/share}/../bin")"
    lang_home="${XDG_DATA_HOME:-${HOME}/.local/share}/${1##*.}"
    bad_lang_home="${HOME}/${1}"
    root_lang_bin="${lang_home}/${3:-bin}"
    if [ -d "${bad_lang_home}" ] && [ ! -L "${bad_lang_home}" ]; then
        printf "Moving %s to a better location, %s.\n" "${bad_lang_home}" \
               "${lang_home}"
        mv "${bad_lang_home}" "${lang_home}"
    fi
    eval "${2}=\"${lang_home}\""
    export "${2?}"
    if [ ! "$(readlink -f "${root_lang_bin}")" = "${local_bin}" ]; then
        mv -t "${local_bin}" "${root_lang_bin}"/* 2>&1
        rmdir "${root_lang_bin}"
        ln -s "${local_bin}" "${root_lang_bin}"
    fi
    if [ -n "${4}" ]; then
        eval "${4}=${local_bin}"
        export "${4?}"
    fi
    unset local_bin lang_home bad_lang_home root_lang_bin
}

Move roots for CARGO_HOME and GOPATH to ${XDG_DATA_HOME}.

move_roots .cargo CARGO_HOME
move_roots go GOPATH

TODO: Add more languages.

  • Remember to keep the repository updated.
git pull --recurse-submodules

Undo Set-up

Do NOT use sudo during unset.

  • The next steps will require a directory containing ’old configuration files’.
  • You HAD BEEN warned against deleting it during the set-up.

Bootstrap unset using script

  • Unset may be bootstrapped by running the unset script.
curl -sLf "https://pradyparanjpe.gitlab.io/runcom/setup/unset.sh" | sh

Inspecting scripts before running them is generally a good idea. The unset script is tangled (with automation wrappers) from the code below. If you feel an urge to inspect it or if it fails, follow manual unset instructions with modifications instead.

Guide to manually undo set-up.

UnStow dot-files

Use GNU stow to unstow to un-linked structure for all contents in ${RUNCOMDIR}/dotfiles from ${HOME}.

  • RUNCOMDIR

    We expect $RUNCOMDIR to be set via ${HOME}/.profile. Set it by hand otherwise.

    RUNCOMDIR="${RUNCOMDIR:-${HOME}/.runcom}"
    
  • UnStow
    stow -v -t "${HOME}" -d "${RUNCOMDIR}" -D dotfiles
    
  • Restore directories form ${XDG_CACHE_HOME:-${HOME}/.cache}/OLD_CONFIG

    Replace the target directory ${1:-${XDG_CACHE_HOME:-${HOME}/.cache}/OLD_CONFIG} in following code block with <path/to/old/config/directory>.

    for conf_dir in "${1:-${XDG_CACHE_HOME:-${HOME}/.cache}/OLD_CONFIG}"/*; do
        cp -r "${conf_dir}" "${HOME}"/. || break
    done
    
    # shellcheck disable=SC2181
    if [ $? -ne 0 ]; then
        printf "Restoration unsuccessful, copy backup files manually.\n"
    else
        printf "Restoration successful, backup directory may be deleted.\n"
    fi
    

Delete runcom

Goodbye

rm -rf "${RUNCOMDIR}" && printf "Goodbye 👋\n"

Restore LANG_HOME

Move ${XDG_DATA_HOME}/LANG to ${HOME}/.LANG.

# @description
# Move root of LANGuage named as XDG_DATA_HOME/$1 back to (HOME/$1). e.g. ".cargo"
#  Any leading dots are stripped to unhide.
# Unset Language ROOT Variable ($2). e.g. "CARGO_HOME"
# Let the symlinked bin to remain at "XDG_DATA_HOME/../bin/"
# Unset BINVAR ${3} e.g. GOBIN.
move_roots () {
    local_bin="$(realpath "${XDG_DATA_HOME:-${HOME}/.local/share}/../bin")"
    lang_home="${XDG_DATA_HOME:-${HOME}/.local/share}/${1##*.}"
    bad_lang_home="${HOME}/${1}"
    root_lang_bin="${lang_home}/${3:-bin}"
    if [ -d "${lang_home}" ] && [ ! -L "${lang_home}" ] && [ -L "${bad_lang_home}" ]; then
        rm "${bad_lang_home}"
        printf "Moving %s back to canonical location, %s.\n" \
               "${lang_home}" "${bad_lang_home}"
        mv "${lang_home}" "${bad_lang_home}"
        unset "${2?}" "${4?}"
        export "${2?}" "${4?}"
    fi
    unset local_bin lang_home bad_lang_home root_lang_bin
}
move_roots .cargo CARGO_HOME
move_roots go GOPATH

Personalization

  • To disable ui launch from /dev/tty*, set export environment variable RUNCOM_LAUNCH_UI=false in ~/.profile.d/UI.

Proxy settings

Read set up for proxy_send.

Author: Pradyumna Paranjape

Created: Thu, 2024-07-18 10:40+0530

Validate