From 2845895ff4d6fe6b3b8b246fad29260c22125fd1 Mon Sep 17 00:00:00 2001 From: Prad Nukala Date: Mon, 28 Sep 2026 11:08:56 -0400 Subject: [PATCH] feat(public): add chezmoi install script --- public/install | 395 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 395 insertions(+) create mode 100755 public/install diff --git a/public/install b/public/install new file mode 100755 index 0000000..bbd5a71 --- /dev/null +++ b/public/install @@ -0,0 +1,395 @@ +#!/bin/sh + +# dots.prd.lk/install — chezmoi install script, preset for prdlk/dotfiles. +# +# Vendored from https://get.chezmoi.io/lb with three changes: +# 1. BINDIR defaults to $HOME/.local/bin (absolute, not cwd-relative). +# 2. With no chezmoi-args, runs `chezmoi init --apply $DOTFILES_REPO` +# (default prdlk/dotfiles). +# 3. chezmoi's stdin is re-attached to /dev/tty when this script is piped +# into sh, so first-run prompts (name, email, role) still work. +# +# Usage: +# curl -fsSL https://dots.prd.lk/install | sh +# sh -c "$(curl -fsSL https://dots.prd.lk/install)" -- init --apply --ssh prdlk/dotfiles + +# chezmoi install script +# contains code from and inspired by +# https://github.com/client9/shlib +# https://github.com/goreleaser/godownloader + +# Copyright (C) 2017 Nick Galbreath +# Copyright (C) 2018 Tom Payne +# SPDX-License-Identifier: MIT + +set -e + +BINDIR="${BINDIR:-${HOME}/.local/bin}" +DOTFILES_REPO="${DOTFILES_REPO:-prdlk/dotfiles}" +TAGARG=latest +LOG_LEVEL=2 + +tmpdir="$(mktemp -d)" +trap 'rm -rf -- "${tmpdir}"' EXIT +trap 'exit' INT TERM + +usage() { + this="${1}" + cat </dev/null; then + exec "${BINDIR}/${BINARY}" "${@}" &2 + return 1 + ;; + esac +} + +get_libc() { + if is_command ldd; then + case "$(ldd --version 2>&1 | tr '[:upper:]' '[:lower:]')" in + *glibc* | *"gnu libc"*) + # If the version of glibc is too old then use the statically-linked + # musl version instead. chezmoi releases are built on GitHub Actions + # ubuntu-22.04 runners, which have glibc version 2.35. + minimum_glibc_version=2.35 + glibc_version="$(ldd --version 2>&1 | awk '$1 == "ldd" { print $NF }')" + # shellcheck disable=SC2046,SC2183 + minimum_glibc_version_string="$(printf "%03d%03d" $(echo "${minimum_glibc_version}" | tr "." " "))" + # shellcheck disable=SC2046,SC2183 + glibc_version_string="$(printf "%03d%03d" $(echo "${glibc_version}" | tr "." " "))" + log_info "found glibc version ${glibc_version}" + if [ "${glibc_version_string}" -lt "${minimum_glibc_version_string}" ]; then + printf musl + return + fi + printf glibc + return + ;; + *musl*) + printf musl + return + ;; + esac + fi + if is_command getconf; then + case "$(getconf GNU_LIBC_VERSION 2>&1)" in + *glibc*) + printf glibc + return + ;; + esac + fi + log_crit "unable to determine libc" 1>&2 + exit 1 +} + +real_tag() { + tag="${1}" + log_debug "checking GitHub for tag ${tag}" + release_url="https://github.com/twpayne/chezmoi/releases/${tag}" + json="$(http_get "${release_url}" "Accept: application/json")" + if [ -z "${json}" ]; then + log_err "real_tag error retrieving GitHub release ${tag}" + return 1 + fi + real_tag="$(printf '%s\n' "${json}" | tr -s '\n' ' ' | sed 's/.*"tag_name":"//' | sed 's/".*//')" + if [ -z "${real_tag}" ]; then + log_err "real_tag error determining real tag of GitHub release ${tag}" + return 1 + fi + if [ -z "${real_tag}" ]; then + return 1 + fi + log_debug "found tag ${real_tag} for ${tag}" + printf '%s' "${real_tag}" +} + +http_get() { + tmpfile="$(mktemp)" + http_download "${tmpfile}" "${1}" "${2}" || return 1 + body="$(cat "${tmpfile}")" + rm -f "${tmpfile}" + printf '%s\n' "${body}" +} + +http_download_curl() { + local_file="${1}" + source_url="${2}" + header="${3}" + if [ -z "${header}" ]; then + code="$(curl -w '%{http_code}' -fsSL -o "${local_file}" "${source_url}")" + else + code="$(curl -w '%{http_code}' -fsSL -H "${header}" -o "${local_file}" "${source_url}")" + fi + if [ "${code}" != "200" ]; then + log_debug "http_download_curl received HTTP status ${code}" + return 1 + fi + return 0 +} + +http_download_wget() { + local_file="${1}" + source_url="${2}" + header="${3}" + if [ -z "${header}" ]; then + wget -q -O "${local_file}" "${source_url}" || return 1 + else + wget -q --header "${header}" -O "${local_file}" "${source_url}" || return 1 + fi +} + +http_download() { + log_debug "http_download ${2}" + if is_command curl; then + http_download_curl "${@}" || return 1 + return + elif is_command wget; then + http_download_wget "${@}" || return 1 + return + fi + log_crit "http_download unable to find wget or curl" + return 1 +} + +hash_sha256() { + target="${1}" + if is_command sha256sum; then + hash="$(sha256sum "${target}")" || return 1 + printf '%s' "${hash}" | cut -d ' ' -f 1 + elif is_command shasum; then + hash="$(shasum -a 256 "${target}" 2>/dev/null)" || return 1 + printf '%s' "${hash}" | cut -d ' ' -f 1 + elif is_command sha256; then + hash="$(sha256 -q "${target}" 2>/dev/null)" || return 1 + printf '%s' "${hash}" | cut -d ' ' -f 1 + elif is_command openssl; then + hash="$(openssl dgst -sha256 "${target}")" || return 1 + printf '%s' "${hash}" | cut -d ' ' -f a + else + log_crit "hash_sha256 unable to find command to compute SHA256 hash" + return 1 + fi +} + +hash_sha256_verify() { + target="${1}" + checksums="${2}" + basename="${target##*/}" + + want="$(grep "${basename}\$" "${checksums}" 2>/dev/null | tr '\t' ' ' | cut -d ' ' -f 1)" + if [ -z "${want}" ]; then + log_err "hash_sha256_verify unable to find checksum for ${target} in ${checksums}" + return 1 + fi + + got="$(hash_sha256 "${target}")" + if [ "${want}" != "${got}" ]; then + log_err "hash_sha256_verify checksum for ${target} did not verify ${want} vs ${got}" + return 1 + fi +} + +untar() { + tarball="${1}" + case "${tarball}" in + *.tar.gz | *.tgz) tar -xzf "${tarball}" ;; + *.tar) tar -xf "${tarball}" ;; + *.zip) unzip -- "${tarball}" ;; + *) + log_err "untar unknown archive format for ${tarball}" + return 1 + ;; + esac +} + +is_command() { + type "${1}" >/dev/null 2>&1 +} + +log_debug() { + [ 3 -le "${LOG_LEVEL}" ] || return 0 + printf 'debug %s\n' "${*}" 1>&2 +} + +log_info() { + [ 2 -le "${LOG_LEVEL}" ] || return 0 + printf 'info %s\n' "${*}" 1>&2 +} + +log_err() { + [ 1 -le "${LOG_LEVEL}" ] || return 0 + printf 'error %s\n' "${*}" 1>&2 +} + +log_crit() { + [ 0 -le "${LOG_LEVEL}" ] || return 0 + printf 'critical %s\n' "${*}" 1>&2 +} + +main "${@}"