Refactor setup workflow
This commit is contained in:
32
Bins/versions.json
Normal file
32
Bins/versions.json
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
"nvim": {
|
||||||
|
"owner": "neovim",
|
||||||
|
"repo": "neovim",
|
||||||
|
"version": "v0.11.5",
|
||||||
|
"linux": {
|
||||||
|
"x86_64": {
|
||||||
|
"asset": "nvim-linux-x86_64.tar.gz",
|
||||||
|
"binary": "nvim-linux-x86_64/bin/nvim"
|
||||||
|
},
|
||||||
|
"aarch64": {
|
||||||
|
"asset": "nvim-linux-arm64.tar.gz",
|
||||||
|
"binary": "nvim-linux-arm64/bin/nvim"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"eza": {
|
||||||
|
"owner": "eza-community",
|
||||||
|
"repo": "eza",
|
||||||
|
"version": "v0.23.4",
|
||||||
|
"linux": {
|
||||||
|
"x86_64": {
|
||||||
|
"asset": "eza_x86_64-unknown-linux-gnu.tar.gz",
|
||||||
|
"binary": "eza"
|
||||||
|
},
|
||||||
|
"aarch64": {
|
||||||
|
"asset": "eza_aarch64-unknown-linux-gnu.tar.gz",
|
||||||
|
"binary": "eza"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
22
Commands/Bin/mod.just
Normal file
22
Commands/Bin/mod.just
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
project_root := justfile_directory()
|
||||||
|
bin_script_dir := project_root + "/Scripts/bin"
|
||||||
|
|
||||||
|
# Install all pinned repo-managed binaries into ~/.local/bin.
|
||||||
|
install-all:
|
||||||
|
bash '{{bin_script_dir}}/install.sh' --all
|
||||||
|
|
||||||
|
# Install one pinned repo-managed binary into ~/.local/bin.
|
||||||
|
install tool:
|
||||||
|
bash '{{bin_script_dir}}/install.sh' '{{tool}}'
|
||||||
|
|
||||||
|
# Update the pinned version for a binary. If no version is given, open an fzf selector when available.
|
||||||
|
update tool version='':
|
||||||
|
bash '{{bin_script_dir}}/update.sh' '{{tool}}' '{{version}}'
|
||||||
|
|
||||||
|
# List available releases for a supported binary.
|
||||||
|
list tool:
|
||||||
|
bash '{{bin_script_dir}}/update.sh' --list '{{tool}}'
|
||||||
|
|
||||||
|
# Print the currently pinned versions.
|
||||||
|
show:
|
||||||
|
cat '{{project_root}}/Bins/versions.json'
|
||||||
20
Commands/Lang/mod.just
Normal file
20
Commands/Lang/mod.just
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
project_root := justfile_directory()
|
||||||
|
scripts_dir := project_root + "/Scripts"
|
||||||
|
|
||||||
|
node:
|
||||||
|
bash '{{scripts_dir}}/node.sh'
|
||||||
|
|
||||||
|
go:
|
||||||
|
bash '{{scripts_dir}}/go.sh'
|
||||||
|
|
||||||
|
rust:
|
||||||
|
bash '{{scripts_dir}}/rust.sh'
|
||||||
|
|
||||||
|
python:
|
||||||
|
bash '{{scripts_dir}}/python.sh'
|
||||||
|
|
||||||
|
r:
|
||||||
|
bash '{{scripts_dir}}/r.sh'
|
||||||
|
|
||||||
|
cpp:
|
||||||
|
bash '{{scripts_dir}}/cpp.sh'
|
||||||
43
Commands/Setup/mod.just
Normal file
43
Commands/Setup/mod.just
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
project_root := justfile_directory()
|
||||||
|
scripts_dir := project_root + "/Scripts"
|
||||||
|
|
||||||
|
# Run the full setup flow.
|
||||||
|
all:
|
||||||
|
bash '{{scripts_dir}}/setup.sh'
|
||||||
|
|
||||||
|
# Install the base system layer only.
|
||||||
|
base:
|
||||||
|
bash '{{scripts_dir}}/base.sh'
|
||||||
|
|
||||||
|
# Stow shell files into $HOME.
|
||||||
|
stow:
|
||||||
|
stow --dir='{{project_root}}' Zsh --target="$HOME"
|
||||||
|
|
||||||
|
# Remove stowed shell files from $HOME.
|
||||||
|
clean:
|
||||||
|
stow --dir='{{project_root}}' -D Zsh --target="$HOME"
|
||||||
|
|
||||||
|
# Pull latest changes and rerun setup.
|
||||||
|
update:
|
||||||
|
git -C '{{project_root}}' pull origin main
|
||||||
|
just --justfile '{{project_root}}/Justfile' setup all
|
||||||
|
|
||||||
|
# Run distro test containers.
|
||||||
|
test-ubuntu:
|
||||||
|
echo "Ubuntu Test"
|
||||||
|
docker run -it --rm -e TERM=xterm-256color -v '{{project_root}}':/root/dotfiles ubuntu:latest \
|
||||||
|
bash -c "export DEBIAN_FRONTEND=noninteractive && \
|
||||||
|
apt-get update && \
|
||||||
|
apt-get install -y sudo git make curl && \
|
||||||
|
cd /root/dotfiles && \
|
||||||
|
make setup"
|
||||||
|
|
||||||
|
test-arch:
|
||||||
|
echo "Spawning Arch Container..."
|
||||||
|
docker run -it --rm -e TERM=xterm-256color -v '{{project_root}}':/root/dotfiles archlinux:latest \
|
||||||
|
bash -c "pacman -Sy --noconfirm base-devel git make sudo && cd /root/dotfiles && make setup"
|
||||||
|
|
||||||
|
test-fedora:
|
||||||
|
echo "Spawning Fedora Container..."
|
||||||
|
docker run -it --rm -e TERM=xterm-256color -v '{{project_root}}':/root/dotfiles fedora:latest \
|
||||||
|
bash -c "dnf install -y git make sudo curl which passwd procps-ng && cd /root/dotfiles && make setup"
|
||||||
9
Justfile
Normal file
9
Justfile
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
set shell := ["bash", "-cu"]
|
||||||
|
|
||||||
|
mod bin "Commands/Bin"
|
||||||
|
mod lang "Commands/Lang"
|
||||||
|
mod setup "Commands/Setup"
|
||||||
|
|
||||||
|
[default]
|
||||||
|
help:
|
||||||
|
just --list --list-submodules
|
||||||
91
Makefile
91
Makefile
@@ -1,93 +1,10 @@
|
|||||||
# Makefile
|
# Makefile
|
||||||
|
|
||||||
REBOOT_MARKER := .setup-reboot-required
|
SCRIPTS_DIR := ./Scripts
|
||||||
|
|
||||||
# Default target
|
# Default target
|
||||||
all: stow
|
all: setup
|
||||||
|
|
||||||
# Full Setup
|
# Bootstrap entrypoint for first-run setup.
|
||||||
setup:
|
setup:
|
||||||
@set -e; \
|
bash $(SCRIPTS_DIR)/setup.sh
|
||||||
rm -f $(REBOOT_MARKER); \
|
|
||||||
bash ./scripts/base.sh; \
|
|
||||||
if [ -f $(REBOOT_MARKER) ]; then \
|
|
||||||
rm -f $(REBOOT_MARKER); \
|
|
||||||
echo "Package layering finished. Reboot, then rerun make setup."; \
|
|
||||||
exit 0; \
|
|
||||||
fi; \
|
|
||||||
bash ./scripts/node.sh; \
|
|
||||||
bash ./scripts/go.sh; \
|
|
||||||
bash ./scripts/rust.sh; \
|
|
||||||
bash ./scripts/python.sh; \
|
|
||||||
if [ -f $(REBOOT_MARKER) ]; then \
|
|
||||||
rm -f $(REBOOT_MARKER); \
|
|
||||||
echo "Package layering finished. Reboot, then rerun make setup."; \
|
|
||||||
exit 0; \
|
|
||||||
fi; \
|
|
||||||
bash ./scripts/r.sh; \
|
|
||||||
if [ -f $(REBOOT_MARKER) ]; then \
|
|
||||||
rm -f $(REBOOT_MARKER); \
|
|
||||||
echo "Package layering finished. Reboot, then rerun make setup."; \
|
|
||||||
exit 0; \
|
|
||||||
fi; \
|
|
||||||
$(MAKE) clean; \
|
|
||||||
$(MAKE) stow; \
|
|
||||||
echo "Full setup completed."
|
|
||||||
|
|
||||||
base:
|
|
||||||
bash ./scripts/base.sh
|
|
||||||
@echo "Base setup completed."
|
|
||||||
|
|
||||||
# Just stow the dotfiles
|
|
||||||
stow:
|
|
||||||
stow . --target=$$HOME --ignore=".git" --ignore=".gitignore" --ignore="README.md" --ignore=".zsh_secrets" --ignore=".zsh_secrets.example" --ignore="LICENSE" --ignore="Makefile" --ignore="bin" --ignore="scripts"
|
|
||||||
@echo "Dotfiles linked."
|
|
||||||
|
|
||||||
# Clean old files and links
|
|
||||||
clean:
|
|
||||||
stow -D . --target=$$HOME
|
|
||||||
@echo "Links removed."
|
|
||||||
|
|
||||||
# Pull Git Updates
|
|
||||||
update:
|
|
||||||
git pull origin main
|
|
||||||
$(MAKE) setup
|
|
||||||
|
|
||||||
# Language Setups
|
|
||||||
node:
|
|
||||||
bash ./scripts/node.sh
|
|
||||||
|
|
||||||
go:
|
|
||||||
bash ./scripts/go.sh
|
|
||||||
|
|
||||||
rust:
|
|
||||||
bash ./scripts/rust.sh
|
|
||||||
|
|
||||||
python:
|
|
||||||
bash ./scripts/python.sh
|
|
||||||
|
|
||||||
r:
|
|
||||||
bash ./scripts/r.sh
|
|
||||||
|
|
||||||
cpp:
|
|
||||||
bash ./scripts/cpp.sh
|
|
||||||
|
|
||||||
# Docker Tests
|
|
||||||
test-ubuntu:
|
|
||||||
@echo "Ubuntu Test"
|
|
||||||
docker run -it --rm -e TERM=xterm-256color -v $(PWD):/root/dotfiles ubuntu:latest \
|
|
||||||
bash -c "export DEBIAN_FRONTEND=noninteractive && \
|
|
||||||
apt-get update && \
|
|
||||||
apt-get install -y sudo git make curl && \
|
|
||||||
cd /root/dotfiles && \
|
|
||||||
make setup"
|
|
||||||
|
|
||||||
test-arch:
|
|
||||||
@echo "Spawning Arch Container..."
|
|
||||||
docker run -it --rm -e TERM=xterm-256color -v $(PWD):/root/dotfiles archlinux:latest \
|
|
||||||
bash -c "pacman -Sy --noconfirm base-devel git make sudo && cd /root/dotfiles && make setup"
|
|
||||||
|
|
||||||
test-fedora:
|
|
||||||
@echo "Spawning Fedora Container..."
|
|
||||||
docker run -it --rm -e TERM=xterm-256color -v $(PWD):/root/dotfiles fedora:latest \
|
|
||||||
bash -c "dnf install -y git make sudo curl which passwd procps-ng && cd /root/dotfiles && make setup"
|
|
||||||
|
|||||||
11
scripts/base.sh → Scripts/base.sh
Executable file → Normal file
11
scripts/base.sh → Scripts/base.sh
Executable file → Normal file
@@ -1,6 +1,6 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Path: scripts/base.sh
|
# Path: Scripts/base.sh
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
@@ -154,10 +154,8 @@ if is_debian_family || is_fedora_family; then
|
|||||||
[ -f /usr/bin/batcat ] && sudo ln -sf /usr/bin/batcat /usr/local/bin/bat
|
[ -f /usr/bin/batcat ] && sudo ln -sf /usr/bin/batcat /usr/local/bin/bat
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Moving Pre-Built bin to .local/bin
|
# Installing pinned repo-managed CLI binaries
|
||||||
mkdir -p "$HOME/.local/bin"
|
bash "$REPO_ROOT/Scripts/bin/install.sh" --all
|
||||||
cp -f "$REPO_ROOT/bin/"* "$HOME/.local/bin/"
|
|
||||||
chmod +x "$HOME/.local/bin/"*
|
|
||||||
|
|
||||||
if ! command -v rclone &> /dev/null; then
|
if ! command -v rclone &> /dev/null; then
|
||||||
echo -e "${BLUE} LOG:${YELLOW} Installing Rclone CLI...${NC}"
|
echo -e "${BLUE} LOG:${YELLOW} Installing Rclone CLI...${NC}"
|
||||||
@@ -250,7 +248,8 @@ fi
|
|||||||
|
|
||||||
# 6. Cleanup & Secrets
|
# 6. Cleanup & Secrets
|
||||||
rm -f "$HOME/.zshrc" "$HOME/.zsh_aliases"
|
rm -f "$HOME/.zshrc" "$HOME/.zsh_aliases"
|
||||||
touch "$HOME/.zsh_secrets"
|
mkdir -p "$REPO_ROOT/Zsh"
|
||||||
|
touch "$REPO_ROOT/Zsh/.zsh_secrets"
|
||||||
|
|
||||||
# 7. Set Shell
|
# 7. Set Shell
|
||||||
TARGET_SHELL="$(command -v zsh)"
|
TARGET_SHELL="$(command -v zsh)"
|
||||||
99
Scripts/bin/install.sh
Normal file
99
Scripts/bin/install.sh
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
REPO_ROOT="$(dirname "$(dirname "$SCRIPT_DIR")")"
|
||||||
|
MANIFEST="$REPO_ROOT/Bins/versions.json"
|
||||||
|
TARGET_DIR="$HOME/.local/bin"
|
||||||
|
|
||||||
|
ensure_deps() {
|
||||||
|
local missing=()
|
||||||
|
|
||||||
|
for cmd in jq curl tar; do
|
||||||
|
if ! command -v "$cmd" >/dev/null 2>&1; then
|
||||||
|
missing+=("$cmd")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "${#missing[@]}" -gt 0 ]; then
|
||||||
|
printf 'Missing required commands: %s\n' "${missing[*]}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
detect_arch() {
|
||||||
|
case "$(uname -m)" in
|
||||||
|
x86_64) printf 'x86_64\n' ;;
|
||||||
|
aarch64|arm64) printf 'aarch64\n' ;;
|
||||||
|
*)
|
||||||
|
printf 'Unsupported architecture: %s\n' "$(uname -m)" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
install_tool() {
|
||||||
|
local tool="$1"
|
||||||
|
local arch version owner repo asset binary_rel url tmp_dir archive_path extracted_path target_path
|
||||||
|
|
||||||
|
arch="$(detect_arch)"
|
||||||
|
|
||||||
|
if ! jq -e --arg tool "$tool" '.[$tool]' "$MANIFEST" >/dev/null; then
|
||||||
|
printf 'Unsupported tool: %s\n' "$tool" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
version="$(jq -r --arg tool "$tool" '.[$tool].version' "$MANIFEST")"
|
||||||
|
owner="$(jq -r --arg tool "$tool" '.[$tool].owner' "$MANIFEST")"
|
||||||
|
repo="$(jq -r --arg tool "$tool" '.[$tool].repo' "$MANIFEST")"
|
||||||
|
asset="$(jq -r --arg tool "$tool" --arg arch "$arch" '.[$tool].linux[$arch].asset' "$MANIFEST")"
|
||||||
|
binary_rel="$(jq -r --arg tool "$tool" --arg arch "$arch" '.[$tool].linux[$arch].binary' "$MANIFEST")"
|
||||||
|
|
||||||
|
if [ -z "$asset" ] || [ "$asset" = "null" ] || [ -z "$binary_rel" ] || [ "$binary_rel" = "null" ]; then
|
||||||
|
printf 'No Linux asset mapping for %s on %s\n' "$tool" "$arch" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$TARGET_DIR"
|
||||||
|
tmp_dir="$(mktemp -d)"
|
||||||
|
archive_path="$tmp_dir/$asset"
|
||||||
|
url="https://github.com/$owner/$repo/releases/download/$version/$asset"
|
||||||
|
|
||||||
|
printf 'Installing %s %s\n' "$tool" "$version"
|
||||||
|
curl -fL "$url" -o "$archive_path"
|
||||||
|
tar -xzf "$archive_path" -C "$tmp_dir"
|
||||||
|
|
||||||
|
extracted_path="$tmp_dir/$binary_rel"
|
||||||
|
if [ ! -f "$extracted_path" ]; then
|
||||||
|
printf 'Expected binary not found after extraction: %s\n' "$binary_rel" >&2
|
||||||
|
rm -rf "$tmp_dir"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
target_path="$TARGET_DIR/$tool"
|
||||||
|
install -m 755 "$extracted_path" "$target_path"
|
||||||
|
rm -rf "$tmp_dir"
|
||||||
|
|
||||||
|
printf 'Installed %s -> %s\n' "$tool" "$target_path"
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
ensure_deps
|
||||||
|
|
||||||
|
if [ "${1:-}" = "--all" ]; then
|
||||||
|
while IFS= read -r tool; do
|
||||||
|
install_tool "$tool"
|
||||||
|
done < <(jq -r 'keys[]' "$MANIFEST")
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${1:-}" ]; then
|
||||||
|
printf 'Usage: %s [--all|tool]\n' "$0" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
install_tool "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
135
Scripts/bin/update.sh
Normal file
135
Scripts/bin/update.sh
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
REPO_ROOT="$(dirname "$(dirname "$SCRIPT_DIR")")"
|
||||||
|
MANIFEST="$REPO_ROOT/Bins/versions.json"
|
||||||
|
|
||||||
|
ensure_deps() {
|
||||||
|
local missing=()
|
||||||
|
|
||||||
|
for cmd in jq curl python3; do
|
||||||
|
if ! command -v "$cmd" >/dev/null 2>&1; then
|
||||||
|
missing+=("$cmd")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "${#missing[@]}" -gt 0 ]; then
|
||||||
|
printf 'Missing required commands: %s\n' "${missing[*]}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
github_api() {
|
||||||
|
local path="$1"
|
||||||
|
local auth_args=()
|
||||||
|
|
||||||
|
if [ -n "${GITHUB_TOKEN:-}" ]; then
|
||||||
|
auth_args=(-H "Authorization: Bearer $GITHUB_TOKEN")
|
||||||
|
fi
|
||||||
|
|
||||||
|
curl -fsSL \
|
||||||
|
-H "Accept: application/vnd.github+json" \
|
||||||
|
"${auth_args[@]}" \
|
||||||
|
"https://api.github.com${path}"
|
||||||
|
}
|
||||||
|
|
||||||
|
list_versions() {
|
||||||
|
local tool="$1" owner repo
|
||||||
|
|
||||||
|
if ! jq -e --arg tool "$tool" '.[$tool]' "$MANIFEST" >/dev/null; then
|
||||||
|
printf 'Unsupported tool: %s\n' "$tool" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
owner="$(jq -r --arg tool "$tool" '.[$tool].owner' "$MANIFEST")"
|
||||||
|
repo="$(jq -r --arg tool "$tool" '.[$tool].repo' "$MANIFEST")"
|
||||||
|
|
||||||
|
github_api "/repos/$owner/$repo/releases?per_page=100" | jq -r '.[].tag_name'
|
||||||
|
}
|
||||||
|
|
||||||
|
select_version() {
|
||||||
|
local tool="$1"
|
||||||
|
local versions
|
||||||
|
|
||||||
|
versions="$(list_versions "$tool")"
|
||||||
|
|
||||||
|
if [ -z "$versions" ]; then
|
||||||
|
printf 'No releases found for %s\n' "$tool" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if command -v fzf >/dev/null 2>&1; then
|
||||||
|
printf '%s\n' "$versions" | fzf --prompt="Select ${tool} version > " --height=20 --reverse
|
||||||
|
else
|
||||||
|
printf '%s\n' "$versions" | sed -n '1,20p' >&2
|
||||||
|
printf 'fzf is not installed, so pass a version explicitly.\n' >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
update_version() {
|
||||||
|
local tool="$1" version="$2"
|
||||||
|
local tmp_file
|
||||||
|
|
||||||
|
if [ -z "$version" ]; then
|
||||||
|
printf 'No version selected for %s\n' "$tool" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
tmp_file="$(mktemp)"
|
||||||
|
python3 - "$MANIFEST" "$tool" "$version" "$tmp_file" <<'PY'
|
||||||
|
import json
|
||||||
|
import pathlib
|
||||||
|
import sys
|
||||||
|
|
||||||
|
manifest_path = pathlib.Path(sys.argv[1])
|
||||||
|
tool = sys.argv[2]
|
||||||
|
version = sys.argv[3]
|
||||||
|
tmp_path = pathlib.Path(sys.argv[4])
|
||||||
|
|
||||||
|
data = json.loads(manifest_path.read_text())
|
||||||
|
if tool not in data:
|
||||||
|
raise SystemExit(f"Unsupported tool: {tool}")
|
||||||
|
|
||||||
|
data[tool]["version"] = version
|
||||||
|
tmp_path.write_text(json.dumps(data, indent=2) + "\n")
|
||||||
|
PY
|
||||||
|
|
||||||
|
mv "$tmp_file" "$MANIFEST"
|
||||||
|
printf 'Pinned %s to %s\n' "$tool" "$version"
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
local mode="update" tool version
|
||||||
|
|
||||||
|
ensure_deps
|
||||||
|
|
||||||
|
if [ "${1:-}" = "--list" ]; then
|
||||||
|
mode="list"
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
|
||||||
|
tool="${1:-}"
|
||||||
|
version="${2:-}"
|
||||||
|
|
||||||
|
if [ -z "$tool" ]; then
|
||||||
|
printf 'Usage: %s [--list] tool [version]\n' "$0" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
case "$mode" in
|
||||||
|
list)
|
||||||
|
list_versions "$tool"
|
||||||
|
;;
|
||||||
|
update)
|
||||||
|
if [ -z "$version" ]; then
|
||||||
|
version="$(select_version "$tool")"
|
||||||
|
fi
|
||||||
|
update_version "$tool" "$version"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Path: scripts/cpp.sh
|
# Path: Scripts/cpp.sh
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Path: scripts/go.sh
|
# Path: Scripts/go.sh
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Path: scripts/node.sh
|
# Path: Scripts/node.sh
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
2
scripts/provision.sh → Scripts/provision.sh
Executable file → Normal file
2
scripts/provision.sh → Scripts/provision.sh
Executable file → Normal file
@@ -1,6 +1,6 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Path: scripts/provision.sh
|
# Path: Scripts/provision.sh
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Path: scripts/python.sh
|
# Path: Scripts/python.sh
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
BLUE='\033[1;34m'
|
BLUE='\033[1;34m'
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Path: scripts/r.sh
|
# Path: Scripts/r.sh
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
BLUE='\033[1;34m'
|
BLUE='\033[1;34m'
|
||||||
@@ -12,6 +12,27 @@ NC='\033[0m'
|
|||||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||||
source "$SCRIPT_DIR/lib/distro.sh"
|
source "$SCRIPT_DIR/lib/distro.sh"
|
||||||
|
|
||||||
|
PROG_DIR="$HOME/.programming"
|
||||||
|
R_ROOT="$PROG_DIR/r"
|
||||||
|
R_BIN_DIR="$R_ROOT/bin"
|
||||||
|
R_LIB_DIR="$R_ROOT/library"
|
||||||
|
|
||||||
|
mkdir -p "$R_BIN_DIR" "$R_LIB_DIR"
|
||||||
|
|
||||||
|
write_r_wrapper() {
|
||||||
|
local target_name="$1"
|
||||||
|
local command_body="$2"
|
||||||
|
|
||||||
|
cat > "$R_BIN_DIR/$target_name" <<EOF
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
export R_LIBS_USER="$R_LIB_DIR"
|
||||||
|
$command_body "\$@"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
chmod +x "$R_BIN_DIR/$target_name"
|
||||||
|
}
|
||||||
|
|
||||||
echo -e "${BLUE} LOG:${YELLOW} Detecting R installation strategy for $OS...${NC}"
|
echo -e "${BLUE} LOG:${YELLOW} Detecting R installation strategy for $OS...${NC}"
|
||||||
|
|
||||||
if is_arch_family; then
|
if is_arch_family; then
|
||||||
@@ -30,6 +51,8 @@ if is_arch_family; then
|
|||||||
echo -e "${GREEN} SUCCESS:${NC} R installed via Pacman."
|
echo -e "${GREEN} SUCCESS:${NC} R installed via Pacman."
|
||||||
|
|
||||||
R_BIN="R"
|
R_BIN="R"
|
||||||
|
write_r_wrapper "R" 'exec "$(command -v R)"'
|
||||||
|
write_r_wrapper "Rscript" 'exec "$(command -v Rscript)"'
|
||||||
|
|
||||||
elif is_debian_family; then
|
elif is_debian_family; then
|
||||||
|
|
||||||
@@ -77,6 +100,8 @@ elif is_debian_family; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
R_BIN="rig run"
|
R_BIN="rig run"
|
||||||
|
write_r_wrapper "R" 'exec rig run'
|
||||||
|
write_r_wrapper "Rscript" 'exec rig run Rscript'
|
||||||
|
|
||||||
elif is_fedora_family; then
|
elif is_fedora_family; then
|
||||||
|
|
||||||
@@ -90,14 +115,18 @@ elif is_fedora_family; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
R_BIN="R"
|
R_BIN="R"
|
||||||
|
write_r_wrapper "R" 'exec "$(command -v R)"'
|
||||||
|
write_r_wrapper "Rscript" 'exec "$(command -v Rscript)"'
|
||||||
|
|
||||||
else
|
else
|
||||||
echo -e "${RED} ERROR:${NC} Unsupported OS: $OS"
|
echo -e "${RED} ERROR:${NC} Unsupported OS: $OS"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
export R_LIBS_USER="$R_LIB_DIR"
|
||||||
|
|
||||||
echo -e "${BLUE} LOG:${YELLOW} Installing 'renv' package in the user R library...${NC}"
|
echo -e "${BLUE} LOG:${YELLOW} Installing 'renv' package in the user R library...${NC}"
|
||||||
|
|
||||||
$R_BIN -e 'user_lib <- path.expand(Sys.getenv("R_LIBS_USER", unset = "~/R/library")); dir.create(user_lib, recursive = TRUE, showWarnings = FALSE); .libPaths(c(user_lib, .libPaths())); if (!require("renv", quietly=TRUE)) install.packages("renv", lib = user_lib, repos = "https://cloud.r-project.org")'
|
$R_BIN -e 'user_lib <- path.expand(Sys.getenv("R_LIBS_USER", unset = "~/.programming/r/library")); dir.create(user_lib, recursive = TRUE, showWarnings = FALSE); .libPaths(c(user_lib, .libPaths())); if (!require("renv", quietly=TRUE)) install.packages("renv", lib = user_lib, repos = "https://cloud.r-project.org")'
|
||||||
|
|
||||||
echo -e "${GREEN} SUCCESS:${NC} R setup completed."
|
echo -e "${GREEN} SUCCESS:${NC} R setup completed."
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Path: scripts/rust.sh
|
# Path: Scripts/rust.sh
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
@@ -38,4 +38,4 @@ if command -v cargo &> /dev/null; then
|
|||||||
else
|
else
|
||||||
echo -e "${RED} ERROR: Cargo not found in PATH. Check CARGO_HOME.${NC}"
|
echo -e "${RED} ERROR: Cargo not found in PATH. Check CARGO_HOME.${NC}"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
68
Scripts/setup.sh
Normal file
68
Scripts/setup.sh
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
REPO_ROOT="$(dirname "$SCRIPT_DIR")"
|
||||||
|
REBOOT_MARKER="$REPO_ROOT/.setup-reboot-required"
|
||||||
|
REPO_SECRET_FILE="$REPO_ROOT/Zsh/.zsh_secrets"
|
||||||
|
HOME_SECRET_FILE="$HOME/.zsh_secrets"
|
||||||
|
|
||||||
|
handle_reboot_marker() {
|
||||||
|
if [ -f "$REBOOT_MARKER" ]; then
|
||||||
|
rm -f "$REBOOT_MARKER"
|
||||||
|
echo "Package layering finished. Reboot, then rerun the same command."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
sync_repo_managed_secret_file() {
|
||||||
|
mkdir -p "$(dirname "$REPO_SECRET_FILE")"
|
||||||
|
|
||||||
|
if [ -L "$HOME_SECRET_FILE" ]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f "$HOME_SECRET_FILE" ]; then
|
||||||
|
if [ ! -f "$REPO_SECRET_FILE" ] || [ ! -s "$REPO_SECRET_FILE" ]; then
|
||||||
|
mv "$HOME_SECRET_FILE" "$REPO_SECRET_FILE"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if cmp -s "$HOME_SECRET_FILE" "$REPO_SECRET_FILE"; then
|
||||||
|
rm -f "$HOME_SECRET_FILE"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Conflict: both $HOME_SECRET_FILE and $REPO_SECRET_FILE exist with different contents."
|
||||||
|
echo "Please merge them manually, then rerun the command."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
touch "$REPO_SECRET_FILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
rm -f "$REBOOT_MARKER"
|
||||||
|
|
||||||
|
bash "$SCRIPT_DIR/base.sh"
|
||||||
|
handle_reboot_marker
|
||||||
|
|
||||||
|
bash "$SCRIPT_DIR/node.sh"
|
||||||
|
bash "$SCRIPT_DIR/go.sh"
|
||||||
|
bash "$SCRIPT_DIR/rust.sh"
|
||||||
|
bash "$SCRIPT_DIR/python.sh"
|
||||||
|
handle_reboot_marker
|
||||||
|
|
||||||
|
bash "$SCRIPT_DIR/r.sh"
|
||||||
|
handle_reboot_marker
|
||||||
|
|
||||||
|
sync_repo_managed_secret_file
|
||||||
|
|
||||||
|
stow --dir="$REPO_ROOT" -D Zsh --target="$HOME" 2>/dev/null || true
|
||||||
|
stow --dir="$REPO_ROOT" Zsh --target="$HOME"
|
||||||
|
|
||||||
|
echo "Full setup completed."
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
@@ -91,4 +91,4 @@ proxy_on() {
|
|||||||
proxy_off() {
|
proxy_off() {
|
||||||
unset ALL_PROXY HTTP_PROXY HTTPS_PROXY
|
unset ALL_PROXY HTTP_PROXY HTTPS_PROXY
|
||||||
echo "Proxy OFF (direct)"
|
echo "Proxy OFF (direct)"
|
||||||
}
|
}
|
||||||
@@ -4,6 +4,8 @@
|
|||||||
[ -f "$HOME/.zsh_secrets" ] && source "$HOME/.zsh_secrets"
|
[ -f "$HOME/.zsh_secrets" ] && source "$HOME/.zsh_secrets"
|
||||||
|
|
||||||
export GOGC=500
|
export GOGC=500
|
||||||
|
export R_ROOT="$HOME/.programming/r"
|
||||||
|
export R_LIBS_USER="$R_ROOT/library"
|
||||||
|
|
||||||
# CodeGraphContext defaults
|
# CodeGraphContext defaults
|
||||||
export CGC_RUNTIME_DB_TYPE=kuzudb
|
export CGC_RUNTIME_DB_TYPE=kuzudb
|
||||||
Reference in New Issue
Block a user