From 9e69b0a5be8fd146c012a22e3324811c642d8b08 Mon Sep 17 00:00:00 2001 From: Junhyeok Ahn Date: Tue, 14 Apr 2026 10:30:56 -0700 Subject: [PATCH 1/2] improvement --- .github/workflows/test-install-scripts.yml | 14 ++++++- install/kitty.sh | 13 ++++-- install/lib/common.sh | 48 ++++++++++++++++++++- install/nvim-bin.sh | 49 +++++++++++++++++++++- install/nvim.sh | 7 +++- install/starship.sh | 2 +- install/zk-bin.sh | 37 ++++++++++++++++ install/zk.sh | 2 + 8 files changed, 164 insertions(+), 8 deletions(-) diff --git a/.github/workflows/test-install-scripts.yml b/.github/workflows/test-install-scripts.yml index ae2cb7d..73a1c3c 100644 --- a/.github/workflows/test-install-scripts.yml +++ b/.github/workflows/test-install-scripts.yml @@ -8,6 +8,16 @@ on: workflow_dispatch: jobs: + shellcheck: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Run shellcheck + uses: ludeeus/action-shellcheck@master + with: + scandir: './install' + severity: error + changes: runs-on: ubuntu-latest outputs: @@ -381,6 +391,7 @@ jobs: runs-on: ubuntu-latest needs: - changes + - shellcheck - test-nvim-install - test-kitty-install - test-starship-install @@ -391,7 +402,8 @@ jobs: run: | echo "Checking test results..." - if [[ "${{ needs.test-nvim-install.result }}" == "failure" ]] || \ + if [[ "${{ needs.shellcheck.result }}" == "failure" ]] || \ + [[ "${{ needs.test-nvim-install.result }}" == "failure" ]] || \ [[ "${{ needs.test-kitty-install.result }}" == "failure" ]] || \ [[ "${{ needs.test-starship-install.result }}" == "failure" ]] || \ [[ "${{ needs.test-zk-install.result }}" == "failure" ]]; then diff --git a/install/kitty.sh b/install/kitty.sh index 811bc76..58a84af 100755 --- a/install/kitty.sh +++ b/install/kitty.sh @@ -66,9 +66,9 @@ install_kitty() { echo "Installing Kitty..." if [[ "${OS}" == "Darwin" ]]; then - curl -fsSL https://sw.kovidgoyal.net/kitty/installer.sh | sh /dev/stdin + download_and_run https://sw.kovidgoyal.net/kitty/installer.sh else - curl -fsSL https://sw.kovidgoyal.net/kitty/installer.sh | sh /dev/stdin launch=n + download_and_run https://sw.kovidgoyal.net/kitty/installer.sh launch=n install_kitty_linux_desktop fi } @@ -92,7 +92,14 @@ install_nerd_fonts() { need_cmd curl need_cmd unzip - local font_version="3.3.0" + local font_version + font_version="$(curl -fsSL https://api.github.com/repos/ryanoasis/nerd-fonts/releases/latest \ + | sed -n 's/.*"tag_name": *"v\([^"]*\)".*/\1/p' | head -n 1)" + if [[ -z "${font_version}" ]]; then + echo "Error: failed to resolve latest Nerd Fonts release" + exit 1 + fi + echo "Latest Nerd Fonts version: ${font_version}" echo "Installing Nerd Fonts..." for font in JetBrainsMono NerdFontsSymbolsOnly; do diff --git a/install/lib/common.sh b/install/lib/common.sh index 13a5542..b5d11b3 100644 --- a/install/lib/common.sh +++ b/install/lib/common.sh @@ -59,6 +59,12 @@ ensure_local_bin_path() { install_fzf() { local local_bin_dir="${HOME}/.local/bin" + local fzf_target="$HOME/.fzf/bin/fzf" + local fzf_link="${local_bin_dir}/fzf" + + if [[ -L "${fzf_link}" && "$(readlink "${fzf_link}")" == "${fzf_target}" && -x "${fzf_target}" ]]; then + return + fi if command -v fzf >/dev/null 2>&1; then return @@ -73,5 +79,45 @@ install_fzf() { "$HOME/.fzf/install" --bin --no-update-rc mkdir -p "${local_bin_dir}" - ln -sf "$HOME/.fzf/bin/fzf" "${local_bin_dir}/fzf" + ln -sf "${fzf_target}" "${fzf_link}" +} + +# sha256_cmd prints the command to use for sha256 verification. +sha256_cmd() { + if command -v sha256sum >/dev/null 2>&1; then + echo "sha256sum" + elif command -v shasum >/dev/null 2>&1; then + echo "shasum -a 256" + else + echo "Error: need sha256sum or shasum to verify checksums." >&2 + exit 1 + fi +} + +# verify_sha256 +verify_sha256() { + local file="$1" + local expected="$2" + local actual + actual="$($(sha256_cmd) "${file}" | awk '{print $1}')" + if [[ "${actual}" != "${expected}" ]]; then + echo "Error: checksum mismatch for ${file}" >&2 + echo " expected: ${expected}" >&2 + echo " actual: ${actual}" >&2 + exit 1 + fi +} + +# download_and_run [args...] — downloads to a temp file, runs it, cleans up. +download_and_run() { + local url="$1" + shift + need_cmd curl + local tmp rc=0 + tmp="$(mktemp)" + curl -fsSL "${url}" -o "${tmp}" + chmod +x "${tmp}" + sh "${tmp}" "$@" || rc=$? + rm -f "${tmp}" + return "${rc}" } diff --git a/install/nvim-bin.sh b/install/nvim-bin.sh index b054bed..6cf43f9 100755 --- a/install/nvim-bin.sh +++ b/install/nvim-bin.sh @@ -45,6 +45,40 @@ brew_install() { brew install "$@" } +sha256_cmd() { + if command -v sha256sum >/dev/null 2>&1; then + echo "sha256sum" + elif command -v shasum >/dev/null 2>&1; then + echo "shasum -a 256" + else + echo "Error: need sha256sum or shasum to verify checksums." >&2 + exit 1 + fi +} + +# verify_sha256_from_manifest +# Downloads a checksum manifest and verifies against the entry for . +verify_sha256_from_manifest() { + local file="$1" manifest_url="$2" asset_name="$3" + local manifest expected actual + manifest="$(mktemp)" + curl -fsSL "${manifest_url}" -o "${manifest}" + expected="$(awk -v name="${asset_name}" '$2 == name || $2 == "*"name {print $1; exit}' "${manifest}")" + rm -f "${manifest}" + if [[ -z "${expected}" ]]; then + echo "Error: no checksum entry for ${asset_name} in ${manifest_url}" >&2 + exit 1 + fi + actual="$($(sha256_cmd) "${file}" | awk '{print $1}')" + if [[ "${actual}" != "${expected}" ]]; then + echo "Error: checksum mismatch for ${file}" >&2 + echo " expected: ${expected}" >&2 + echo " actual: ${actual}" >&2 + exit 1 + fi + echo "Verified sha256 for ${asset_name}" +} + ensure_local_bin_path() { local path_line='export PATH="$HOME/.local/bin:$PATH"' append_once "${path_line}" "$HOME/.bashrc" @@ -86,7 +120,11 @@ install_linux_deps() { clang \ libclang-dev - curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y + local rustup_tmp + rustup_tmp="$(mktemp)" + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs -o "${rustup_tmp}" + sh "${rustup_tmp}" -y + rm -f "${rustup_tmp}" . "$HOME/.cargo/env" cargo install --locked tree-sitter-cli @@ -128,6 +166,10 @@ install_nvim_macos() { echo "Downloading Neovim ${NVIM_CHANNEL} for macOS (${ARCH})..." curl -fL "${url}" -o "/tmp/${file}" + verify_sha256_from_manifest "/tmp/${file}" \ + "https://github.com/neovim/neovim/releases/download/${NVIM_CHANNEL}/shasum.txt" \ + "${file}" + rm -rf "${LOCAL_DIR:?}/${name}" "${LOCAL_BIN_DIR}/nvim" tar xzf "/tmp/${file}" -C "${LOCAL_DIR}" ln -sf "${LOCAL_DIR}/${name}/bin/nvim" "${LOCAL_BIN_DIR}/nvim" @@ -153,6 +195,11 @@ install_nvim_linux() { echo "Downloading Neovim ${NVIM_CHANNEL} AppImage for Linux (${ARCH})..." curl -fL "${url}" -o "${LOCAL_BIN_DIR}/nvim" + + verify_sha256_from_manifest "${LOCAL_BIN_DIR}/nvim" \ + "https://github.com/neovim/neovim/releases/download/${NVIM_CHANNEL}/shasum.txt" \ + "${name}" + chmod u+x "${LOCAL_BIN_DIR}/nvim" } diff --git a/install/nvim.sh b/install/nvim.sh index f850d5d..7283319 100755 --- a/install/nvim.sh +++ b/install/nvim.sh @@ -17,7 +17,12 @@ install_nvim_config() { } echo "Installing Neovim config..." - rm -rf "${CONFIG_DIR}" + if [[ -d "${CONFIG_DIR}" ]]; then + local backup_dir + backup_dir="${CONFIG_DIR}.bak.$(date +%Y%m%d%H%M%S)" + echo "Backing up existing config to ${backup_dir}" + mv "${CONFIG_DIR}" "${backup_dir}" + fi mkdir -p "$(dirname "${CONFIG_DIR}")" cp -R "${NVIM_SOURCE_DIR}" "${CONFIG_DIR}" } diff --git a/install/starship.sh b/install/starship.sh index aa5b56f..597b16e 100755 --- a/install/starship.sh +++ b/install/starship.sh @@ -27,7 +27,7 @@ install_starship() { brew_install starship else need_cmd curl - curl -fsSL https://starship.rs/install.sh | sh -s -- -y + download_and_run https://starship.rs/install.sh -y fi } diff --git a/install/zk-bin.sh b/install/zk-bin.sh index c41d992..525d46e 100755 --- a/install/zk-bin.sh +++ b/install/zk-bin.sh @@ -40,6 +40,39 @@ brew_install() { brew install "$@" } +sha256_cmd() { + if command -v sha256sum >/dev/null 2>&1; then + echo "sha256sum" + elif command -v shasum >/dev/null 2>&1; then + echo "shasum -a 256" + else + echo "Error: need sha256sum or shasum to verify checksums." >&2 + exit 1 + fi +} + +# verify_sha256_from_manifest +verify_sha256_from_manifest() { + local file="$1" manifest_url="$2" asset_name="$3" + local manifest expected actual + manifest="$(mktemp)" + curl -fsSL "${manifest_url}" -o "${manifest}" + expected="$(awk -v name="${asset_name}" '$2 == name || $2 == "*"name {print $1; exit}' "${manifest}")" + rm -f "${manifest}" + if [[ -z "${expected}" ]]; then + echo "Error: no checksum entry for ${asset_name} in ${manifest_url}" >&2 + exit 1 + fi + actual="$($(sha256_cmd) "${file}" | awk '{print $1}')" + if [[ "${actual}" != "${expected}" ]]; then + echo "Error: checksum mismatch for ${file}" >&2 + echo " expected: ${expected}" >&2 + echo " actual: ${actual}" >&2 + exit 1 + fi + echo "Verified sha256 for ${asset_name}" +} + install_linux_deps() { echo "Installing zk dependencies for Ubuntu..." apt_install curl tar @@ -96,6 +129,10 @@ install_zk_from_release() { echo "Downloading ${asset_name}..." curl -fL "${download_url}" -o "${TMPDIR_TO_CLEANUP}/${asset_name}" + verify_sha256_from_manifest "${TMPDIR_TO_CLEANUP}/${asset_name}" \ + "https://github.com/zk-org/zk/releases/download/${ZK_VERSION}/checksums.txt" \ + "${asset_name}" + echo "Extracting ${asset_name}..." tar -xzf "${TMPDIR_TO_CLEANUP}/${asset_name}" -C "${TMPDIR_TO_CLEANUP}" diff --git a/install/zk.sh b/install/zk.sh index 1458899..92d4b29 100755 --- a/install/zk.sh +++ b/install/zk.sh @@ -4,6 +4,8 @@ set -euo pipefail SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" REPO_ROOT="$(cd -- "${SCRIPT_DIR}/.." && pwd)" +OS="$(uname -s)" + # shellcheck source=install/zk-bin.sh source "${SCRIPT_DIR}/zk-bin.sh" From b83faa12c50731a6796b885bcda3fc58f856cde3 Mon Sep 17 00:00:00 2001 From: Junhyeok Ahn Date: Tue, 14 Apr 2026 10:43:45 -0700 Subject: [PATCH 2/2] remove checksum --- install/nvim-bin.sh | 43 ------------------------------------------- install/zk-bin.sh | 37 ------------------------------------- 2 files changed, 80 deletions(-) diff --git a/install/nvim-bin.sh b/install/nvim-bin.sh index 6cf43f9..a7ee956 100755 --- a/install/nvim-bin.sh +++ b/install/nvim-bin.sh @@ -45,40 +45,6 @@ brew_install() { brew install "$@" } -sha256_cmd() { - if command -v sha256sum >/dev/null 2>&1; then - echo "sha256sum" - elif command -v shasum >/dev/null 2>&1; then - echo "shasum -a 256" - else - echo "Error: need sha256sum or shasum to verify checksums." >&2 - exit 1 - fi -} - -# verify_sha256_from_manifest -# Downloads a checksum manifest and verifies against the entry for . -verify_sha256_from_manifest() { - local file="$1" manifest_url="$2" asset_name="$3" - local manifest expected actual - manifest="$(mktemp)" - curl -fsSL "${manifest_url}" -o "${manifest}" - expected="$(awk -v name="${asset_name}" '$2 == name || $2 == "*"name {print $1; exit}' "${manifest}")" - rm -f "${manifest}" - if [[ -z "${expected}" ]]; then - echo "Error: no checksum entry for ${asset_name} in ${manifest_url}" >&2 - exit 1 - fi - actual="$($(sha256_cmd) "${file}" | awk '{print $1}')" - if [[ "${actual}" != "${expected}" ]]; then - echo "Error: checksum mismatch for ${file}" >&2 - echo " expected: ${expected}" >&2 - echo " actual: ${actual}" >&2 - exit 1 - fi - echo "Verified sha256 for ${asset_name}" -} - ensure_local_bin_path() { local path_line='export PATH="$HOME/.local/bin:$PATH"' append_once "${path_line}" "$HOME/.bashrc" @@ -166,10 +132,6 @@ install_nvim_macos() { echo "Downloading Neovim ${NVIM_CHANNEL} for macOS (${ARCH})..." curl -fL "${url}" -o "/tmp/${file}" - verify_sha256_from_manifest "/tmp/${file}" \ - "https://github.com/neovim/neovim/releases/download/${NVIM_CHANNEL}/shasum.txt" \ - "${file}" - rm -rf "${LOCAL_DIR:?}/${name}" "${LOCAL_BIN_DIR}/nvim" tar xzf "/tmp/${file}" -C "${LOCAL_DIR}" ln -sf "${LOCAL_DIR}/${name}/bin/nvim" "${LOCAL_BIN_DIR}/nvim" @@ -195,11 +157,6 @@ install_nvim_linux() { echo "Downloading Neovim ${NVIM_CHANNEL} AppImage for Linux (${ARCH})..." curl -fL "${url}" -o "${LOCAL_BIN_DIR}/nvim" - - verify_sha256_from_manifest "${LOCAL_BIN_DIR}/nvim" \ - "https://github.com/neovim/neovim/releases/download/${NVIM_CHANNEL}/shasum.txt" \ - "${name}" - chmod u+x "${LOCAL_BIN_DIR}/nvim" } diff --git a/install/zk-bin.sh b/install/zk-bin.sh index 525d46e..c41d992 100755 --- a/install/zk-bin.sh +++ b/install/zk-bin.sh @@ -40,39 +40,6 @@ brew_install() { brew install "$@" } -sha256_cmd() { - if command -v sha256sum >/dev/null 2>&1; then - echo "sha256sum" - elif command -v shasum >/dev/null 2>&1; then - echo "shasum -a 256" - else - echo "Error: need sha256sum or shasum to verify checksums." >&2 - exit 1 - fi -} - -# verify_sha256_from_manifest -verify_sha256_from_manifest() { - local file="$1" manifest_url="$2" asset_name="$3" - local manifest expected actual - manifest="$(mktemp)" - curl -fsSL "${manifest_url}" -o "${manifest}" - expected="$(awk -v name="${asset_name}" '$2 == name || $2 == "*"name {print $1; exit}' "${manifest}")" - rm -f "${manifest}" - if [[ -z "${expected}" ]]; then - echo "Error: no checksum entry for ${asset_name} in ${manifest_url}" >&2 - exit 1 - fi - actual="$($(sha256_cmd) "${file}" | awk '{print $1}')" - if [[ "${actual}" != "${expected}" ]]; then - echo "Error: checksum mismatch for ${file}" >&2 - echo " expected: ${expected}" >&2 - echo " actual: ${actual}" >&2 - exit 1 - fi - echo "Verified sha256 for ${asset_name}" -} - install_linux_deps() { echo "Installing zk dependencies for Ubuntu..." apt_install curl tar @@ -129,10 +96,6 @@ install_zk_from_release() { echo "Downloading ${asset_name}..." curl -fL "${download_url}" -o "${TMPDIR_TO_CLEANUP}/${asset_name}" - verify_sha256_from_manifest "${TMPDIR_TO_CLEANUP}/${asset_name}" \ - "https://github.com/zk-org/zk/releases/download/${ZK_VERSION}/checksums.txt" \ - "${asset_name}" - echo "Extracting ${asset_name}..." tar -xzf "${TMPDIR_TO_CLEANUP}/${asset_name}" -C "${TMPDIR_TO_CLEANUP}"