Ctrl K
ComunidadGuías…

bootstrap.sh

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
#!/bin/bash
# bootstrap.sh — the one-line installer's entry point, and the only Sjel script that runs
# before there is a checkout. Decided in #2; everything it does is deliberately small.
#
#   curl -fsSL https://raw.githubusercontent.com/larsboes/Sjel/<tag>/bootstrap.sh | bash
#
# Fetch it BY TAG, never from main: a pipe-to-bash of a moving branch executes whatever that
# branch says today, and the whole point of a release line is that an install is reproducible.
#
# What it does, and nothing else: check the host has git, resolve the newest release tag,
# clone at it in the profile you pick, and hand off to tools/install.sh. Every real decision
# — which overlay, which capabilities, which harness — stays in the repository, where it is
# reviewable and tested. This file is the part that cannot be, so it stays trivial.
#
#   SJEL_REF=v1.2.3      clone that tag instead of the newest release
#   SJEL_DIR=~/src/Sjel  clone here instead of ./Sjel
#   SJEL_PROFILE=usage   answer the profile question up front (usage | development)
#
# bash 3.2-safe.
#
# Every line below is a definition. The single call is the last line of the file, so a
# download truncated mid-transfer defines some functions and then reaches EOF without ever
# running one — the failure mode that makes piping a URL into a shell worth doing carefully.
set -euo pipefail

SJEL_REPO="${SJEL_REPO:-larsboes/Sjel}"
# Split from SJEL_REPO so the clone URL has one home. Overridable so bootstrap.test.sh can
# point both profiles at a scratch remote and exercise the real cloning rather than a mock.
SJEL_REMOTE="${SJEL_REMOTE:-https://github.com/$SJEL_REPO.git}"

say()  { printf '%s\n' "$*"; }
die()  { printf 'bootstrap: %s\n' "$*" >&2; exit 1; }

require_git() {
  command -v git >/dev/null 2>&1 || die "git is required and was not found.
  Sjel resolves its own version from the checkout (git describe) and updates by fast-forward,
  so git is a hard requirement rather than a convenience — see #2."
}

# The newest release tag, asked of the API rather than embedded here. Embedding it would make
# this file a second home for the version and something to remember at every release.
resolve_ref() {
  if [ -n "${SJEL_REF:-}" ]; then printf '%s' "$SJEL_REF"; return 0; fi
  command -v curl >/dev/null 2>&1 || die "curl is required to resolve the newest release (or set SJEL_REF)."
  curl -fsSL "https://api.github.com/repos/$SJEL_REPO/releases/latest" 2>/dev/null \
    | sed -n 's/.*"tag_name"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' \
    | head -1
}

# usage = a pinned tag you run; development = the full history you change. The difference is
# only the clone; both land in the same tools/install.sh.
ask_profile() {
  if [ -n "${SJEL_PROFILE:-}" ]; then printf '%s' "$SJEL_PROFILE"; return 0; fi
  # Piped into bash, stdin is the script itself — so the prompt reads the terminal directly.
  # Without a terminal there is nothing to ask, and usage is the safe default to assume.
  if [ ! -r /dev/tty ]; then printf 'usage'; return 0; fi
  say "" >&2
  say "  usage        pinned to the release, shallow clone — run Sjel" >&2
  say "  development  full history — change Sjel" >&2
  say "" >&2
  printf '  Which? [usage/development]: ' >&2
  local answer=""
  read -r answer < /dev/tty || answer=""
  case "$answer" in
    d|dev|development) printf 'development' ;;
    *)                 printf 'usage' ;;
  esac
}

clone_sjel() { # clone_sjel <profile> <ref> <dir>
  local profile="$1" ref="$2" dir="$3"
  [ -e "$dir" ] && die "$dir already exists — remove it or set SJEL_DIR to somewhere else."
  if [ "$profile" = "development" ]; then
    say "Cloning $SJEL_REPO (development: full history) into $dir"
    git clone --quiet "$SJEL_REMOTE" "$dir"
    git -C "$dir" checkout --quiet "$ref"
  else
    say "Cloning $SJEL_REPO at $ref (usage: shallow) into $dir"
    git clone --quiet --depth 1 --branch "$ref" "$SJEL_REMOTE" "$dir"
  fi
}

main() {
  require_git

  local ref profile dir
  ref="$(resolve_ref)"
  [ -n "$ref" ] || die "could not resolve the newest release of $SJEL_REPO — set SJEL_REF to a tag."
  dir="${SJEL_DIR:-$PWD/Sjel}"
  profile="$(ask_profile)"
  case "$profile" in
    usage|development) ;;
    *) die "unknown profile '$profile' — use usage or development." ;;
  esac

  clone_sjel "$profile" "$ref" "$dir"

  say ""
  say "Cloned $(git -C "$dir" describe --tags 2>/dev/null || printf '%s' "$ref") into $dir"
  say "Handing off to tools/install.sh — every decision from here lives in the repository."
  say ""
  exec "$dir/tools/install.sh"
}

main "$@"