mirror of
https://github.com/Matir/skel.git
synced 2026-07-24 21:26:57 -07:00
Compare commits
15 Commits
684f6c6e95
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e2ec4e1f9c | ||
|
|
ba97442895 | ||
|
|
a9b68bfe1f | ||
|
|
2814312d60 | ||
|
|
a390d0a4d4 | ||
|
|
6caee04853 | ||
|
|
da1ee162c2 | ||
|
|
22b3f2e049 | ||
|
|
b81ca9703b | ||
|
|
be903aeb2c | ||
|
|
37816c7f72 | ||
|
|
63f8bb9364 | ||
|
|
691b2a7c6f | ||
|
|
8e42781710 | ||
|
|
de601c4a83 |
1
Brewfile
1
Brewfile
@@ -24,7 +24,6 @@ brew "direnv"
|
|||||||
brew "dua-cli"
|
brew "dua-cli"
|
||||||
brew "duck"
|
brew "duck"
|
||||||
brew "dust"
|
brew "dust"
|
||||||
brew "earthly"
|
|
||||||
brew "espressif/eim/eim", trusted: true
|
brew "espressif/eim/eim", trusted: true
|
||||||
brew "esptool"
|
brew "esptool"
|
||||||
brew "fish"
|
brew "fish"
|
||||||
|
|||||||
@@ -4,7 +4,12 @@ set -ueo pipefail
|
|||||||
shopt -s extglob
|
shopt -s extglob
|
||||||
|
|
||||||
# get libraries
|
# get libraries
|
||||||
. ${HOME}/.local/lib/bash/tui.sh
|
if [[ -f "${HOME}/.local/lib/bash/tui.sh" ]]; then
|
||||||
|
. "${HOME}/.local/lib/bash/tui.sh"
|
||||||
|
else
|
||||||
|
echo "Error: ${HOME}/.local/lib/bash/tui.sh not found!" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
COMMANDS=(
|
COMMANDS=(
|
||||||
gctx
|
gctx
|
||||||
@@ -43,7 +48,7 @@ _gctx_choose() {
|
|||||||
--format='value(is_active, name, format("{} (as {})", properties.core.project, properties.core.account))')
|
--format='value(is_active, name, format("{} (as {})", properties.core.project, properties.core.account))')
|
||||||
local choice
|
local choice
|
||||||
if choice=$(printf "%-${maxnamelen}s %s\n" "${lines[@]}" | select_entry "gcloud config" "$default") ; then
|
if choice=$(printf "%-${maxnamelen}s %s\n" "${lines[@]}" | select_entry "gcloud config" "$default") ; then
|
||||||
_gctx_set "${choice}"
|
_gctx_set "$(echo "${choice}" | awk '{print $1}')"
|
||||||
else
|
else
|
||||||
echo "No option selected, leaving unchanged."
|
echo "No option selected, leaving unchanged."
|
||||||
fi
|
fi
|
||||||
@@ -68,7 +73,7 @@ _gctx_clone() {
|
|||||||
local oldconfig=()
|
local oldconfig=()
|
||||||
local line
|
local line
|
||||||
while IFS= read -r line ; do
|
while IFS= read -r line ; do
|
||||||
old_config+=("$line")
|
oldconfig+=("$line")
|
||||||
done < <(gcloud config configurations describe "$(_gctx_name)" --format='multi(properties:format="flattened[separator=\" \"]")')
|
done < <(gcloud config configurations describe "$(_gctx_name)" --format='multi(properties:format="flattened[separator=\" \"]")')
|
||||||
|
|
||||||
# create new
|
# create new
|
||||||
|
|||||||
@@ -1,8 +1,22 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
env > ${TMPDIR}/env-pre
|
set -o nounset
|
||||||
. ${HOME}/.shenv
|
|
||||||
env > ${TMPDIR}/env-post
|
TMP_DIR="${TMPDIR:-/tmp}"
|
||||||
for VAR in $(env | cut -d'=' -f1) ; do
|
TMP_DIR="${TMP_DIR%/}"
|
||||||
/bin/launchctl setenv "${VAR}" "$(eval echo \$${VAR})"
|
|
||||||
|
env > "${TMP_DIR}/env-pre" 2>/dev/null || true
|
||||||
|
if [ -f "${HOME}/.shenv" ]; then
|
||||||
|
. "${HOME}/.shenv"
|
||||||
|
fi
|
||||||
|
env > "${TMP_DIR}/env-post" 2>/dev/null || true
|
||||||
|
|
||||||
|
if [ -x "/bin/launchctl" ]; then
|
||||||
|
for VAR in $(env | awk -F= '/^[a-zA-Z_][a-zA-Z0-9_]*=/ {print $1}') ; do
|
||||||
|
case "${VAR}" in
|
||||||
|
_|""|*[!a-zA-Z0-9_]*|[0-9]*) continue ;;
|
||||||
|
esac
|
||||||
|
eval "val=\${${VAR}:-}"
|
||||||
|
/bin/launchctl setenv "${VAR}" "${val}"
|
||||||
done
|
done
|
||||||
|
fi
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ shift $((OPTIND - 1)) # Remove the parsed options
|
|||||||
|
|
||||||
# --- Set target directory ---
|
# --- Set target directory ---
|
||||||
# Use the first remaining argument as the target directory.
|
# Use the first remaining argument as the target directory.
|
||||||
if [ -n "$1" ]; then
|
if [ "$#" -gt 0 ]; then
|
||||||
TARGET_DIR="$1"
|
TARGET_DIR="$1"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -75,7 +75,7 @@ find "${TARGET_DIR}" -type l ! -exec test -e {} \; -print0 | while IFS= read -r
|
|||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
# Ask the user for confirmation.
|
# Ask the user for confirmation.
|
||||||
read -p "Remove broken symlink '${link}'? [y/N] " -n 1 -r
|
read -p "Remove broken symlink '${link}'? [y/N] " -n 1 -r < /dev/tty
|
||||||
echo # Move to a new line after input.
|
echo # Move to a new line after input.
|
||||||
|
|
||||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
# Installs Ansible, trying user-space methods first before falling back to sudo.
|
# Installs Ansible, trying user-space methods first before falling back to sudo.
|
||||||
# This script is designed to be idempotent and safe to run multiple times.
|
# This script is designed to be idempotent and safe to run multiple times.
|
||||||
|
|
||||||
set -e # Exit immediately if a command exits with a non-zero status.
|
set -euo pipefail # Exit immediately if a command exits with a non-zero status, undefined variable, or pipe failure.
|
||||||
|
|
||||||
# --- Helper Functions ---
|
# --- Helper Functions ---
|
||||||
info() { echo "[INFO] $1"; }
|
info() { echo "[INFO] $1"; }
|
||||||
@@ -44,8 +44,8 @@ fi
|
|||||||
|
|
||||||
# Try Python's venv module if pipx failed or wasn't present
|
# Try Python's venv module if pipx failed or wasn't present
|
||||||
VENV_PATH="${HOME}/.local/share/ansible_venv"
|
VENV_PATH="${HOME}/.local/share/ansible_venv"
|
||||||
# Create a temp path to avoid clobbering a failed install
|
# Create a temp path securely to avoid clobbering a failed install
|
||||||
VENV_TEST_PATH="/tmp/ansible_venv_test_$$"
|
VENV_TEST_PATH="$(mktemp -d "${TMPDIR:-/tmp}/ansible_venv_test.XXXXXX")"
|
||||||
if python3 -m venv "${VENV_TEST_PATH}" >/dev/null 2>&1; then
|
if python3 -m venv "${VENV_TEST_PATH}" >/dev/null 2>&1; then
|
||||||
rm -rf "${VENV_TEST_PATH}" # Clean up test
|
rm -rf "${VENV_TEST_PATH}" # Clean up test
|
||||||
info "Python's venv module is available. Creating a virtual environment at ${VENV_PATH}..."
|
info "Python's venv module is available. Creating a virtual environment at ${VENV_PATH}..."
|
||||||
@@ -55,7 +55,7 @@ if python3 -m venv "${VENV_TEST_PATH}" >/dev/null 2>&1; then
|
|||||||
info "Ansible installed successfully into a virtual environment."
|
info "Ansible installed successfully into a virtual environment."
|
||||||
info "To use it, run: '${VENV_PATH}/bin/ansible'"
|
info "To use it, run: '${VENV_PATH}/bin/ansible'"
|
||||||
info "To make it available everywhere, add its bin directory to your PATH:"
|
info "To make it available everywhere, add its bin directory to your PATH:"
|
||||||
info " echo 'export PATH="${VENV_PATH}/bin:$PATH"' >> ~/.profile"
|
info " echo 'export PATH=\"${VENV_PATH}/bin:\$PATH\"' >> ~/.profile"
|
||||||
info "(You may need to source ~/.profile or restart your shell)."
|
info "(You may need to source ~/.profile or restart your shell)."
|
||||||
exit 0
|
exit 0
|
||||||
else
|
else
|
||||||
@@ -63,6 +63,7 @@ if python3 -m venv "${VENV_TEST_PATH}" >/dev/null 2>&1; then
|
|||||||
rm -rf "${VENV_PATH}" # Clean up failed attempt
|
rm -rf "${VENV_PATH}" # Clean up failed attempt
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
|
rm -rf "${VENV_TEST_PATH}" # Clean up test after failure
|
||||||
info "Python's venv module not available or failed to create a test environment."
|
info "Python's venv module not available or failed to create a test environment."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
set -ue
|
set -ueo pipefail
|
||||||
|
|
||||||
TMPDIR=$(mktemp -d)
|
SYS_TMPDIR="${TMPDIR:-/tmp}"
|
||||||
|
TMPDIR="$(mktemp -d "${SYS_TMPDIR%/}/install_tool.XXXXXX")"
|
||||||
trap 'rm -rf -- "${TMPDIR}"' EXIT
|
trap 'rm -rf -- "${TMPDIR}"' EXIT
|
||||||
|
export -n TMPDIR 2>/dev/null || true
|
||||||
|
|
||||||
REINSTALL=0
|
REINSTALL=0
|
||||||
PACKAGES=1
|
PACKAGES=1
|
||||||
@@ -38,7 +40,7 @@ shift $((OPTIND-1))
|
|||||||
|
|
||||||
function list_tools {
|
function list_tools {
|
||||||
echo "Options:" >/dev/stderr
|
echo "Options:" >/dev/stderr
|
||||||
awk 'BEGIN {s=0;FS=")"};/main tool selection/{s=1};/^\s+\w+)$/{if(s==1){print $1}}' "$0" | sort | while read -r opt; do
|
awk 'BEGIN {s=0;FS=")"};/main tool selection/{s=1};/^\s+[a-zA-Z0-9_.-]+)$/{if(s==1){print $1}}' "$0" | sort | while read -r opt; do
|
||||||
echo -e "\\t${opt}" >/dev/stderr
|
echo -e "\\t${opt}" >/dev/stderr
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
@@ -124,11 +126,13 @@ function get_latest_github_release_url {
|
|||||||
local repo="$1"
|
local repo="$1"
|
||||||
local glob="$2"
|
local glob="$2"
|
||||||
curl -s "https://api.github.com/repos/${repo}/releases/latest" | \
|
curl -s "https://api.github.com/repos/${repo}/releases/latest" | \
|
||||||
jq -r ".assets[] | select(.name|test(\"${glob}\")) | .browser_download_url"
|
jq -r --arg rx "${glob}" '.assets[] | select(.name | test($rx)) | .browser_download_url'
|
||||||
}
|
}
|
||||||
|
|
||||||
function require_pipx {
|
function require {
|
||||||
command -v pipx >/dev/null 2>&1 || die "Requires pipx"
|
local cmd="${1}"
|
||||||
|
local msg="${2:-Requires ${cmd}}"
|
||||||
|
command -v "${cmd}" >/dev/null 2>&1 || die "${msg}"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Begin main tool selection
|
# Begin main tool selection
|
||||||
@@ -288,10 +292,7 @@ case ${TOOL} in
|
|||||||
git clone "${src}" "${DESTDIR}"
|
git clone "${src}" "${DESTDIR}"
|
||||||
;;
|
;;
|
||||||
pwndbg)
|
pwndbg)
|
||||||
if ! command -v gdb > /dev/null 2>&1 ; then
|
require gdb "No gdb available!"
|
||||||
echo 'No gdb available!' >/dev/stderr
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
git clone --depth 1 -b stable https://github.com/pwndbg/pwndbg.git "${DESTDIR}"
|
git clone --depth 1 -b stable https://github.com/pwndbg/pwndbg.git "${DESTDIR}"
|
||||||
PY_PACKAGES=${DESTDIR}/vendor
|
PY_PACKAGES=${DESTDIR}/vendor
|
||||||
mkdir -p "${PY_PACKAGES}"
|
mkdir -p "${PY_PACKAGES}"
|
||||||
@@ -311,10 +312,7 @@ case ${TOOL} in
|
|||||||
;;
|
;;
|
||||||
gef)
|
gef)
|
||||||
makedest_or_die
|
makedest_or_die
|
||||||
if ! command -v gdb > /dev/null 2>&1 ; then
|
require gdb "No gdb available!"
|
||||||
echo 'No gdb available!' >/dev/stderr
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
download \
|
download \
|
||||||
https://github.com/hugsy/gef/raw/master/gef.py \
|
https://github.com/hugsy/gef/raw/master/gef.py \
|
||||||
"${DESTDIR}/gef.py"
|
"${DESTDIR}/gef.py"
|
||||||
@@ -441,25 +439,19 @@ EOF
|
|||||||
add_bin_symlink docker-compose
|
add_bin_symlink docker-compose
|
||||||
;;
|
;;
|
||||||
tldr)
|
tldr)
|
||||||
require_pipx
|
require pipx
|
||||||
pipx install tldr
|
pipx install tldr
|
||||||
;;
|
;;
|
||||||
blint)
|
blint)
|
||||||
require_pipx
|
require pipx
|
||||||
pipx install blint
|
pipx install blint
|
||||||
;;
|
;;
|
||||||
dust)
|
dust)
|
||||||
if ! command -v cargo >/dev/null 2>&1 ; then
|
require cargo "This needs cargo (for rust)!"
|
||||||
echo "This needs cargo (for rust)!" >/dev/stderr
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
cargo install du-dust
|
cargo install du-dust
|
||||||
;;
|
;;
|
||||||
bottom)
|
bottom)
|
||||||
if ! command -v cargo >/dev/null 2>&1 ; then
|
require cargo "This needs cargo (for rust)!"
|
||||||
echo "This needs cargo (for rust)!" >/dev/stderr
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
cargo install bottom
|
cargo install bottom
|
||||||
;;
|
;;
|
||||||
delta)
|
delta)
|
||||||
@@ -476,7 +468,8 @@ EOF
|
|||||||
ropper)
|
ropper)
|
||||||
deb_only
|
deb_only
|
||||||
install_pkgs python3-z3
|
install_pkgs python3-z3
|
||||||
pip3 install --user pyvex ropper
|
require pipx
|
||||||
|
pipx install ropper
|
||||||
;;
|
;;
|
||||||
kubeconform)
|
kubeconform)
|
||||||
go install github.com/yannh/kubeconform/cmd/kubeconform@latest
|
go install github.com/yannh/kubeconform/cmd/kubeconform@latest
|
||||||
@@ -527,14 +520,11 @@ EOF
|
|||||||
sh "${rustup_init}" --no-modify-path -y
|
sh "${rustup_init}" --no-modify-path -y
|
||||||
;;
|
;;
|
||||||
igrep)
|
igrep)
|
||||||
if ! command -v cargo >/dev/null 2>&1 ; then
|
require cargo "This needs cargo (for rust)!"
|
||||||
echo "This needs cargo (for rust)!" >/dev/stderr
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
cargo install igrep
|
cargo install igrep
|
||||||
;;
|
;;
|
||||||
unblob)
|
unblob)
|
||||||
require_pipx
|
require pipx
|
||||||
pipx install unblob
|
pipx install unblob
|
||||||
;;
|
;;
|
||||||
fq)
|
fq)
|
||||||
@@ -555,6 +545,37 @@ EOF
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
|
speckit)
|
||||||
|
require uv
|
||||||
|
latest_version=$(curl -s "https://api.github.com/repos/github/spec-kit/releases/latest" | jq -r '.tag_name')
|
||||||
|
if [ -z "${latest_version}" ] || [ "${latest_version}" = "null" ]; then
|
||||||
|
die "Failed to determine latest release version for speckit."
|
||||||
|
fi
|
||||||
|
uv tool install specify-cli --from "git+https://github.com/github/spec-kit.git@${latest_version}"
|
||||||
|
;;
|
||||||
|
ssh-agent-mux)
|
||||||
|
makedest_or_die
|
||||||
|
os=$(uname -s | tr '[:upper:]' '[:lower:]')
|
||||||
|
case "$(uname -m)" in
|
||||||
|
x86_64|amd64)
|
||||||
|
arch="amd64"
|
||||||
|
;;
|
||||||
|
aarch64|arm64)
|
||||||
|
arch="arm64"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
die "Unsupported architecture: $(uname -m)"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
tar_url=$(get_latest_github_release_url "overhacked/ssh-agent-mux" ".*${os}-${arch}\\.tar\\.gz$")
|
||||||
|
if [ -z "${tar_url}" ]; then
|
||||||
|
die "Could not find ssh-agent-mux release for ${os}-${arch}"
|
||||||
|
fi
|
||||||
|
download "${tar_url}" "${TMPDIR}/ssh-agent-mux.tar.gz"
|
||||||
|
tar zxf "${TMPDIR}/ssh-agent-mux.tar.gz" --strip-components=1 -C "${DESTDIR}"
|
||||||
|
chmod +x "${DESTDIR}/ssh-agent-mux"
|
||||||
|
add_bin_symlink ssh-agent-mux
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
echo "Unknown tool: ${TOOL}" >/dev/stderr
|
echo "Unknown tool: ${TOOL}" >/dev/stderr
|
||||||
list_tools
|
list_tools
|
||||||
|
|||||||
@@ -2,12 +2,20 @@
|
|||||||
|
|
||||||
set -ue
|
set -ue
|
||||||
|
|
||||||
|
if [ "$(id -u)" -ne 0 ]; then
|
||||||
|
echo "Error: This script must be run as root." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
cat >/usr/local/bin/x-resize <<"EOF"
|
cat >/usr/local/bin/x-resize <<"EOF"
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
PATH=/usr/bin:/bin:/usr/local/bin
|
PATH=/usr/bin:/bin:/usr/local/bin
|
||||||
desktopuser=$(/bin/ps -ef | /bin/grep -oP '^\w+ (?=.*vdagent( |$))') || exit 0
|
desktopuser=$(/bin/ps -eo user,comm 2>/dev/null | awk '$2 ~ /vdagent/ {print $1; exit}')
|
||||||
|
[ -z "$desktopuser" ] && exit 0
|
||||||
|
desktophome=$(getent passwd "$desktopuser" | cut -d: -f6)
|
||||||
|
[ -z "$desktophome" ] && exit 0
|
||||||
export DISPLAY=:0
|
export DISPLAY=:0
|
||||||
export XAUTHORITY=$(eval echo "~$desktopuser")/.Xauthority
|
export XAUTHORITY="${desktophome}/.Xauthority"
|
||||||
/usr/bin/xrandr --output $(/usr/bin/xrandr | awk '/ connected/{print $1; exit; }') --auto
|
/usr/bin/xrandr --output $(/usr/bin/xrandr | awk '/ connected/{print $1; exit; }') --auto
|
||||||
EOF
|
EOF
|
||||||
chmod 755 /usr/local/bin/x-resize
|
chmod 755 /usr/local/bin/x-resize
|
||||||
|
|||||||
@@ -182,13 +182,14 @@ if [[ -f "$TARGET_FILE" && "$OVERWRITE" != "true" ]]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# 4. If the path ends in .md (case-insensitive), generate appropriate YAML front matter and write it to the new file.
|
# 4. If the path ends in .md (case-insensitive), generate appropriate YAML front matter and write it to the new file.
|
||||||
if [[ "${TARGET_BASE,,}" == *.md ]]; then
|
if [[ "$TARGET_BASE" =~ \.[mM][dD]$ ]]; then
|
||||||
NOTE_TITLE="${TARGET_BASE%.*}"
|
NOTE_TITLE="${TARGET_BASE%.*}"
|
||||||
|
NOTE_TITLE_ESCAPED="${NOTE_TITLE//\"/\\\"}"
|
||||||
CURRENT_DATE="$(date +"%Y-%m-%d %H:%M")"
|
CURRENT_DATE="$(date +"%Y-%m-%d %H:%M")"
|
||||||
|
|
||||||
cat << EOF > "$TARGET_FILE"
|
cat << EOF > "$TARGET_FILE"
|
||||||
---
|
---
|
||||||
title: "$NOTE_TITLE"
|
title: "$NOTE_TITLE_ESCAPED"
|
||||||
date: $CURRENT_DATE
|
date: $CURRENT_DATE
|
||||||
tags: []
|
tags: []
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ set -o pipefail
|
|||||||
# For this script, we assume the user's home directory.
|
# For this script, we assume the user's home directory.
|
||||||
SOURCE_DIR="${HOME}"
|
SOURCE_DIR="${HOME}"
|
||||||
|
|
||||||
# Exclude file location. We'll create a default one next to the script.
|
# Exclude file location.
|
||||||
EXCLUDE_FILE="$HOME/.restic_exclude.darwin"
|
EXCLUDE_FILE="${HOME}/.restic_exclude.darwin"
|
||||||
|
|
||||||
# --- Functions ---
|
# --- Functions ---
|
||||||
usage() {
|
usage() {
|
||||||
@@ -34,7 +34,7 @@ EOF
|
|||||||
|
|
||||||
# --- Main Script ---
|
# --- Main Script ---
|
||||||
# Check if restic is installed
|
# Check if restic is installed
|
||||||
if ! command -v restic &> /dev/null; then
|
if ! command -v restic >/dev/null 2>&1; then
|
||||||
echo "Error: restic command not found." >&2
|
echo "Error: restic command not found." >&2
|
||||||
echo "Please install restic first: https://restic.net/" >&2
|
echo "Please install restic first: https://restic.net/" >&2
|
||||||
exit 1
|
exit 1
|
||||||
@@ -57,7 +57,7 @@ while getopts ":l:bu:h" opt; do
|
|||||||
;;
|
;;
|
||||||
b)
|
b)
|
||||||
BACKUP_MODE="b2"
|
BACKUP_MODE="b2"
|
||||||
if [[ ${OPTIND} -le $# && "${!OPTIND}" != -* ]]; then
|
if [[ ${OPTIND} -le $# && "${!OPTIND:-}" != -* ]]; then
|
||||||
REPO="b2:${!OPTIND}:"
|
REPO="b2:${!OPTIND}:"
|
||||||
OPTIND=$((OPTIND + 1))
|
OPTIND=$((OPTIND + 1))
|
||||||
fi
|
fi
|
||||||
@@ -91,18 +91,19 @@ fi
|
|||||||
|
|
||||||
if [[ "${BACKUP_MODE}" == "b2" ]]; then
|
if [[ "${BACKUP_MODE}" == "b2" ]]; then
|
||||||
if [[ -f "${HOME}/.resticb2" ]] ; then
|
if [[ -f "${HOME}/.resticb2" ]] ; then
|
||||||
|
# shellcheck disable=SC1090
|
||||||
. "${HOME}/.resticb2"
|
. "${HOME}/.resticb2"
|
||||||
fi
|
fi
|
||||||
export B2_ACCOUNT_ID
|
export B2_ACCOUNT_ID="${B2_ACCOUNT_ID:-}"
|
||||||
export B2_ACCOUNT_KEY
|
export B2_ACCOUNT_KEY="${B2_ACCOUNT_KEY:-}"
|
||||||
export B2_BUCKET_NAME
|
export B2_BUCKET_NAME="${B2_BUCKET_NAME:-}"
|
||||||
if [[ -z "${B2_ACCOUNT_ID:-}" || -z "${B2_ACCOUNT_KEY:-}" ]]; then
|
if [[ -z "${B2_ACCOUNT_ID}" || -z "${B2_ACCOUNT_KEY}" ]]; then
|
||||||
echo "Error: For Backblaze B2 backups, you must set the B2_ACCOUNT_ID and B2_ACCOUNT_KEY environment variables." >&2
|
echo "Error: For Backblaze B2 backups, you must set the B2_ACCOUNT_ID and B2_ACCOUNT_KEY environment variables." >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -z "${REPO:-}" ]]; then
|
if [[ -z "${REPO}" ]]; then
|
||||||
if [[ -n "${B2_BUCKET_NAME:-}" ]]; then
|
if [[ -n "${B2_BUCKET_NAME}" ]]; then
|
||||||
REPO="b2:${B2_BUCKET_NAME}:"
|
REPO="b2:${B2_BUCKET_NAME}:"
|
||||||
else
|
else
|
||||||
echo "Error: Backup mode is B2 but no bucket name was provided and the B2_BUCKET_NAME environment variable is not set." >&2
|
echo "Error: Backup mode is B2 but no bucket name was provided and the B2_BUCKET_NAME environment variable is not set." >&2
|
||||||
@@ -113,41 +114,56 @@ if [[ "${BACKUP_MODE}" == "b2" ]]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
KEYCHAIN_ENTRY_NAME="restic_repo_password"
|
KEYCHAIN_ENTRY_NAME="restic_repo_password"
|
||||||
if security find-generic-password -a "$(whoami)" -s "${KEYCHAIN_ENTRY_NAME}" >/dev/null 2>&1 ; then
|
local_user="$(id -un 2>/dev/null || whoami)"
|
||||||
export RESTIC_PASSWORD_COMMAND="security find-generic-password -a \"$(whoami)\" -s \"${KEYCHAIN_ENTRY_NAME}\" -w"
|
if security find-generic-password -a "${local_user}" -s "${KEYCHAIN_ENTRY_NAME}" >/dev/null 2>&1 ; then
|
||||||
|
printf -v RESTIC_PASSWORD_COMMAND 'security find-generic-password -a %q -s %q -w' "${local_user}" "${KEYCHAIN_ENTRY_NAME}"
|
||||||
|
export RESTIC_PASSWORD_COMMAND
|
||||||
# Source file?
|
# Source file?
|
||||||
elif [[ -f "${HOME}/.resticpass" ]] ; then
|
elif [[ -f "${HOME}/.resticpass" ]] ; then
|
||||||
export RESTIC_PASSWORD_FILE="${HOME}/.resticpass"
|
export RESTIC_PASSWORD_FILE="${HOME}/.resticpass"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Ensure exclude file exists so restic does not fail when checking exclusions.
|
||||||
|
if [[ ! -f "${EXCLUDE_FILE}" ]]; then
|
||||||
|
echo "Exclude file '${EXCLUDE_FILE}' not found. Creating a default macOS exclude file..."
|
||||||
|
cat << 'EOF' > "${EXCLUDE_FILE}"
|
||||||
|
# Default restic exclusions for macOS
|
||||||
|
.Trash
|
||||||
|
Library/Caches
|
||||||
|
Library/Logs
|
||||||
|
.CFUserTextEncoding
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
|
||||||
# If the repository does not exist, initialize it.
|
# If the repository does not exist, initialize it.
|
||||||
# The user will be prompted for a password, which will be required for all
|
# The user will be prompted for a password, which will be required for all
|
||||||
# future interactions with the repository.
|
# future interactions with the repository.
|
||||||
if ! restic -r "${REPO}" snapshots &> /dev/null; then
|
if ! restic -r "${REPO}" snapshots >/dev/null 2>&1; then
|
||||||
echo "Restic repository not found or not accessible. Initializing..."
|
echo "Restic repository not found or not accessible. Initializing..."
|
||||||
restic init -r "${REPO}"
|
restic init -r "${REPO}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
# --- Run Backup ---
|
# --- Run Backup ---
|
||||||
echo "Starting restic backup..."
|
echo "Starting restic backup..."
|
||||||
echo "Source: ${SOURCE_DIR}"
|
echo "Source: ${SOURCE_DIR}"
|
||||||
echo "Repository: ${REPO}"
|
echo "Repository: ${REPO}"
|
||||||
|
|
||||||
BACKUP_CMD="restic backup \
|
BACKUP_ARGS=(
|
||||||
--verbose \
|
"restic" "backup"
|
||||||
--repo \"${REPO}\" \
|
"--verbose"
|
||||||
--exclude-file \"${EXCLUDE_FILE}\" \
|
"--repo" "${REPO}"
|
||||||
--one-file-system \
|
"--exclude-file" "${EXCLUDE_FILE}"
|
||||||
--tag \"macbook-backup\""
|
"--one-file-system"
|
||||||
|
"--tag" "macbook-backup"
|
||||||
|
)
|
||||||
|
|
||||||
if [[ -n "${UPLOAD_LIMIT}" ]]; then
|
if [[ -n "${UPLOAD_LIMIT}" ]]; then
|
||||||
BACKUP_CMD="${BACKUP_CMD} --limit-upload ${UPLOAD_LIMIT}"
|
BACKUP_ARGS+=("--limit-upload" "${UPLOAD_LIMIT}")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
BACKUP_CMD="${BACKUP_CMD} \"${SOURCE_DIR}\""
|
BACKUP_ARGS+=("${SOURCE_DIR}")
|
||||||
|
|
||||||
eval "${BACKUP_CMD}"
|
"${BACKUP_ARGS[@]}"
|
||||||
|
|
||||||
echo "Backup complete."
|
echo "Backup complete."
|
||||||
|
|
||||||
|
|||||||
60
bin/ssh-sign
60
bin/ssh-sign
@@ -72,15 +72,51 @@ shift # Consume the subcommand
|
|||||||
# Separate arguments from the file to be signed
|
# Separate arguments from the file to be signed
|
||||||
declare -a remaining_args
|
declare -a remaining_args
|
||||||
file_to_sign=""
|
file_to_sign=""
|
||||||
|
f_provided=false
|
||||||
|
n_provided=false
|
||||||
|
I_provided=false
|
||||||
|
s_provided=false
|
||||||
|
|
||||||
while [[ "$#" -gt 0 ]]; do
|
while [[ "$#" -gt 0 ]]; do
|
||||||
# If we see a non-flag argument, assume it's the file to sign.
|
case "$1" in
|
||||||
# This works because the file to sign is the only positional argument.
|
-f)
|
||||||
if [[ "$1" != -* ]] && [[ -z "$file_to_sign" ]]; then
|
[[ -z "${2:-}" ]] && error "Option -f requires an argument."
|
||||||
file_to_sign="$1"
|
remaining_args+=("-f" "$2")
|
||||||
else
|
f_provided=true
|
||||||
remaining_args+=("$1")
|
shift 2
|
||||||
|
;;
|
||||||
|
-n)
|
||||||
|
[[ -z "${2:-}" ]] && error "Option -n requires an argument."
|
||||||
|
remaining_args+=("-n" "$2")
|
||||||
|
n_provided=true
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
-I)
|
||||||
|
[[ -z "${2:-}" ]] && error "Option -I requires an argument."
|
||||||
|
remaining_args+=("-I" "$2")
|
||||||
|
I_provided=true
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
-s)
|
||||||
|
[[ -z "${2:-}" ]] && error "Option -s requires an argument."
|
||||||
|
remaining_args+=("-s" "$2")
|
||||||
|
s_provided=true
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
-h|--help)
|
||||||
|
usage
|
||||||
|
;;
|
||||||
|
-*)
|
||||||
|
error "Unknown option: $1"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
if [[ -n "$file_to_sign" ]]; then
|
||||||
|
error "Unexpected positional argument '$1' (already specified '$file_to_sign')."
|
||||||
fi
|
fi
|
||||||
|
file_to_sign="$1"
|
||||||
shift
|
shift
|
||||||
|
;;
|
||||||
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
# --- Build command based on subcommand ---
|
# --- Build command based on subcommand ---
|
||||||
@@ -90,18 +126,6 @@ CMD_ARGS=("ssh-keygen" "-Y" "$SUBCOMMAND")
|
|||||||
# Append all the flag-based arguments (-f, -n, -I, -s)
|
# Append all the flag-based arguments (-f, -n, -I, -s)
|
||||||
CMD_ARGS+=("${remaining_args[@]}")
|
CMD_ARGS+=("${remaining_args[@]}")
|
||||||
|
|
||||||
# Scan for provided flags to handle defaults correctly
|
|
||||||
f_provided=false
|
|
||||||
n_provided=false
|
|
||||||
I_provided=false
|
|
||||||
s_provided=false
|
|
||||||
for arg in "${remaining_args[@]}"; do
|
|
||||||
[[ "$arg" == "-f" ]] && f_provided=true
|
|
||||||
[[ "$arg" == "-n" ]] && n_provided=true
|
|
||||||
[[ "$arg" == "-I" ]] && I_provided=true
|
|
||||||
[[ "$arg" == "-s" ]] && s_provided=true
|
|
||||||
done
|
|
||||||
|
|
||||||
if [[ "$SUBCOMMAND" == "sign" ]]; then
|
if [[ "$SUBCOMMAND" == "sign" ]]; then
|
||||||
if [[ -z "$file_to_sign" ]]; then
|
if [[ -z "$file_to_sign" ]]; then
|
||||||
error "Path to file to be signed is required for 'sign' command."
|
error "Path to file to be signed is required for 'sign' command."
|
||||||
|
|||||||
@@ -260,6 +260,7 @@ if [[ -f "${TARGET_FILE}" ]]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
MANAGED_SIGS_TMP=$(mktemp)
|
MANAGED_SIGS_TMP=$(mktemp)
|
||||||
|
CLEANUP_FILES+=("${MANAGED_SIGS_TMP}")
|
||||||
echo "${MANAGED_BLOCK}" | awk '/^[^#]/ {
|
echo "${MANAGED_BLOCK}" | awk '/^[^#]/ {
|
||||||
n = split($0, parts, " ")
|
n = split($0, parts, " ")
|
||||||
sig = ""
|
sig = ""
|
||||||
|
|||||||
@@ -1,7 +1,49 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
set -e
|
set -eu
|
||||||
SKEL_DIR=$(dirname -- "$(readlink -f -- "$HOME/.profile")")
|
|
||||||
cd -- "$SKEL_DIR"
|
resolve_symlink() {
|
||||||
cd -- "$(git rev-parse --show-toplevel)"
|
_target="$1"
|
||||||
|
if command -v readlink >/dev/null 2>&1 && readlink -f -- "$_target" >/dev/null 2>&1; then
|
||||||
|
readlink -f -- "$_target"
|
||||||
|
elif command -v python3 >/dev/null 2>&1; then
|
||||||
|
python3 -c 'import os, sys; print(os.path.realpath(sys.argv[1]))' "$_target"
|
||||||
|
else
|
||||||
|
while [ -L "$_target" ]; do
|
||||||
|
_dir=$(cd -P "$(dirname -- "$_target")" >/dev/null 2>&1 && pwd)
|
||||||
|
_target=$(readlink "$_target")
|
||||||
|
case "$_target" in
|
||||||
|
/*) ;;
|
||||||
|
*) _target="$_dir/$_target" ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
echo "$_target"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ -e "$HOME/.profile" ]; then
|
||||||
|
TARGET=$(resolve_symlink "$HOME/.profile")
|
||||||
|
SKEL_DIR=$(dirname -- "$TARGET")
|
||||||
|
else
|
||||||
|
SKEL_DIR=""
|
||||||
|
fi
|
||||||
|
|
||||||
|
REPO_ROOT=""
|
||||||
|
if [ -n "$SKEL_DIR" ] && cd -- "$SKEL_DIR" 2>/dev/null; then
|
||||||
|
REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || true)
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$REPO_ROOT" ] || [ ! -f "$REPO_ROOT/install.sh" ]; then
|
||||||
|
SCRIPT_DIR=$(dirname -- "$(resolve_symlink "$0")")
|
||||||
|
if cd -- "$SCRIPT_DIR" 2>/dev/null; then
|
||||||
|
REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || true)
|
||||||
|
fi
|
||||||
|
if [ -z "$REPO_ROOT" ] || [ ! -f "$REPO_ROOT/install.sh" ]; then
|
||||||
|
echo "Error: Could not determine skel repository root." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd -- "$REPO_ROOT"
|
||||||
git pull
|
git pull
|
||||||
./install.sh
|
./install.sh "$@"
|
||||||
|
|
||||||
|
|||||||
65
deploy_checkout.sh
Executable file
65
deploy_checkout.sh
Executable file
@@ -0,0 +1,65 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
echo "Usage: $(basename "$0") [--dry-run] user@host" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
DRY_RUN=0
|
||||||
|
REMOTE=
|
||||||
|
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case "$1" in
|
||||||
|
--dry-run)
|
||||||
|
DRY_RUN=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-h|--help)
|
||||||
|
usage
|
||||||
|
;;
|
||||||
|
--)
|
||||||
|
shift
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
-*)
|
||||||
|
usage
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
if [[ -n "${REMOTE}" ]]; then
|
||||||
|
usage
|
||||||
|
fi
|
||||||
|
REMOTE="$1"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ $# -gt 0 || -z "${REMOTE}" ]]; then
|
||||||
|
usage
|
||||||
|
fi
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"
|
||||||
|
|
||||||
|
if ! git -C "$SCRIPT_DIR" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
||||||
|
echo "Error: $SCRIPT_DIR is not inside a git repository." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$DRY_RUN" -eq 1 ]]; then
|
||||||
|
archive_list="$(git -C "$SCRIPT_DIR" archive --format=tar HEAD | tar -tf - | sed 's#^\./##' | sed '/^$/d;/^\.$/d' | sort)"
|
||||||
|
remote_list="$(ssh "$REMOTE" 'if [ -d "$HOME/.skel" ]; then cd "$HOME/.skel" && find . | sed "s#^\./##" | sed "/^$/d;/^\.$/d" | sort; fi' || true)"
|
||||||
|
|
||||||
|
printf 'Would deploy HEAD from %s to %s:%s\n' "$SCRIPT_DIR" "$REMOTE" '$HOME/.skel'
|
||||||
|
printf 'Would replace remote ~/.skel with %s tracked paths\n' "$(printf '%s' "$archive_list" | awk 'NF { n++ } END { print n + 0 }')"
|
||||||
|
if [[ -n "$remote_list" ]]; then
|
||||||
|
printf 'Would remove %s existing remote paths not present in HEAD\n' "$(comm -13 <(printf '%s\n' "$archive_list") <(printf '%s\n' "$remote_list") | awk 'NF { n++ } END { print n + 0 }')"
|
||||||
|
else
|
||||||
|
printf 'Remote ~/.skel does not exist or is empty\n'
|
||||||
|
fi
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
git -C "$SCRIPT_DIR" archive --format=tar HEAD | \
|
||||||
|
ssh "$REMOTE" 'rm -rf "$HOME/.skel" && mkdir -p "$HOME/.skel" && tar -xf - -C "$HOME/.skel"'
|
||||||
@@ -104,3 +104,9 @@
|
|||||||
|
|
||||||
[rerere]
|
[rerere]
|
||||||
enabled = true
|
enabled = true
|
||||||
|
[lfs]
|
||||||
|
concurrenttransfers = 3
|
||||||
|
[lfs "customtransfer.xet"]
|
||||||
|
path = git-xet
|
||||||
|
args = transfer
|
||||||
|
concurrent = true
|
||||||
|
|||||||
@@ -4,16 +4,17 @@
|
|||||||
# Should only use POSIX constructs.
|
# Should only use POSIX constructs.
|
||||||
|
|
||||||
# Always load ENV
|
# Always load ENV
|
||||||
test -f "$HOME/.shenv" && . "$HOME/.shenv"
|
test -f "${HOME}/.shenv" && . "${HOME}/.shenv"
|
||||||
|
|
||||||
# Setup GREP_COLORS
|
# Setup GREP_COLORS
|
||||||
export GREP_COLOR='01;31'
|
export GREP_COLOR='01;31'
|
||||||
export GREP_COLORS='mt=01;31:mc=01;31:ms=01;31'
|
export GREP_COLORS='mt=01;31:mc=01;31:ms=01;31'
|
||||||
|
|
||||||
# Setup LS_COLORS
|
# Setup LS_COLORS
|
||||||
if whence dircolors >/dev/null 2>&1 ; then
|
if command -v dircolors >/dev/null 2>&1 && test -f "${HOME}/.dircolors" ; then
|
||||||
test -f "${HOME}/.dircolors" && \
|
eval "$(dircolors -b "${HOME}/.dircolors" 2>/dev/null)"
|
||||||
eval "$(dircolors "${HOME}/.dircolors")"
|
elif command -v gdircolors >/dev/null 2>&1 && test -f "${HOME}/.dircolors" ; then
|
||||||
|
eval "$(gdircolors -b "${HOME}/.dircolors" 2>/dev/null)"
|
||||||
else
|
else
|
||||||
# Static solarized LS_COLORS
|
# Static solarized LS_COLORS
|
||||||
LS_COLORS='no=00:fi=00:di=34:ow=34;40:ln=35:pi=30;44:so=35;44:do=35;44:bd=33;44:cd=37;44:or=05;37;41:mi=05;37;41:ex=01;31:*.cmd=01;31:*.exe=01;31:*.com=01;31:*.bat=01;31:*.reg=01;31:*.app=01;31:*.txt=32:*.org=32:*.md=32:*.mkd=32:*.h=32:*.hpp=32:*.c=32:*.C=32:*.cc=32:*.cpp=32:*.cxx=32:*.objc=32:*.cl=32:*.sh=32:*.bash=32:*.csh=32:*.zsh=32:*.el=32:*.vim=32:*.java=32:*.pl=32:*.pm=32:*.py=32:*.rb=32:*.hs=32:*.php=32:*.htm=32:*.html=32:*.shtml=32:*.erb=32:*.haml=32:*.xml=32:*.rdf=32:*.css=32:*.sass=32:*.scss=32:*.less=32:*.js=32:*.coffee=32:*.man=32:*.0=32:*.1=32:*.2=32:*.3=32:*.4=32:*.5=32:*.6=32:*.7=32:*.8=32:*.9=32:*.l=32:*.n=32:*.p=32:*.pod=32:*.tex=32:*.go=32:*.sql=32:*.csv=32:*.sv=32:*.svh=32:*.v=32:*.vh=32:*.vhd=32:*.bmp=33:*.cgm=33:*.dl=33:*.dvi=33:*.emf=33:*.eps=33:*.gif=33:*.jpeg=33:*.jpg=33:*.JPG=33:*.mng=33:*.pbm=33:*.pcx=33:*.pdf=33:*.pgm=33:*.png=33:*.PNG=33:*.ppm=33:*.pps=33:*.ppsx=33:*.ps=33:*.svg=33:*.svgz=33:*.tga=33:*.tif=33:*.tiff=33:*.xbm=33:*.xcf=33:*.xpm=33:*.xwd=33:*.xwd=33:*.yuv=33:*.aac=33:*.au=33:*.flac=33:*.m4a=33:*.mid=33:*.midi=33:*.mka=33:*.mp3=33:*.mpa=33:*.mpeg=33:*.mpg=33:*.ogg=33:*.opus=33:*.ra=33:*.wav=33:*.anx=33:*.asf=33:*.avi=33:*.axv=33:*.flc=33:*.fli=33:*.flv=33:*.gl=33:*.m2v=33:*.m4v=33:*.mkv=33:*.mov=33:*.MOV=33:*.mp4=33:*.mp4v=33:*.mpeg=33:*.mpg=33:*.nuv=33:*.ogm=33:*.ogv=33:*.ogx=33:*.qt=33:*.rm=33:*.rmvb=33:*.swf=33:*.vob=33:*.webm=33:*.wmv=33:*.doc=31:*.docx=31:*.rtf=31:*.odt=31:*.dot=31:*.dotx=31:*.ott=31:*.xls=31:*.xlsx=31:*.ods=31:*.ots=31:*.ppt=31:*.pptx=31:*.odp=31:*.otp=31:*.fla=31:*.psd=31:*.7z=1;35:*.apk=1;35:*.arj=1;35:*.bin=1;35:*.bz=1;35:*.bz2=1;35:*.cab=1;35:*.deb=1;35:*.dmg=1;35:*.gem=1;35:*.gz=1;35:*.iso=1;35:*.jar=1;35:*.msi=1;35:*.rar=1;35:*.rpm=1;35:*.tar=1;35:*.tbz=1;35:*.tbz2=1;35:*.tgz=1;35:*.tx=1;35:*.war=1;35:*.xpi=1;35:*.xz=1;35:*.z=1;35:*.Z=1;35:*.zip=1;35:*.ANSI-30-black=30:*.ANSI-01;30-brblack=01;30:*.ANSI-31-red=31:*.ANSI-01;31-brred=01;31:*.ANSI-32-green=32:*.ANSI-01;32-brgreen=01;32:*.ANSI-33-yellow=33:*.ANSI-01;33-bryellow=01;33:*.ANSI-34-blue=34:*.ANSI-01;34-brblue=01;34:*.ANSI-35-magenta=35:*.ANSI-01;35-brmagenta=01;35:*.ANSI-36-cyan=36:*.ANSI-01;36-brcyan=01;36:*.ANSI-37-white=37:*.ANSI-01;37-brwhite=01;37:*.log=01;32:*~=01;32:*#=01;32:*.bak=01;33:*.BAK=01;33:*.old=01;33:*.OLD=01;33:*.org_archive=01;33:*.off=01;33:*.OFF=01;33:*.dist=01;33:*.DIST=01;33:*.orig=01;33:*.ORIG=01;33:*.swp=01;33:*.swo=01;33:*,v=01;33:*.gpg=34:*.gpg=34:*.pgp=34:*.asc=34:*.3des=34:*.aes=34:*.enc=34:*.sqlite=34:';
|
LS_COLORS='no=00:fi=00:di=34:ow=34;40:ln=35:pi=30;44:so=35;44:do=35;44:bd=33;44:cd=37;44:or=05;37;41:mi=05;37;41:ex=01;31:*.cmd=01;31:*.exe=01;31:*.com=01;31:*.bat=01;31:*.reg=01;31:*.app=01;31:*.txt=32:*.org=32:*.md=32:*.mkd=32:*.h=32:*.hpp=32:*.c=32:*.C=32:*.cc=32:*.cpp=32:*.cxx=32:*.objc=32:*.cl=32:*.sh=32:*.bash=32:*.csh=32:*.zsh=32:*.el=32:*.vim=32:*.java=32:*.pl=32:*.pm=32:*.py=32:*.rb=32:*.hs=32:*.php=32:*.htm=32:*.html=32:*.shtml=32:*.erb=32:*.haml=32:*.xml=32:*.rdf=32:*.css=32:*.sass=32:*.scss=32:*.less=32:*.js=32:*.coffee=32:*.man=32:*.0=32:*.1=32:*.2=32:*.3=32:*.4=32:*.5=32:*.6=32:*.7=32:*.8=32:*.9=32:*.l=32:*.n=32:*.p=32:*.pod=32:*.tex=32:*.go=32:*.sql=32:*.csv=32:*.sv=32:*.svh=32:*.v=32:*.vh=32:*.vhd=32:*.bmp=33:*.cgm=33:*.dl=33:*.dvi=33:*.emf=33:*.eps=33:*.gif=33:*.jpeg=33:*.jpg=33:*.JPG=33:*.mng=33:*.pbm=33:*.pcx=33:*.pdf=33:*.pgm=33:*.png=33:*.PNG=33:*.ppm=33:*.pps=33:*.ppsx=33:*.ps=33:*.svg=33:*.svgz=33:*.tga=33:*.tif=33:*.tiff=33:*.xbm=33:*.xcf=33:*.xpm=33:*.xwd=33:*.xwd=33:*.yuv=33:*.aac=33:*.au=33:*.flac=33:*.m4a=33:*.mid=33:*.midi=33:*.mka=33:*.mp3=33:*.mpa=33:*.mpeg=33:*.mpg=33:*.ogg=33:*.opus=33:*.ra=33:*.wav=33:*.anx=33:*.asf=33:*.avi=33:*.axv=33:*.flc=33:*.fli=33:*.flv=33:*.gl=33:*.m2v=33:*.m4v=33:*.mkv=33:*.mov=33:*.MOV=33:*.mp4=33:*.mp4v=33:*.mpeg=33:*.mpg=33:*.nuv=33:*.ogm=33:*.ogv=33:*.ogx=33:*.qt=33:*.rm=33:*.rmvb=33:*.swf=33:*.vob=33:*.webm=33:*.wmv=33:*.doc=31:*.docx=31:*.rtf=31:*.odt=31:*.dot=31:*.dotx=31:*.ott=31:*.xls=31:*.xlsx=31:*.ods=31:*.ots=31:*.ppt=31:*.pptx=31:*.odp=31:*.otp=31:*.fla=31:*.psd=31:*.7z=1;35:*.apk=1;35:*.arj=1;35:*.bin=1;35:*.bz=1;35:*.bz2=1;35:*.cab=1;35:*.deb=1;35:*.dmg=1;35:*.gem=1;35:*.gz=1;35:*.iso=1;35:*.jar=1;35:*.msi=1;35:*.rar=1;35:*.rpm=1;35:*.tar=1;35:*.tbz=1;35:*.tbz2=1;35:*.tgz=1;35:*.tx=1;35:*.war=1;35:*.xpi=1;35:*.xz=1;35:*.z=1;35:*.Z=1;35:*.zip=1;35:*.ANSI-30-black=30:*.ANSI-01;30-brblack=01;30:*.ANSI-31-red=31:*.ANSI-01;31-brred=01;31:*.ANSI-32-green=32:*.ANSI-01;32-brgreen=01;32:*.ANSI-33-yellow=33:*.ANSI-01;33-bryellow=01;33:*.ANSI-34-blue=34:*.ANSI-01;34-brblue=01;34:*.ANSI-35-magenta=35:*.ANSI-01;35-brmagenta=01;35:*.ANSI-36-cyan=36:*.ANSI-01;36-brcyan=01;36:*.ANSI-37-white=37:*.ANSI-01;37-brwhite=01;37:*.log=01;32:*~=01;32:*#=01;32:*.bak=01;33:*.BAK=01;33:*.old=01;33:*.OLD=01;33:*.org_archive=01;33:*.off=01;33:*.OFF=01;33:*.dist=01;33:*.DIST=01;33:*.orig=01;33:*.ORIG=01;33:*.swp=01;33:*.swo=01;33:*,v=01;33:*.gpg=34:*.gpg=34:*.pgp=34:*.asc=34:*.3des=34:*.aes=34:*.enc=34:*.sqlite=34:';
|
||||||
@@ -27,16 +28,16 @@ if [ "$(uname)" = "Darwin" ] ; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Setup for libvirt
|
# Setup for libvirt
|
||||||
if [ -z "${LIBVIRT_DEFAULT_URI}" ] ; then
|
if [ -z "${LIBVIRT_DEFAULT_URI:-}" ] ; then
|
||||||
if [ "$(id -u)" = "0" ] || (id -g -n | grep -q "\blibvirt\b") ; then
|
export LIBVIRT_DEFAULT_URI="qemu:///system"
|
||||||
LIBVIRT_DEFAULT_URI="qemu:///system"
|
|
||||||
export LIBVIRT_DEFAULT_URI
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Got rust? (gvim, etc.)
|
# Got rust? (gvim, etc.)
|
||||||
if test -d "${HOME}/.cargo/bin" ; then
|
if test -d "${HOME}/.cargo/bin" ; then
|
||||||
PATH="${PATH}:${HOME}/.cargo/bin"
|
case ":${PATH}:" in
|
||||||
|
*:"${HOME}/.cargo/bin":*) ;;
|
||||||
|
*) PATH="${PATH}:${HOME}/.cargo/bin" ;;
|
||||||
|
esac
|
||||||
fi
|
fi
|
||||||
|
|
||||||
test -f "${HOME}/.profile.local" && . "${HOME}/.profile.local"
|
test -f "${HOME}/.profile.local" && . "${HOME}/.profile.local"
|
||||||
|
|||||||
176
dotfiles/shenv
176
dotfiles/shenv
@@ -29,6 +29,9 @@ export WORKON_HOME="$HOME/.virtualenvs"
|
|||||||
# GPG full key id
|
# GPG full key id
|
||||||
export GPG_ID=7FD58D9A196DCEEEAD671F94F4D7A7915DEA789B
|
export GPG_ID=7FD58D9A196DCEEEAD671F94F4D7A7915DEA789B
|
||||||
|
|
||||||
|
# Capture uname early
|
||||||
|
_UNAME="$(uname)"
|
||||||
|
|
||||||
# things we need in all interactive shells
|
# things we need in all interactive shells
|
||||||
case "$-" in
|
case "$-" in
|
||||||
*i*)
|
*i*)
|
||||||
@@ -86,7 +89,6 @@ case "$-" in
|
|||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
|
||||||
# Opt out of .net telemetry
|
# Opt out of .net telemetry
|
||||||
export DOTNET_CLI_TELEMETRY_OPTOUT=1
|
export DOTNET_CLI_TELEMETRY_OPTOUT=1
|
||||||
|
|
||||||
@@ -97,78 +99,145 @@ export LVM_SUPPRESS_FD_WARNINGS=1
|
|||||||
export EARTHLY_SSH_AUTH_SOCK=""
|
export EARTHLY_SSH_AUTH_SOCK=""
|
||||||
|
|
||||||
# Handle SSH_AUTH_SOCK for tmux consistency
|
# Handle SSH_AUTH_SOCK for tmux consistency
|
||||||
|
case "$-" in
|
||||||
|
*i*)
|
||||||
_SSH_AUTH_LINK="${HOME}/.ssh/ssh_auth_sock"
|
_SSH_AUTH_LINK="${HOME}/.ssh/ssh_auth_sock"
|
||||||
|
|
||||||
# Helper to check if a path is our link or points to it
|
# Helper to check if a path is our link or points to it
|
||||||
_is_link_path() {
|
_is_link_path() {
|
||||||
[ -z "$1" ] && return 1
|
[ -z "$1" ] && return 1
|
||||||
[ "$1" = "${_SSH_AUTH_LINK}" ] && return 0
|
_target="${_SSH_AUTH_LINK:-${HOME}/.ssh/ssh_auth_sock}"
|
||||||
|
[ "$1" = "${_target}" ] && { unset -v _target; return 0; }
|
||||||
if [ -L "$1" ] && command -v readlink >/dev/null 2>&1; then
|
if [ -L "$1" ] && command -v readlink >/dev/null 2>&1; then
|
||||||
_T=$(readlink "$1")
|
_T=$(readlink "$1")
|
||||||
# Handle relative symlinks
|
# Handle relative symlinks
|
||||||
case "${_T}" in /*) ;; *) _T="$(dirname "$1")/${_T}" ;; esac
|
case "${_T}" in /*) ;; *) _T="$(dirname "$1")/${_T}" ;; esac
|
||||||
[ "${_T}" = "${_SSH_AUTH_LINK}" ] && return 0
|
[ "${_T}" = "${_target}" ] && { unset -v _target _T; return 0; }
|
||||||
|
unset -v _T
|
||||||
fi
|
fi
|
||||||
|
unset -v _target
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Helper to check if an SSH socket is valid and useful
|
||||||
|
_is_valid_ssh_sock() {
|
||||||
|
[ -z "$1" ] && return 1
|
||||||
|
[ -S "$1" ] || return 1
|
||||||
|
|
||||||
|
if command -v nc >/dev/null 2>&1; then
|
||||||
|
# Use nc to quickly check if the socket is listening.
|
||||||
|
# We use -N to shutdown the socket after EOF on stdin (for OpenBSD netcat compatibility).
|
||||||
|
if echo '' | nc -w 1 -N -U "$1" >/dev/null 2>&1; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if command -v ssh-add >/dev/null 2>&1; then
|
||||||
|
SSH_AUTH_SOCK="$1" ssh-add -l >/dev/null 2>&1
|
||||||
|
case "$?" in
|
||||||
|
0|1) return 0 ;;
|
||||||
|
*) return 1 ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
if command -v nc >/dev/null 2>&1; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to get the path to the socket for the local ssh-agent
|
||||||
|
get_local_ssh_agent_sock() {
|
||||||
|
_found=""
|
||||||
|
if [ "$(uname)" = "Darwin" ]; then
|
||||||
|
_found=$(launchctl getenv SSH_AUTH_SOCK 2>/dev/null)
|
||||||
|
elif command -v systemctl >/dev/null 2>&1; then
|
||||||
|
# Query systemd socket units directly to avoid environment overrides.
|
||||||
|
for _u in ssh-agent.socket openssh-agent.socket gcr-ssh-agent.socket gpg-agent-ssh.socket; do
|
||||||
|
_p=$(systemctl --user show "${_u}" -p Listen 2>/dev/null | cut -d= -f2- | cut -d' ' -f1)
|
||||||
|
if ! _is_link_path "${_p}" && _is_valid_ssh_sock "${_p}"; then
|
||||||
|
_found="${_p}"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
# Fallback to systemd environment
|
||||||
|
if [ -z "${_found}" ] || _is_link_path "${_found}" || ! _is_valid_ssh_sock "${_found}"; then
|
||||||
|
_found=$(systemctl --user show-environment 2>/dev/null | grep "^SSH_AUTH_SOCK=" | cut -d= -f2-)
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "${_found}" ] && ! _is_link_path "${_found}" && _is_valid_ssh_sock "${_found}"; then
|
||||||
|
echo "${_found}"
|
||||||
|
unset -v _found _u _p
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Search common fallback paths
|
||||||
|
_u=$(id -u)
|
||||||
|
for _p in "/run/user/${_u}/keyring/ssh" "/run/user/${_u}/ssh-agent.socket" "/run/user/${_u}/openssh_agent" "/run/user/${_u}/gnupg/S.gpg-agent.ssh"; do
|
||||||
|
if ! _is_link_path "${_p}" && _is_valid_ssh_sock "${_p}"; then
|
||||||
|
echo "${_p}"
|
||||||
|
unset -v _found _u _p
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Search /run/user/UID and /tmp for agent.* sockets
|
||||||
|
_search=""
|
||||||
|
for _d in "/run/user/${_u}" /tmp; do [ -d "${_d}" ] && _search="${_search} ${_d}"; done
|
||||||
|
if [ -n "${_search}" ]; then
|
||||||
|
for _p in $(find ${_search} -maxdepth 2 -type s -name 'agent.*' 2>/dev/null); do
|
||||||
|
if ! _is_link_path "${_p}" && _is_valid_ssh_sock "${_p}"; then
|
||||||
|
echo "${_p}"
|
||||||
|
unset -v _found _u _p _search _d
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
unset -v _found _u _p _search _d
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to reset SSH_AUTH_SOCK to the local ssh-agent
|
||||||
|
reset_ssh_socket() {
|
||||||
|
_rss_sock=$(get_local_ssh_agent_sock)
|
||||||
|
if [ -n "${_rss_sock}" ]; then
|
||||||
|
_rss_link="${HOME}/.ssh/ssh_auth_sock"
|
||||||
|
mkdir -p "$(dirname "${_rss_link}")"
|
||||||
|
ln -sf "${_rss_sock}" "${_rss_link}"
|
||||||
|
export SSH_AUTH_SOCK="${_rss_link}"
|
||||||
|
if command -v systemctl >/dev/null 2>&1; then
|
||||||
|
systemctl --user set-environment SSH_AUTH_SOCK="${_rss_link}" 2>/dev/null
|
||||||
|
fi
|
||||||
|
echo "Reset SSH_AUTH_SOCK to ${_rss_link} -> ${_rss_sock}"
|
||||||
|
unset -v _rss_sock _rss_link
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
echo "reset_ssh_socket: no valid local ssh-agent socket found." >&2
|
||||||
|
unset -v _rss_sock
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
_CANDIDATE=""
|
_CANDIDATE=""
|
||||||
|
|
||||||
# 1. If current environment has a valid socket that is NOT our link, it's a prime candidate
|
# 1. If current environment has a valid socket that is NOT our link, it's a prime candidate
|
||||||
# (e.g. fresh SSH login: sshd sets SSH_AUTH_SOCK to the raw forwarded socket before ssh/rc
|
# (e.g. fresh SSH login: sshd sets SSH_AUTH_SOCK to the raw forwarded socket before ssh/rc
|
||||||
# rewrites it to the stable symlink; the shell inherits the original raw path).
|
# rewrites it to the stable symlink; the shell inherits the original raw path).
|
||||||
if [ -S "${SSH_AUTH_SOCK:-}" ] && ! _is_link_path "${SSH_AUTH_SOCK}"; then
|
if ! _is_link_path "${SSH_AUTH_SOCK:-}" && _is_valid_ssh_sock "${SSH_AUTH_SOCK:-}"; then
|
||||||
_CANDIDATE="${SSH_AUTH_SOCK}"
|
_CANDIDATE="${SSH_AUTH_SOCK}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 2. Only look for a system agent if the stable link is already broken. If the link is
|
# 2. Only look for a system agent if the stable link is already broken. If the link is
|
||||||
# valid (e.g. a tmux pane where SSH_AUTH_SOCK points to our symlink which ssh/rc just
|
# valid (e.g. a tmux pane where SSH_AUTH_SOCK points to our symlink which ssh/rc just
|
||||||
# updated to the forwarded socket), leave it alone — don't clobber it with a local agent.
|
# updated to the forwarded socket), leave it alone — don't clobber it with a local agent.
|
||||||
if [ -z "${_CANDIDATE}" ] && [ ! -S "${_SSH_AUTH_LINK}" ]; then
|
if [ -z "${_CANDIDATE}" ] && ! _is_valid_ssh_sock "${_SSH_AUTH_LINK}"; then
|
||||||
_FOUND=""
|
_CANDIDATE=$(get_local_ssh_agent_sock)
|
||||||
if [ "$(uname)" = "Darwin" ]; then
|
|
||||||
_FOUND=$(launchctl getenv SSH_AUTH_SOCK 2>/dev/null)
|
|
||||||
elif command -v systemctl >/dev/null 2>&1; then
|
|
||||||
# Query systemd socket units directly to avoid environment overrides.
|
|
||||||
for _u in ssh-agent.socket openssh-agent.socket gcr-ssh-agent.socket gpg-agent-ssh.socket; do
|
|
||||||
_P=$(systemctl --user show "${_u}" -p Listen 2>/dev/null | cut -d= -f2- | cut -d' ' -f1)
|
|
||||||
if [ -S "${_P}" ]; then
|
|
||||||
_FOUND="${_P}"
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
# Fallback to systemd environment
|
|
||||||
if [ -z "${_FOUND}" ] || _is_link_path "${_FOUND}"; then
|
|
||||||
_FOUND=$(systemctl --user show-environment 2>/dev/null | grep "^SSH_AUTH_SOCK=" | cut -d= -f2-)
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -S "${_FOUND}" ] && ! _is_link_path "${_FOUND}"; then
|
# 3. Sync the stable link if we found a valid "real" socket.
|
||||||
_CANDIDATE="${_FOUND}"
|
if [ -n "${_CANDIDATE}" ] && ! _is_link_path "${_CANDIDATE}" && _is_valid_ssh_sock "${_CANDIDATE}"; then
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 3. Last resort: search common paths if we still don't have a candidate and the link is broken.
|
|
||||||
if [ ! -S "${_CANDIDATE}" ] && [ ! -S "${_SSH_AUTH_LINK}" ]; then
|
|
||||||
_U=$(id -u)
|
|
||||||
for _p in "/run/user/${_U}/keyring/ssh" "/run/user/${_U}/ssh-agent.socket" "/run/user/${_U}/openssh_agent" "/run/user/${_U}/gnupg/S.gpg-agent.ssh"; do
|
|
||||||
if [ -S "${_p}" ] && ! _is_link_path "${_p}"; then
|
|
||||||
_CANDIDATE="${_p}"
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
if [ -z "${_CANDIDATE}" ]; then
|
|
||||||
# Build search path list based on what actually exists
|
|
||||||
_SEARCH=""
|
|
||||||
for _d in "/run/user/${_U}" /tmp; do [ -d "${_d}" ] && _SEARCH="${_SEARCH} ${_d}"; done
|
|
||||||
if [ -n "${_SEARCH}" ]; then
|
|
||||||
_CANDIDATE=$(find ${_SEARCH} -maxdepth 2 -type s -name 'agent.*' 2>/dev/null | grep -F -v "${_SSH_AUTH_LINK}" | head -n 1)
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 4. Sync the stable link if we found a valid "real" socket.
|
|
||||||
if [ -S "${_CANDIDATE}" ] && ! _is_link_path "${_CANDIDATE}"; then
|
|
||||||
mkdir -p "$(dirname "${_SSH_AUTH_LINK}")"
|
mkdir -p "$(dirname "${_SSH_AUTH_LINK}")"
|
||||||
ln -sf "${_CANDIDATE}" "${_SSH_AUTH_LINK}"
|
ln -sf "${_CANDIDATE}" "${_SSH_AUTH_LINK}"
|
||||||
export SSH_AUTH_SOCK="${_SSH_AUTH_LINK}"
|
export SSH_AUTH_SOCK="${_SSH_AUTH_LINK}"
|
||||||
@@ -176,17 +245,18 @@ if [ -S "${_CANDIDATE}" ] && ! _is_link_path "${_CANDIDATE}"; then
|
|||||||
if command -v systemctl >/dev/null 2>&1; then
|
if command -v systemctl >/dev/null 2>&1; then
|
||||||
systemctl --user set-environment SSH_AUTH_SOCK="${_SSH_AUTH_LINK}" 2>/dev/null
|
systemctl --user set-environment SSH_AUTH_SOCK="${_SSH_AUTH_LINK}" 2>/dev/null
|
||||||
fi
|
fi
|
||||||
elif [ -S "${_SSH_AUTH_LINK}" ]; then
|
elif _is_valid_ssh_sock "${_SSH_AUTH_LINK}"; then
|
||||||
# If we found nothing better but the link is valid, use it.
|
# If we found nothing better but the link is valid, use it.
|
||||||
export SSH_AUTH_SOCK="${_SSH_AUTH_LINK}"
|
export SSH_AUTH_SOCK="${_SSH_AUTH_LINK}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
unset _SSH_AUTH_LINK _CANDIDATE _FOUND _T _P _U _u _SEARCH _d
|
unset _SSH_AUTH_LINK _CANDIDATE
|
||||||
unset -f _is_link_path
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
# Setup XDG-like dirs on MacOS
|
# Setup XDG-like dirs on MacOS
|
||||||
# Based on https://leebyron.com/til/mac-xdg/
|
# Based on https://leebyron.com/til/mac-xdg/
|
||||||
if [ "$(uname)" = "Darwin" ] ; then
|
if [ "${_UNAME}" = "Darwin" ] ; then
|
||||||
export XDG_BIN_HOME="${XDG_BIN_HOME:-$HOME/.local/bin}"
|
export XDG_BIN_HOME="${XDG_BIN_HOME:-$HOME/.local/bin}"
|
||||||
export XDG_CACHE_HOME="${XDG_CACHE_HOME:-$HOME/Library/Caches}"
|
export XDG_CACHE_HOME="${XDG_CACHE_HOME:-$HOME/Library/Caches}"
|
||||||
export XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/.config}"
|
export XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/.config}"
|
||||||
@@ -195,10 +265,12 @@ if [ "$(uname)" = "Darwin" ] ; then
|
|||||||
export XDG_RUNTIME_DIR="${XDG_RUNTIME_DIR:-$TMPDIR/runtime-$(id -u)}"
|
export XDG_RUNTIME_DIR="${XDG_RUNTIME_DIR:-$TMPDIR/runtime-$(id -u)}"
|
||||||
export XDG_STATE_HOME="${XDG_STATE_HOME:-$HOME/.local/state}"
|
export XDG_STATE_HOME="${XDG_STATE_HOME:-$HOME/.local/state}"
|
||||||
export PATH="${HOME}/bin/macos:${PATH}"
|
export PATH="${HOME}/bin/macos:${PATH}"
|
||||||
elif [ "$(uname)" = "Linux" ] ; then
|
elif [ "${_UNAME}" = "Linux" ] ; then
|
||||||
export PATH="${HOME}/bin/linux:${PATH}"
|
export PATH="${HOME}/bin/linux:${PATH}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
unset _UNAME
|
||||||
|
|
||||||
if test -e "$HOME/.localenv"; then
|
if test -e "$HOME/.localenv"; then
|
||||||
# shellcheck source=/dev/null
|
# shellcheck source=/dev/null
|
||||||
. "$HOME/.localenv"
|
. "$HOME/.localenv"
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
# For interactive shells
|
# For interactive shells
|
||||||
[[ -n "$ZSH_PROFILE" ]] && {
|
[[ -n "$ZSH_PROFILE" ]] && {
|
||||||
zmodload zsh/datetime
|
zmodload zsh/datetime
|
||||||
zshrc_start_time=$EPOCHREALTIME
|
|
||||||
zmodload zsh/zprof
|
zmodload zsh/zprof
|
||||||
|
export PS4='+[%D{%f} / %D{%s.%N}] %N:%i> '
|
||||||
|
exec 3>&2 2>/tmp/zsh_startup.log
|
||||||
|
set -x
|
||||||
|
zshrc_start_time=$EPOCHREALTIME
|
||||||
}
|
}
|
||||||
HISTFILE=~/.zhistory
|
HISTFILE=~/.zhistory
|
||||||
HISTSIZE=10000
|
HISTSIZE=10000
|
||||||
@@ -129,7 +132,12 @@ case $TERM in
|
|||||||
else
|
else
|
||||||
# this will also work in tmux but is not what we want
|
# this will also work in tmux but is not what we want
|
||||||
# Set the terminal title to include the command being run
|
# Set the terminal title to include the command being run
|
||||||
|
# Skip adding (cmd) in iTerm2 — shell integration already injects the job name
|
||||||
|
if [[ -z "$ITERM_SESSION_ID" ]]; then
|
||||||
print -Pn "\e]0;%n@%m: %~ ($cmd)\a"
|
print -Pn "\e]0;%n@%m: %~ ($cmd)\a"
|
||||||
|
else
|
||||||
|
print -Pn "\e]0;%n@%m: %~\a"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
# Add the hooks to zsh
|
# Add the hooks to zsh
|
||||||
@@ -298,6 +306,8 @@ typeset -U PATH
|
|||||||
|
|
||||||
if [[ -n "$ZSH_PROFILE" ]]; then
|
if [[ -n "$ZSH_PROFILE" ]]; then
|
||||||
zshrc_end_time=$EPOCHREALTIME
|
zshrc_end_time=$EPOCHREALTIME
|
||||||
|
set +x
|
||||||
|
exec 2>&3 3>&-
|
||||||
# Calculation in ms using zsh floating point math
|
# Calculation in ms using zsh floating point math
|
||||||
elapsed_ms=$(( (zshrc_end_time - zshrc_start_time) * 1000 ))
|
elapsed_ms=$(( (zshrc_end_time - zshrc_start_time) * 1000 ))
|
||||||
printf "zshrc done: %.0fms\n" "$elapsed_ms"
|
printf "zshrc done: %.0fms\n" "$elapsed_ms"
|
||||||
|
|||||||
@@ -14,4 +14,8 @@
|
|||||||
have_command docker && \
|
have_command docker && \
|
||||||
missing_comp _docker && \
|
missing_comp _docker && \
|
||||||
docker completion zsh > $COMPDIR/_docker || true
|
docker completion zsh > $COMPDIR/_docker || true
|
||||||
|
|
||||||
|
have_command resticprofile && \
|
||||||
|
missing_comp _resticprofile && \
|
||||||
|
resticprofile generate --zsh-completion > $COMPDIR/_resticprofile || true
|
||||||
} &>/dev/null &!
|
} &>/dev/null &!
|
||||||
|
|||||||
@@ -72,3 +72,27 @@ function generate_secure_key {
|
|||||||
local BYTES=$((BITS/8))
|
local BYTES=$((BITS/8))
|
||||||
head -c "${BYTES}" /dev/urandom | ${(s: :)ENCODE}
|
head -c "${BYTES}" /dev/urandom | ${(s: :)ENCODE}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function reset-ssh-socket {
|
||||||
|
reset_ssh_socket "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
function with-local-ssh-agent {
|
||||||
|
local sock
|
||||||
|
sock=$(get_local_ssh_agent_sock)
|
||||||
|
if [[ -z "${sock}" ]] ; then
|
||||||
|
echo "with-local-ssh-agent: no valid local ssh-agent socket found." >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
if [ "$#" -eq 0 ] ; then
|
||||||
|
(
|
||||||
|
export SSH_AUTH_SOCK="${sock}"
|
||||||
|
"${SHELL:-zsh}"
|
||||||
|
)
|
||||||
|
else
|
||||||
|
(
|
||||||
|
export SSH_AUTH_SOCK="${sock}"
|
||||||
|
eval "$@"
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|||||||
17
install.sh
17
install.sh
@@ -151,12 +151,12 @@ read_saved_prefs() {
|
|||||||
|
|
||||||
save_prefs() {
|
save_prefs() {
|
||||||
[[ "$SAVE" = 1 ]] || return 0
|
[[ "$SAVE" = 1 ]] || return 0
|
||||||
local pref_file=${BASEDIR}/.installed-prefs
|
local pref_file="${BASEDIR}/.installed-prefs"
|
||||||
{
|
{
|
||||||
echo "BASEDIR=\"${BASEDIR}\""
|
printf 'BASEDIR=%q\n' "${BASEDIR}"
|
||||||
echo "MINIMAL=\"${MINIMAL}\""
|
printf 'MINIMAL=%q\n' "${MINIMAL}"
|
||||||
echo "INSTALL_KEYS=\"${INSTALL_KEYS}\""
|
printf 'INSTALL_KEYS=%q\n' "${INSTALL_KEYS}"
|
||||||
echo "VERBOSE=\"${VERBOSE}\""
|
printf 'VERBOSE=%q\n' "${VERBOSE}"
|
||||||
} >| "$pref_file"
|
} >| "$pref_file"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,8 +205,7 @@ install_starship() {
|
|||||||
echo "apt-get install starship failed, installing locally" >&2
|
echo "apt-get install starship failed, installing locally" >&2
|
||||||
fi
|
fi
|
||||||
local tmpd
|
local tmpd
|
||||||
tmpd="$(mktemp -d tmp.starship.XXXXXX)" || return 1
|
tmpd="$(mktemp -d "${TMPDIR:-/tmp}/starship.XXXXXX")" || return 1
|
||||||
trap '[[ -n "${tmpd}" && -d "${tmpd}" ]] && rm -rf "${tmpd}"' EXIT
|
|
||||||
|
|
||||||
local install_path="${tmpd}/install.sh"
|
local install_path="${tmpd}/install.sh"
|
||||||
if have_command curl ; then
|
if have_command curl ; then
|
||||||
@@ -216,7 +215,6 @@ install_starship() {
|
|||||||
else
|
else
|
||||||
echo "No curl or wget available!!" >&2
|
echo "No curl or wget available!!" >&2
|
||||||
rm -rf "${tmpd}"
|
rm -rf "${tmpd}"
|
||||||
trap - EXIT
|
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
local dl_hash
|
local dl_hash
|
||||||
@@ -225,20 +223,17 @@ install_starship() {
|
|||||||
echo "Hash check failed!!" >&2
|
echo "Hash check failed!!" >&2
|
||||||
echo "Expected: ${STARSHIP_INSTALL_HASH}, got ${dl_hash} on ${install_path}" >&2
|
echo "Expected: ${STARSHIP_INSTALL_HASH}, got ${dl_hash} on ${install_path}" >&2
|
||||||
rm -rf "${tmpd}"
|
rm -rf "${tmpd}"
|
||||||
trap - EXIT
|
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
if sudo_group ; then
|
if sudo_group ; then
|
||||||
if maybe_sudo sh "${install_path}" ; then
|
if maybe_sudo sh "${install_path}" ; then
|
||||||
rm -rf "${tmpd}"
|
rm -rf "${tmpd}"
|
||||||
trap - EXIT
|
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
echo "root installation failed, falling back to user-local" >&2
|
echo "root installation failed, falling back to user-local" >&2
|
||||||
fi
|
fi
|
||||||
sh "${install_path}" -b "${LOCAL_BIN}"
|
sh "${install_path}" -b "${LOCAL_BIN}"
|
||||||
rm -rf "${tmpd}"
|
rm -rf "${tmpd}"
|
||||||
trap - EXIT
|
|
||||||
}
|
}
|
||||||
|
|
||||||
install_main() {
|
install_main() {
|
||||||
|
|||||||
Reference in New Issue
Block a user