From b67a76d0da2747284ee046126d53eb60f338dd82 Mon Sep 17 00:00:00 2001 From: yage Date: Sat, 19 Sep 2026 23:27:44 -0600 Subject: [PATCH] working through some setup fixes -> good checkpoint --- README.md | 24 +- scwrypts/dotwryn/dotwryn.scwrypts.zsh | 2 +- scwrypts/dotwryn/office/vim/vundle/update | 2 +- scwrypts/remote/tmux/manager | 2 +- setup/config.zsh | 171 +++++++------- setup/git.zsh | 50 ++--- setup/os-dependencies/arch.min.txt | 1 + setup/os-dependencies/arch.txt | 3 +- setup/os-dependencies/debian.min.txt | 12 + setup/os-dependencies/debian.txt | 4 + setup/os-dependencies/fedora.min.txt | 15 ++ setup/os-dependencies/fedora.txt | 3 +- setup/os-dependencies/generic.txt | 1 + setup/os-dependencies/macos.min.txt | 14 ++ setup/os-dependencies/macos.txt | 3 + setup/os.zsh | 260 ++++++++++++++-------- setup/requirements.zsh | 41 +++- setup/run | 48 ++-- 18 files changed, 410 insertions(+), 246 deletions(-) create mode 100644 setup/os-dependencies/debian.min.txt create mode 100644 setup/os-dependencies/fedora.min.txt create mode 100644 setup/os-dependencies/macos.min.txt diff --git a/README.md b/README.md index 48bfee2..2a18879 100644 --- a/README.md +++ b/README.md @@ -9,17 +9,19 @@ This serves as CI/CD for the ZSH library and a convenient, root-privileged conta ## Setup / Configuration The setup script is the pride and joy of this project. -Running an [interactive installer](./setup/linux) removes the hassle of setting up a new computer by configuring symlinks, installing applications, and synchronizing media with the cloud. +Running the [interactive installer](./setup/run) removes the hassle of setting up a new computer by configuring symlinks, installing applications, and synchronizing media with the cloud. -After running the setup, [default configurations](./env) can be overridden by editing the appropriate local configuration (`~/.config/wryn/env`). +After running the setup, default configurations can be overridden by editing the appropriate local configuration (`~/.config/wryn/env.*`). ## System Breakdown -`.wryn/MODULE` | Description -------------------------------- | -------------------------------------- -[setup/](./setup) | os-specific setup / update utilities -[colorschemes/](./colorschemes) | 16-color terminal colorschemes; see [colors](./zsh/colors) to see how these are loaded -[config/](./config) | general configuration; appropriate `~/.config` files are symlinked on setup -[resume/](./resume) | my working resume in `.tex` format -[vim/](./vim) | `vim` keybindings, plugins, and dictionary binary; activated by an [entry rc](./vim/rc.vim) -[zsh/](./zsh) | `zsh` aliases, functions, and plugins; activated by an [entry rc](./zsh/rc) -[zsh/plugins](./zsh/plugins) | external `zsh` plugins + + +| `.wryn/MODULE` | Description | +| ------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | +| [setup/](./setup) | os-specific setup / update utilities | +| [config/](./config) | general configuration (including [colorschemes](./config/colorschemes)); appropriate `~/.config` files are symlinked on setup | +| [resume/](./resume) | my working resume in `.tex` format | +| [vim/](./vim) | `vim` keybindings, plugins, and dictionary binary; activated by an [entry rc](./vim/rc.vim) | +| [zsh/](./zsh) | `zsh` aliases, functions, and plugins; activated by an [entry rc](./zsh/rc) | +| [zsh/plugins](./zsh/plugins) | external `zsh` plugins | + diff --git a/scwrypts/dotwryn/dotwryn.scwrypts.zsh b/scwrypts/dotwryn/dotwryn.scwrypts.zsh index 98cbb75..534c00e 100644 --- a/scwrypts/dotwryn/dotwryn.scwrypts.zsh +++ b/scwrypts/dotwryn/dotwryn.scwrypts.zsh @@ -6,7 +6,7 @@ readonly ${scwryptsgroup}__color=$(utils.colors.red) [ "${DOTWRYN}" ] \ || export DOTWRYN=$(git -C "${0:a:h}" rev-parse --show-toplevel 2>/dev/null) -export DOTWRYN_HOSTNAME=$(hostnamectl --static) +export DOTWRYN_HOSTNAME=$(hostnamectl --static 2>/dev/null || hostname 2>/dev/null | sed 's/\.local$//') [ "${XDG_CONFIG_HOME}" ] \ || export XDG_CONFIG_HOME="${HOME}/.config" diff --git a/scwrypts/dotwryn/office/vim/vundle/update b/scwrypts/dotwryn/office/vim/vundle/update index 2de25c4..70c90b6 100755 --- a/scwrypts/dotwryn/office/vim/vundle/update +++ b/scwrypts/dotwryn/office/vim/vundle/update @@ -2,6 +2,6 @@ use office/vim/vundle --group dotwryn ##################################################################### -dotwryn.office.vim.vundle.parse.usage +dotwryn.office.vim.vundle.update.parse.usage MAIN() { dotwryn.office.vim.vundle.update $@; } diff --git a/scwrypts/remote/tmux/manager b/scwrypts/remote/tmux/manager index e7bfb1b..0accb67 100755 --- a/scwrypts/remote/tmux/manager +++ b/scwrypts/remote/tmux/manager @@ -3,7 +3,7 @@ # must work as a standalone zsh script # eval "$(scwrypts --config)" \ - && use --group omni \ + && use --group remote omni \ && utils.check-environment \ || { echo 'scwrypts config error; aborting' >&2; sleep 5; return 1; } diff --git a/setup/config.zsh b/setup/config.zsh index 787193d..546f99b 100644 --- a/setup/config.zsh +++ b/setup/config.zsh @@ -1,161 +1,170 @@ -function SETUP__CONFIG() { - STATUS 'starting application configuration' +setup.config() { + echo.status 'starting application configuration' - GENERATE_INITIAL_LOCAL_CONFIG + setup.config._.generate-initial-local-config - CONFIG__ZSH || return 2 - CONFIG__VIM || return 3 + setup.config._.zsh || return 2 + setup.config._.vim || return 3 - CONFIG__SYSTEM || return 4 + setup.config._.system || return 4 SCWRYPTS generate i3 config || return 5 - SUCCESS 'finished application configuration' + echo.success 'finished application configuration' } ##################################################################### -GENERATE_INITIAL_LOCAL_CONFIG() { - local HOSTNAME="$(hostnamectl --static 2>/dev/null || hostname | sed 's/\.local$//' 2>/dev/null)" - [ ${HOSTNAME} ] || return 0 +setup.config._.generate-initial-local-config() { + local local_hostname="$(hostnamectl --static 2>/dev/null || hostname 2>/dev/null | sed 's/\.local$//')" + [ "${local_hostname}" ] || return 0 - mkdir -p "${DOTWRYN_PATH}/bin/${HOSTNAME}" + mkdir -p "${DOTWRYN_PATH}/bin/${local_hostname}" - local ENV_DIR="${DOTWRYN_PATH}/config/scwrypts/environments" - local GROUP - for GROUP in $(find "${ENV_DIR}" -type f -name \*env.yaml | sed -n 's|.*/local\.\([^.]*\)\.env\.yaml|\1|p') + local env_dir="${DOTWRYN_PATH}/config/scwrypts/environments" + local group + for group in $(find "${env_dir}" -type f -name \*env.yaml | sed -n 's|.*/local\.\([^.]*\)\.env\.yaml|\1|p') do - [ -f "${ENV_DIR}/local.${HOSTNAME}.${GROUP}.env.yaml" ] \ - || cp "${ENV_DIR}/local.altaria.${GROUP}.env.yaml" "${ENV_DIR}/local.${HOSTNAME}.${GROUP}.env.yaml" - done + [ -f "${env_dir}/local.${local_hostname}.${group}.env.yaml" ] && continue - local LOCAL_OVERRIDE - for LOCAL_OVERRIDE in \ + if [ -f "${env_dir}/local.altaria.${group}.env.yaml" ] + then + cp "${env_dir}/local.altaria.${group}.env.yaml" "${env_dir}/local.${local_hostname}.${group}.env.yaml" + else + cp "${env_dir}/local.${group}.env.yaml" "${env_dir}/local.${local_hostname}.${group}.env.yaml" + fi + done + unset group + + local local_override + for local_override in \ i3/local.yaml \ polybar/local.ini \ alacritty/local.toml \ ; do - mkdir -p -- "${DOTWRYN_PATH}/config/${HOSTNAME}/user/$(dirname -- "${LOCAL_OVERRIDE}")" - touch -- "${DOTWRYN_PATH}/config/${HOSTNAME}/user/${LOCAL_OVERRIDE}" + mkdir -p -- "${DOTWRYN_PATH}/config/${local_hostname}/user/$(dirname -- "${local_override}")" + touch -- "${DOTWRYN_PATH}/config/${local_hostname}/user/${local_override}" done + unset local_override } ##################################################################### -CONFIG__ZSH() { - CONFIG__ENV zsh || return 1 - CONFIG__RC zsh || return 2 - CONFIG__SET_DEFAULT_SHELL || return 3 +setup.config._.zsh() { + setup.config._.env zsh || return 1 + setup.config._.rc zsh || return 2 + setup.config._.set-default-shell || return 3 } -CONFIG__SET_DEFAULT_SHELL() { - local DEFAULT_SHELL=$(awk -F: -v user="${USER}" '$1 == user {print $NF}' /etc/passwd) - [[ ${DEFAULT_SHELL} =~ zsh ]] && return 0 +setup.config._.set-default-shell() { + local default_shell="$(awk -F: -v user="${USER}" '$1 == user {print $NF}' /etc/passwd)" + [[ "${default_shell}" =~ zsh ]] && return 0 - [ ${FORCE_ROOT} ] && return 0 + [[ "${FORCE_ROOT}" == true ]] && return 0 - STATUS 'setting zsh as default shell' - sudo chsh -s $(which zsh) $(whoami) 2>&1 \ - && SUCCESS "set zsh as default shell for '${USER}'" \ - || FAIL 1 'failed to set zsh as default shell' \ + echo.status 'setting zsh as default shell' + sudo chsh -s "$(which zsh)" "$(whoami)" 2>&1 \ + && echo.success "set zsh as default shell for '${USER}'" \ + || utils.fail 1 'failed to set zsh as default shell' \ ; } ##################################################################### -CONFIG__VIM() { - CONFIG__RC vim || return 1 +setup.config._.vim() { + setup.config._.rc vim || return 1 - STATUS 'starting vim setup' + echo.status 'starting vim setup' SCWRYPTS dotwryn vundle update || return 2 - CONFIG__VIM__LINK_SUPERUSER_RC + setup.config._.vim.link-superuser-rc return 0 } -CONFIG__VIM__LINK_SUPERUSER_RC() { - sudo [ /root/.vimrc ] && return 0 +setup.config._.vim.link-superuser-rc() { + sudo [ -f /root/.vimrc ] && return 0 echo "let \$DOTWRYN=\"${DOTWRYN_PATH}\"\nsource \"${DOTWRYN_PATH}/vim/rc.vim\"" \ | sudo tee /root/.vimrc >/dev/null sudo mkdir -p /root/.vim - sudo ln -s /home/w0ryn/.vim/bundle /root/.vim/bundle + sudo ln -s "${HOME}/.vim/bundle" /root/.vim/bundle } ##################################################################### -CONFIG__SYSTEM() { +setup.config._.system() { SCWRYPTS dotwryn system setup } ##################################################################### -CONFIG__ENV() { - local DEFAULT_CONFIG="${DOTWRYN_PATH}/$1/env.$1" - local LOCAL_CONFIG="${HOME}/.config/wryn/env.$1" +setup.config._.env() { + local config_type="${1}" + local default_config="${DOTWRYN_PATH}/${config_type}/env.${config_type}" + local local_config="${HOME}/.config/wryn/env.${config_type}" - [ -f ${LOCAL_CONFIG} ] && { - case ${OVERWRITE_EXISTING} in - 0 ) return 0 ;; - 1 ) - WARNING "local $1 configuration exists (${LOCAL_CONFIG})" - yN 'overwrite this configuration?' || return 0 + [ -f "${local_config}" ] && { + case "${OVERWRITE_EXISTING}" in + ( false ) return 0 ;; + ( true ) + echo.warning "local ${config_type} configuration exists (${local_config})" + utils.yN 'overwrite this configuration?' || return 0 - mv "${LOCAL_CONFIG}" "${LOCAL_CONFIG}.bak" >/dev/null 2>&1 \ - && INFO "created backup of local configuration (${LOCAL_CONFIG}.bak)" + mv "${local_config}" "${local_config}.bak" >/dev/null 2>&1 \ + && echo.status "created backup of local configuration (${local_config}.bak)" + ;; esac } - STATUS "setting up $1 configuration (${LOCAL_CONFIG})" + echo.status "setting up ${config_type} configuration (${local_config})" - case $1 in - zsh ) COMMENT='#' ;; + local comment + case "${config_type}" in + ( zsh ) comment='#' ;; esac { - echo "source ${DEFAULT_CONFIG}" - echo -e "\\n${COMMENT}\n${COMMENT} .wryn configuration overrides\n${COMMENT}\n" - sed "s/^[^${COMMENT}].*/${COMMENT}&/" ${DEFAULT_CONFIG} - } > ${LOCAL_CONFIG} \ - && SUCCESS "created $1 configuration" \ - || FAIL 1 "unable to create $1 configuration" \ + echo "source ${default_config}" + echo -e "\\n${comment}\n${comment} .wryn configuration overrides\n${comment}\n" + sed "s/^[^${comment}].*/${comment}&/" "${default_config}" + } > "${local_config}" \ + && echo.success "created ${config_type} configuration" \ + || utils.fail 1 "unable to create ${config_type} configuration" \ ; - EDITOR=vim VISUAL=vim EDIT "${LOCAL_CONFIG}" + EDITOR=vim VISUAL=vim utils.io.edit "${local_config}" } -CONFIG__RC() { - local TYPE="$1" - local RC - case ${TYPE} in - vim ) - RC="${XDG_CONFIG_HOME:-${HOME}/.config}/vim/vimrc" - mkdir -p -- "$(dirname -- "${RC}")" +setup.config._.rc() { + local config_type="${1}" + local rc + case "${config_type}" in + ( vim ) + rc="${XDG_CONFIG_HOME:-${HOME}/.config}/vim/vimrc" + mkdir -p -- "$(dirname -- "${rc}")" [ -f "${HOME}/.vimrc" ] \ && cat "${HOME}/.vimrc" >> "${XDG_CONFIG_HOME:-${HOME}/.config}/vim/vimrc" \ && rm "${HOME}/.vimrc" \ ; ;; - * ) RC="${HOME}/.${TYPE}rc"; - ;; + ( * ) rc="${HOME}/.${config_type}rc" ;; esac - local SOURCE_LINE - case ${TYPE} in - zsh ) SOURCE_LINE="source ${DOTWRYN_PATH}/zsh/rc" ;; - vim ) SOURCE_LINE="source ${DOTWRYN_PATH}/vim/rc.vim" ;; + local source_line + case "${config_type}" in + ( zsh ) source_line="source ${DOTWRYN_PATH}/zsh/rc" ;; + ( vim ) source_line="source ${DOTWRYN_PATH}/vim/rc.vim" ;; esac + grep -q "^${source_line}$" "${rc}" \ + || echo "${source_line}" >> "${rc}" - grep -q "^${SOURCE_LINE}$" "${RC}" \ - || echo "${SOURCE_LINE}" >> ${RC} - - grep -q "^${SOURCE_LINE}$" "${RC}" \ - && SUCCESS "${TYPE}rc is configured correctly" \ - || FAIL 1 "failed to configure ${TYPE}rc" \ + grep -q "^${source_line}$" "${rc}" \ + && echo.success "${config_type}rc is configured correctly" \ + || utils.fail 1 "failed to configure ${config_type}rc" \ ; } diff --git a/setup/git.zsh b/setup/git.zsh index a8a8553..8194a03 100644 --- a/setup/git.zsh +++ b/setup/git.zsh @@ -1,74 +1,74 @@ ##################################################################### -SETUP__GIT() { - local SOURCES_DIR="${XDG_DATA_HOME:-${HOME}/.local/share}/project-source-code" +setup.git() { + local sources_dir="${XDG_DATA_HOME:-${HOME}/.local/share}/project-source-code" SOURCE_DIR="${DOTWRYN_PATH}" \ - TARGET_DIR="${SOURCES_DIR}/yage/dotwryn" \ + TARGET_DIR="${sources_dir}/yage/dotwryn" \ REMOTE_UPSTREAMS=( 'git@github.com:wrynegade/dotwryn.git' 'git@yage.io:wrynegade/dotwryn.git' 'git@bitbucket.org:wrynegade/dotwryn.git' - ) SETUP__GIT__REMOTES '.wryn' + ) setup.git._.remotes '.wryn' SOURCE_DIR="${DOTWRYN_PATH}/zsh/plugins/code-activator" \ - TARGET_DIR="${SOURCES_DIR}/zsh/code-activator" \ + TARGET_DIR="${sources_dir}/zsh/code-activator" \ REMOTE_UPSTREAMS=( 'git@yage.io:zsh/code-activator.git' 'git@github.com:wrynegade/code-activator.git' - ) SETUP__GIT__REMOTES 'zsh-plugins/code-activator' + ) setup.git._.remotes 'zsh-plugins/code-activator' SOURCE_DIR="${DOTWRYN_PATH}/zsh/plugins/scwrypts" \ - TARGET_DIR="${SOURCES_DIR}/zsh/scwrypts" \ + TARGET_DIR="${sources_dir}/zsh/scwrypts" \ REMOTE_UPSTREAMS=( 'git@yage.io:zsh/scwrypts' 'git@github.com:wrynegade/scwrypts' - ) SETUP__GIT__REMOTES 'zsh-plugins/scwrypts' + ) setup.git._.remotes 'zsh-plugins/scwrypts' return 0 } -SETUP__GIT__REMOTES() { +setup.git._.remotes() { : \ && [ "${SOURCE_DIR}" ] \ && [ "${TARGET_DIR}" ] \ && [[ ${#REMOTE_UPSTREAMS[@]} -gt 0 ]] \ || return 1 - [ "$1" ] && STATUS "updating remotes for '$1'" + [ "$1" ] && echo.status "updating remotes for '$1'" git -C "${SOURCE_DIR}" remote rm upstream 2>/dev/null - git -C "${SOURCE_DIR}" remote add upstream ${REMOTE_UPSTREAMS[1]} + git -C "${SOURCE_DIR}" remote add upstream "${REMOTE_UPSTREAMS[1]}" - local REMOTE_UPSTREAM - for REMOTE_UPSTREAM in ${REMOTE_UPSTREAMS[@]} + local remote_upstream + for remote_upstream in "${REMOTE_UPSTREAMS[@]}" do - git -C "${SOURCE_DIR}" remote set-url --add --push upstream "${REMOTE_UPSTREAM}" + git -C "${SOURCE_DIR}" remote set-url --add --push upstream "${remote_upstream}" - case ${REMOTE_UPSTREAM} in - git@github.com:* ) + case "${remote_upstream}" in + ( git@github.com:* ) git -C "${SOURCE_DIR}" remote rm github 2>/dev/null - git -C "${SOURCE_DIR}" remote add github "${REMOTE_UPSTREAM}" + git -C "${SOURCE_DIR}" remote add github "${remote_upstream}" ;; - git@yage.io:* ) + ( git@yage.io:* ) git -C "${SOURCE_DIR}" remote rm yage 2>/dev/null - git -C "${SOURCE_DIR}" remote add yage "${REMOTE_UPSTREAM}" + git -C "${SOURCE_DIR}" remote add yage "${remote_upstream}" ;; - git@bitbucket.org:* ) + ( git@bitbucket.org:* ) git -C "${SOURCE_DIR}" remote rm bitbucket 2>/dev/null - git -C "${SOURCE_DIR}" remote add bitbucket "${REMOTE_UPSTREAM}" + git -C "${SOURCE_DIR}" remote add bitbucket "${remote_upstream}" ;; esac done + unset remote_upstream - SOURCE_DIR="${SOURCE_DIR}" TARGET_DIR="${TARGET_DIR}" SETUP__GIT__LINK_TO_PROJECTS || { - WARNING "failed to link '${TARGET_DIR}'" - } + SOURCE_DIR="${SOURCE_DIR}" TARGET_DIR="${TARGET_DIR}" setup.git._.link-to-projects \ + || echo.warning "failed to link '${TARGET_DIR}'" return 0 } -SETUP__GIT__LINK_TO_PROJECTS() { +setup.git._.link-to-projects() { [ "${TARGET_DIR}" ] && [ "${SOURCE_DIR}" ] \ || return 1 diff --git a/setup/os-dependencies/arch.min.txt b/setup/os-dependencies/arch.min.txt index 5fee309..1eceef1 100644 --- a/setup/os-dependencies/arch.min.txt +++ b/setup/os-dependencies/arch.min.txt @@ -6,6 +6,7 @@ figlet fzf go-yq htop +jo jq lolcat ncurses diff --git a/setup/os-dependencies/arch.txt b/setup/os-dependencies/arch.txt index 83d7f25..f9cfd0a 100644 --- a/setup/os-dependencies/arch.txt +++ b/setup/os-dependencies/arch.txt @@ -18,12 +18,13 @@ google-chrome htop i3-wm jdk-openjdk +jo jq lolcat lxappearance mono ncurses -neofetch +fastfetch nodejs noto-fonts-emoji npm diff --git a/setup/os-dependencies/debian.min.txt b/setup/os-dependencies/debian.min.txt new file mode 100644 index 0000000..3aa2d6c --- /dev/null +++ b/setup/os-dependencies/debian.min.txt @@ -0,0 +1,12 @@ +bsdextrautils +build-essential +cmake +cowsay +figlet +fzf +jo +jq +ncurses-dev +ripgrep +tmux +uuid-runtime diff --git a/setup/os-dependencies/debian.txt b/setup/os-dependencies/debian.txt index b64c770..dd58ca3 100644 --- a/setup/os-dependencies/debian.txt +++ b/setup/os-dependencies/debian.txt @@ -1,4 +1,5 @@ awscli +bsdextrautils build-essential cmake cowsay @@ -6,6 +7,8 @@ default-jdk figlet fzf golang +jo +jq lolcat mono-devel ncurses-dev @@ -14,3 +17,4 @@ npm python3-dev ripgrep tmux +uuid-runtime diff --git a/setup/os-dependencies/fedora.min.txt b/setup/os-dependencies/fedora.min.txt new file mode 100644 index 0000000..5e8eeb8 --- /dev/null +++ b/setup/os-dependencies/fedora.min.txt @@ -0,0 +1,15 @@ +bat +cmake +cowsay +figlet +fzf +htop +jo +jq +lolcat +ncurses +python3-devel +ripgrep +tmux +vim-enhanced +yq diff --git a/setup/os-dependencies/fedora.txt b/setup/os-dependencies/fedora.txt index 075b59d..fa4e1d3 100644 --- a/setup/os-dependencies/fedora.txt +++ b/setup/os-dependencies/fedora.txt @@ -21,12 +21,13 @@ gnupg2 go htop java-latest-openjdk +jo jq libtool lolcat mono-complete ncurses -neofetch +fastfetch nodejs npm openssh diff --git a/setup/os-dependencies/generic.txt b/setup/os-dependencies/generic.txt index 0d18ab9..1d7ffc6 100644 --- a/setup/os-dependencies/generic.txt +++ b/setup/os-dependencies/generic.txt @@ -5,6 +5,7 @@ figlet fzf go java +jo jq lolcat ncurses diff --git a/setup/os-dependencies/macos.min.txt b/setup/os-dependencies/macos.min.txt new file mode 100644 index 0000000..349e8b2 --- /dev/null +++ b/setup/os-dependencies/macos.min.txt @@ -0,0 +1,14 @@ +bat +cmake +cowsay +figlet +fzf +htop +jo +jq +lolcat +ncurses +python +ripgrep +tmux +vim diff --git a/setup/os-dependencies/macos.txt b/setup/os-dependencies/macos.txt index 087bfbc..7d53bc0 100644 --- a/setup/os-dependencies/macos.txt +++ b/setup/os-dependencies/macos.txt @@ -6,6 +6,7 @@ bison cmake coreutils cowsay +fastfetch feh figlet findutils @@ -21,6 +22,7 @@ grep gsed htop iproute2mac +jo jq libtool lolcat @@ -34,6 +36,7 @@ pkg-config pylint python python-setuptools +redis ripgrep rust tmux diff --git a/setup/os.zsh b/setup/os.zsh index 1a7ad9e..e91038f 100644 --- a/setup/os.zsh +++ b/setup/os.zsh @@ -1,45 +1,90 @@ ##################################################################### -SETUP__OS() { - OS__MAKE_REQUIRED_RESOURCES || return 1 - [ ${CI} ] && { STATUS 'detected CI; skipping os setup'; return 0; } - GETSUDO +setup.os() { + setup.os._.make-required-resources || return 1 + [[ "${CI}" == true ]] && { echo.status 'detected CI; skipping os setup'; return 0; } + utils.io.getsudo - local OS_NAME=$(OS__GET_OS) - [ ! ${OS_NAME} ] && ABORT + local OS_NAME="$(setup.os._.get-os)" + [ ! "${OS_NAME}" ] && utils.abort - OS__INSTALL_SOURCE_DEPENDENCIES || return 2 - OS__INSTALL_MANAGED_DEPENDENCIES || return 3 + setup.os._.install-source-dependencies || return 2 + setup.os._.install-managed-dependencies || return 3 } -OS__GET_OS() { - local OS_NAME=$(lsb_release -is 2>/dev/null | tr '[:upper:]' '[:lower:]') +setup.os._.get-os() { + local OS_NAME="$(lsb_release -is 2>/dev/null | tr '[:upper:]' '[:lower:]')" - [ ! ${OS_NAME} ] \ - && OS_NAME=$(cat /etc/os-release 2>/dev/null | sed -n 's/^ID=//p') + [ ! "${OS_NAME}" ] \ + && OS_NAME="$(sed -n 's/^ID=//p' /etc/os-release 2>/dev/null)" uname -s | grep -q Darwin \ && OS_NAME=macos - [ ! ${OS_NAME} ] \ - && WARNING 'failed to detect operating system' \ - && OS_NAME=$(echo -e "arch\ndebian\nother" | FZF 'select an operating system') \ + [ ! "${OS_NAME}" ] \ + && echo.warning 'failed to detect operating system' \ + && OS_NAME="$(echo -e "arch\ndebian\nother" | utils.fzf 'select an operating system')" \ ; - [[ ${OS_NAME} =~ ^ubuntu$ ]] && OS_NAME=debian + [[ "${OS_NAME}" =~ ^ubuntu$ ]] && OS_NAME=debian - [[ ${OS_NAME} =~ ^[Ee]ndeavour[Oo][Ss]$ ]] && OS_NAME=arch + [[ "${OS_NAME}" =~ ^[Ee]ndeavour[Oo][Ss]$ ]] && OS_NAME=arch - echo ${OS_NAME} + echo "${OS_NAME}" } ##################################################################### -OS__INSTALL_SOURCE_DEPENDENCIES() { - case ${OS_NAME} in +setup.os._.install-from-source() { # clone + build/install a git-hosted package (AUR PKGBUILD or Makefile) + local target_url="${1}" + local name="${2:-$(echo "${target_url}" | sed 's/.*\///; s/\.git$//')}" + local install_dir="${HOME}/.local/share/source-packages" + mkdir -p "${install_dir}" + + if [ -d "${install_dir}/${name}" ] + then + echo.status "updating '${name}'" + ( cd "${install_dir}/${name}" && git pull origin "$(git rev-parse --abbrev-ref HEAD)" ) \ + && echo.success "successfully updated '${name}'" \ + || { echo.error "failed to update '${name}'"; return 1; } + else + echo.status "downloading '${name}'" + git clone "${target_url}" "${install_dir}/${name}" \ + && echo.success "successfully downloaded '${name}'" \ + || { echo.error "failed to download '${name}'"; return 2; } + fi + + cd "${install_dir}/${name}" + if [ -f ./PKGBUILD ] + then + echo.status "installing '${name}'" + yes | makepkg -si \ + && echo.success "successfully installed '${name}'" \ + || { echo.error "failed to install '${name}'"; return 3; } + elif [ -f ./Makefile ] + then + echo.status "building '${name}'" + make \ + && echo.success "finished building '${name}'" \ + || { echo.error "build failed for '${name}'"; return 4; } + + echo.status "installing '${name}'" + utils.io.getsudo + sudo make install \ + && echo.success "successfully installed '${name}'" \ + || { echo.error "failed to install '${name}'"; return 5; } + else + echo.warning 'could not detect supported installation method' + echo.reminder "complete manual installation in the directory below:" + echo.reminder "${install_dir}/${name}" + fi +} + +setup.os._.install-source-dependencies() { + case "${OS_NAME}" in ( arch ) command -v yay >/dev/null 2>&1 \ - || SCWRYPTS packages/install -- 'https://aur.archlinux.org/yay.git' --local-name 'yay' \ + || setup.os._.install-from-source 'https://aur.archlinux.org/yay.git' 'yay' \ ; ;; @@ -48,59 +93,80 @@ OS__INSTALL_SOURCE_DEPENDENCIES() { ( debian ) ;; ( macos ) - command -v brew &>/dev/null \ - || /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" + xcode-select -p &>/dev/null || { # brew requires the xcode command line tools + echo.status 'installing xcode command line tools' + touch /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress + local clt_package="$(softwareupdate -l | grep '\*.*Command Line' | tail -n1 | sed 's/^[^C]*\(C.*\)/\1/')" + sudo softwareupdate -i "${clt_package}" --verbose \ + && echo.success 'successfully installed xcode command line tools' \ + || echo.error 'failed to install xcode command line tools' \ + ; + rm -f /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress + } + + command -v brew &>/dev/null || { + /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" + eval "$(/opt/homebrew/bin/brew shellenv 2>/dev/null || /usr/local/bin/brew shellenv 2>/dev/null)" + } ;; ( * ) ;; esac - [ ${COMPILE_DMENU} ] && [[ ${COMPILE_DMENU} -eq 1 ]] \ - && SCWRYPTS packages/install -- 'https://github.com/tiyn/dmenu' --local-name 'patched-dmenu' + [[ "${OS_NAME}" != macos ]] && [[ "${COMPILE_DMENU}" == true ]] \ + && setup.os._.install-from-source 'https://github.com/tiyn/dmenu' 'patched-dmenu' return 0 } ##################################################################### -OS__INSTALL_MANAGED_DEPENDENCIES() { +setup.os._.install-managed-dependencies() { local ERRORS=0 - STATUS 'checking os dependencies' - case ${OS_NAME} in + echo.status 'checking os dependencies' + case "${OS_NAME}" in ( arch | fedora | debian | macos ) ;; ( * ) OS_NAME='generic' - WARNING "no automated installer available for '${OS_NAME}'" + echo.warning "no automated installer available for '${OS_NAME}'" ;; esac - [ ${MIN} ] && [[ ${MIN} -eq 1 ]] && [ -f "${DOTWRYN_PATH}/setup/os-dependencies/${OS_NAME}.min.txt" ] \ - && DEPENDENCIES="${DOTWRYN_PATH}/setup/os-dependencies/${OS_NAME}.min.txt" \ - || DEPENDENCIES="${DOTWRYN_PATH}/setup/os-dependencies/${OS_NAME}.txt" \ + local dependencies_file + [[ "${MIN}" == true ]] && [ -f "${DOTWRYN_PATH}/setup/os-dependencies/${OS_NAME}.min.txt" ] \ + && dependencies_file="${DOTWRYN_PATH}/setup/os-dependencies/${OS_NAME}.min.txt" \ + || dependencies_file="${DOTWRYN_PATH}/setup/os-dependencies/${OS_NAME}.txt" \ ; - [ ! ${CI} ] && { - STATUS 'updating system, repositories, and mirrors' - UPDATE_REPOSITORIES__${OS_NAME} + [[ "${CI}" != true ]] && { + echo.status 'updating system, repositories, and mirrors' + "setup.os._.update-repositories.${OS_NAME}" } - for DEPENDENCY in $(cat "${DEPENDENCIES}") + local dependency + for dependency in $(cat "${dependencies_file}") do - INSTALL_MANAGED__${OS_NAME} ${DEPENDENCY} + "setup.os._.install-managed.${OS_NAME}" "${dependency}" done + unset dependency - [[ ${ERRORS} -ne 0 ]] && { - WARNING "detected ${ERRORS} errors; double check warnings before proceeding!" - yN 'continue with install?' && return 0 || ABORT + [[ "${ERRORS}" -ne 0 ]] && { + echo.warning "detected ${ERRORS} errors; double check warnings before proceeding!" + utils.yN 'continue with install?' && return 0 || utils.abort } - case ${OS_NAME} in + case "${OS_NAME}" in ( macos ) - local P - for P in "$(brew --prefix)"/opt/*/libexec/gnubin(N); do export PATH="${P}:${PATH}"; done + local shellenv_line='eval "$(/opt/homebrew/bin/brew shellenv 2>/dev/null || /usr/local/bin/brew shellenv 2>/dev/null)"' + grep -qF "${shellenv_line}" "${HOME}/.zprofile" 2>/dev/null \ + || echo "${shellenv_line}" >> "${HOME}/.zprofile" + + local gnubin_path + for gnubin_path in "$(brew --prefix)"/opt/*/libexec/gnubin(N); do export PATH="${gnubin_path}:${PATH}"; done + unset gnubin_path local gnubin_line='for P in "$(brew --prefix)"/opt/*/libexec/gnubin(N); do export PATH="${P}:${PATH}"; done' grep -qF "${gnubin_line}" "${HOME}/.zprofile" 2>/dev/null \ @@ -108,108 +174,120 @@ OS__INSTALL_MANAGED_DEPENDENCIES() { ;; esac - SUCCESS 'all dependencies satisfied' + echo.success 'all dependencies satisfied' return 0 } ########################################## -UPDATE_REPOSITORIES__arch() { yay -Syu; } -INSTALL_MANAGED__arch() { - local TARGET="$1" - [[ ${TARGET} =~ aws-cli-v2 ]] && { - STATUS "skipping aws-cli-v2 checks since they are bad right now" +setup.os._.update-repositories.arch() { yay -Syu; } +setup.os._.install-managed.arch() { + local target="${1}" + [[ "${target}" =~ aws-cli-v2 ]] && { + echo.status "skipping aws-cli-v2 checks since they are bad right now" return 0 } - yay -Qq 2>/dev/null | grep -q "^${TARGET}$\|^${TARGET}-git$" && { - SUCCESS "found '${TARGET}'" + yay -Qq 2>/dev/null | grep -q "^${target}$\|^${target}-git$" && { + echo.success "found '${target}'" } || { - STATUS "installing '${TARGET}'" - yay -Syu --noconfirm ${TARGET} \ - && SUCCESS "successfully installed '${TARGET}'" \ - || ERROR "failed to install '${TARGET}'" \ + echo.status "installing '${target}'" + yay -Syu --noconfirm "${target}" \ + && echo.success "successfully installed '${target}'" \ + || echo.error "failed to install '${target}'" \ ; } } ########################################## -UPDATE_REPOSITORIES__debian() { sudo apt-get update && sudo apt-get upgrade; } -INSTALL_MANAGED__debian() { - STATUS "checking / installing '$1'" - sudo apt-get install --yes $1 \ - && SUCCESS "'$1' installed" \ - || ERROR "failed to install $1" \ +setup.os._.update-repositories.debian() { sudo apt-get update && sudo apt-get upgrade; } +setup.os._.install-managed.debian() { + local target="${1}" + echo.status "checking / installing '${target}'" + sudo apt-get install --yes "${target}" \ + && echo.success "'${target}' installed" \ + || echo.error "failed to install ${target}" \ ; } ########################################## -UPDATE_REPOSITORIES__fedora() { +setup.os._.update-repositories.fedora() { : \ && sudo dnf update \ && sudo dnf upgrade \ && sudo dnf install -y dnf-plugins-core \ - && sudo dnf config-manager --add-repo https://download.docker.com/linux/fedora/docker-ce.repo \ + && sudo dnf config-manager addrepo --from-repofile=https://download.docker.com/linux/fedora/docker-ce.repo \ ; } -INSTALL_MANAGED__fedora() { - STATUS "checking / installing '$1'" - sudo dnf install -y $1 \ - && SUCCESS "'$1' installed" \ - || ERROR "failed to install $1" \ +setup.os._.install-managed.fedora() { + local target="${1}" + echo.status "checking / installing '${target}'" + sudo dnf install -y "${target}" \ + && echo.success "'${target}' installed" \ + || echo.error "failed to install ${target}" \ ; } ########################################## -UPDATE_REPOSITORIES__macos() { brew update && brew upgrade; } -INSTALL_MANAGED__macos() { - STATUS "checking / installing '$1'" - yes | brew install $1 \ - && SUCCESS "'$1' installed" \ - || ERROR "failed to install $1" \ - ; +setup.os._.update-repositories.macos() { brew update && brew upgrade; } +setup.os._.install-managed.macos() { + local target="${1}" + brew list --versions "${target}" &>/dev/null && { + echo.success "found '${target}'" + } || { + echo.status "installing '${target}'" + yes | brew install "${target}" \ + && echo.success "'${target}' installed" \ + || echo.error "failed to install ${target}" \ + ; + } } ########################################## -UPDATE_REPOSITORIES__generic() { return 0; } -INSTALL_MANAGED__generic() { - command -v $1 >/dev/null 2>&1 \ - || ERROR "could not find '$1'; it's up to you to install this one!" +setup.os._.update-repositories.generic() { return 0; } +setup.os._.install-managed.generic() { + local target="${1}" + command -v "${target}" >/dev/null 2>&1 \ + || echo.error "could not find '${target}'; it's up to you to install this one!" } ##################################################################### -OS__MAKE_REQUIRED_RESOURCES() { +setup.os._.make-required-resources() { local ERRORS=0 - local DIRECTORIES=( + local directories=( "${XDG_CONFIG_HOME:-${HOME}/.config}/wryn" "${HOME}/.local/bin" ) - local FILES=( + local files=( "${HOME}/.zshrc" ) - STATUS 'making required system resources' - for D in ${DIRECTORIES} + echo.status 'making required system resources' + local directory + for directory in "${directories[@]}" do - [ ! -d ${D} ] && { mkdir -p ${D} || ERROR "failed to create directory '${D}'"; } + [ ! -d "${directory}" ] && { mkdir -p "${directory}" || echo.error "failed to create directory '${directory}'"; } done + unset directory - for F in ${FILES} + local file + for file in "${files[@]}" do - [ ! -f ${F} ] && { touch ${F} || ERROR "failed to create file '${F}'"; } + [ ! -f "${file}" ] && { touch "${file}" || echo.error "failed to create file '${file}'"; } done + unset file - [[ ${ERRORS} -eq 0 ]] \ - && SUCCESS 'finished creating system resources' \ - || ERROR 'failed to create system resources' \ + [[ "${ERRORS}" -eq 0 ]] \ + && echo.success 'finished creating system resources' \ + || echo.error 'failed to create system resources' \ ; - return ${ERRORS} + return "${ERRORS}" } diff --git a/setup/requirements.zsh b/setup/requirements.zsh index 3c7bd72..26fa32e 100644 --- a/setup/requirements.zsh +++ b/setup/requirements.zsh @@ -1,4 +1,4 @@ -[[ $EUID -eq 0 ]] && [ ! $FORCE_ROOT ] \ +[[ "${EUID}" -eq 0 ]] && [[ "${FORCE_ROOT}" != true ]] \ && { echo 'ERROR::Setup cannot be run as root'; exit 1; } ##################################################################### @@ -6,7 +6,7 @@ # normally "DOTWRYN", but uses "DOTWRYN_PATH" to avoid conflict during setup cd "${0:a:h}" export DOTWRYN_PATH="$(git rev-parse --show-toplevel)" -cd "$DOTWRYN_PATH" +cd "${DOTWRYN_PATH}" printf 'initializing required submodules...' >&2 git submodule update --init --remote --recursive >/dev/null 2>&1 || { @@ -17,30 +17,47 @@ git submodule update --init --remote --recursive >/dev/null 2>&1 || { ##################################################################### -_DEPENDENCIES+=(zsh) -_REQUIRED_ENV+=() +DEPENDENCIES+=(zsh) +REQUIRED_ENV+=() command -v fzf &>/dev/null || fzf() { head -n1; } +command -v jo &>/dev/null || jo() { :; } +command -v jq &>/dev/null || jq() { :; } -source "$DOTWRYN_PATH/zsh/plugins/scwrypts/zsh/lib/utils/utils.module.zsh" || exit 3 +source "${DOTWRYN_PATH}/zsh/plugins/scwrypts/zsh/utils/utils.module.zsh" || exit 3 unset -f fzf &>/dev/null +unset -f jo &>/dev/null +unset -f jq &>/dev/null + +# register the '.wryn' dotwryn scwrypts group; scwrypts only discovers groups +# listed in SCWRYPTS_GROUP_DIRS inside this file, and this file doesn't exist +# yet on a fresh machine +scwrypts_user_config_dir="${XDG_CONFIG_HOME:-${HOME}/.config}/scwrypts" +scwrypts_user_config="${scwrypts_user_config_dir}/config.zsh" +mkdir -p "${scwrypts_user_config_dir}" +[ -f "${scwrypts_user_config}" ] \ + || cp "${DOTWRYN_PATH}/zsh/plugins/scwrypts/zsh/config.user.zsh" "${scwrypts_user_config}" + +grep -qF "${DOTWRYN_PATH}/scwrypts" "${scwrypts_user_config}" \ + || echo "SCWRYPTS_GROUP_DIRS+=(\"${DOTWRYN_PATH}/scwrypts\")" >> "${scwrypts_user_config}" +unset scwrypts_user_config_dir scwrypts_user_config SCWRYPTS() { CI=1 \ - CONFIG__USER_SETTINGS="$DOTWRYN_PATH/config/scwrypts/dotfiles.zsh" \ - DOTWRYN=$DOTWRYN_PATH \ - "$DOTWRYN_PATH/zsh/plugins/scwrypts/scwrypts" -n $@ + CONFIG__USER_SETTINGS="${DOTWRYN_PATH}/config/scwrypts/dotfiles.zsh" \ + DOTWRYN="${DOTWRYN_PATH}" \ + "${DOTWRYN_PATH}/zsh/plugins/scwrypts/scwrypts" -n "${@}" } ##################################################################### -source "$DOTWRYN_PATH/setup/os.zsh" -source "$DOTWRYN_PATH/setup/git.zsh" -source "$DOTWRYN_PATH/setup/config.zsh" +source "${DOTWRYN_PATH}/setup/os.zsh" +source "${DOTWRYN_PATH}/setup/git.zsh" +source "${DOTWRYN_PATH}/setup/config.zsh" ##################################################################### clear # shhh don't worry about it -[[ $CI -ne 0 ]] || {C=$((){B(){base64 -d};A="$(cat "$2")";for _ in {1..$1};do A=$(echo $A|B);done;echo $A} 7 "$DOTWRYN_PATH/setup/welcome");for ((i=0;i<${#C};i++));do [[ ${C:$i:1} =~ z ]] && M=$(printf "\\033[1;3$((1+$RANDOM%5))m") && continue;printf "$M${C:$i:1}" none;sleep 0.01;done;echo;unset C M;} +[[ "${CI}" == true ]] || {C=$((){B(){base64 -d};A="$(cat "$2")";for _ in {1..$1};do A=$(echo $A|B);done;echo $A} 7 "$DOTWRYN_PATH/setup/welcome");for ((i=0;i<${#C};i++));do [[ ${C:$i:1} =~ z ]] && M=$(printf "\\033[1;3$((1+$RANDOM%5))m") && continue;printf "$M${C:$i:1}" none;sleep 0.01;done;echo;unset C M;} diff --git a/setup/run b/setup/run index a039a83..0eda447 100755 --- a/setup/run +++ b/setup/run @@ -1,19 +1,25 @@ #!/bin/zsh cd "${0:a:h}" -OVERWRITE_EXISTING=0 -while [[ $# -gt 0 ]] + +FORCE_ROOT=false +CI=false +OVERWRITE_EXISTING=false +COMPILE_DMENU=true +MIN=false + +while [[ "${#}" -gt 0 ]] do - case $1 in - --force-root ) FORCE_ROOT=1 ;; - --ci ) export CI=1 ;; + case "${1}" in + ( --force-root ) FORCE_ROOT=true ;; + ( --ci ) export CI=true ;; - --overwrite ) OVERWRITE_EXISTING=1 ;; + ( --overwrite ) OVERWRITE_EXISTING=true ;; - --no-compile-dmenu ) COMPILE_DMENU=0 ;; + ( --no-compile-dmenu ) COMPILE_DMENU=false ;; - --min ) - MIN=1 - COMPILE_DMENU=0 + ( --min ) + MIN=true + COMPILE_DMENU=false ;; esac shift 1 @@ -21,22 +27,22 @@ done source ./requirements.zsh || exit 1 ################################################################################ -LOGFILE="${HOME}/dotwryn-install.txt" +logfile="${HOME}/dotwryn-install.txt" -STATUS "installation start : $(date)" 2>> "${LOGFILE}" +echo.status "installation start : $(date)" 2>> "${logfile}" { - SETUP__OS || FAIL 1 'failed to set up os-dependencies (see above)' - SETUP__GIT || FAIL 2 'failed to set up git (see above)' - SETUP__CONFIG || FAIL 3 'failed to set up program configuration (see above)' -} 2>&1 | tee -a "${LOGFILE}" + setup.os || utils.fail 1 'failed to set up os-dependencies (see above)' + setup.git || utils.fail 2 'failed to set up git (see above)' + setup.config || utils.fail 3 'failed to set up program configuration (see above)' +} 2>&1 | tee -a "${logfile}" -STATUS "installation complete: $(date)" 2>> "${LOGFILE}" +echo.status "installation complete: $(date)" 2>> "${logfile}" ################################################################################ -[[ ${ERRORS} -eq 0 ]] || { - yN 'keep logfile?' \ - || { rm "${LOGFILE}" || ERROR "unable to remove '${LOGFILE}'" } +[[ "${ERRORS}" -eq 0 ]] || { + utils.yN 'keep logfile?' \ + || { rm "${logfile}" || echo.error "unable to remove '${logfile}'" } } -SUCCESS "\n.wryn setup complete; have a nice day :)\n " +echo.success "\n.wryn setup complete; have a nice day :)\n "