From c08c37956587be2840416dc97c0edc195f711015 Mon Sep 17 00:00:00 2001 From: Yann Autissier Date: Thu, 3 Sep 2026 18:49:22 +0200 Subject: [PATCH] look for the catalogue beside the installation too An install under a custom prefix (--prefix ~/.local) could not find the catalogue it had just cloned into /share/myos: only the three system paths were searched. --- install.sh | 106 ++++++++++++++++++++++++++++++++++++++++ lib/stack.sh | 7 ++- spec/unit/stack_spec.sh | 22 +++++++++ 3 files changed, 134 insertions(+), 1 deletion(-) create mode 100755 install.sh diff --git a/install.sh b/install.sh new file mode 100755 index 0000000..22d449e --- /dev/null +++ b/install.sh @@ -0,0 +1,106 @@ +#!/bin/sh +# myos installer. +# +# curl -fsSL https://raw.githubusercontent.com/aya/myos/lightning/install.sh | sh +# ... | sh -s -- --prefix ~/.local --with-stacks +# +# Installs the framework into /lib/myos, links /bin/myos, and +# optionally clones the stack catalogue into /share/myos. +set -eu + +MYOS_REPOSITORY=${MYOS_REPOSITORY:-https://github.com/aya/myos} +STACKS_REPOSITORY=${STACKS_REPOSITORY:-https://github.com/aya/myos-stacks} +REF=${MYOS_REF:-lightning} +PREFIX= +WITH_STACKS=false +WRITE_CONF=false + +say() { printf '%s\n' "$*"; } +warn() { printf 'warning: %s\n' "$*" >&2; } +die() { printf 'error: %s\n' "$*" >&2; exit 1; } +have() { command -v "$1" >/dev/null 2>&1; } + +while [ $# -gt 0 ]; do + case $1 in + --prefix) PREFIX=$2; shift 2 ;; + --ref) REF=$2; shift 2 ;; + --repository) MYOS_REPOSITORY=$2; shift 2 ;; + --with-stacks) WITH_STACKS=true; shift ;; + --conf) WRITE_CONF=true; shift ;; + -h|--help) + sed -n '2,9p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;; + *) die "unknown option: $1" ;; + esac +done + +# Default prefix: system wide when we can write there, user local otherwise. +if [ -z "$PREFIX" ]; then + if [ "$(id -u)" = 0 ] || [ -w /usr/local/lib ]; then PREFIX=/usr/local; else PREFIX=$HOME/.local; fi +fi + +# --- requirements --------------------------------------------------------- +have git || die "git is required" +have docker || warn "docker not found: myos will not be able to run anything" +if have docker && docker compose version >/dev/null 2>&1; then : +elif have docker-compose; then : +else warn "no docker compose found: install the compose plugin, or docker-compose >= 2.24.4" +fi + +# --- install -------------------------------------------------------------- +LIB=$PREFIX/lib/myos +BIN=$PREFIX/bin + +if [ -d "$LIB/.git" ]; then + say "updating $LIB" + git -C "$LIB" fetch --quiet origin "$REF" + git -C "$LIB" checkout --quiet FETCH_HEAD +else + say "installing myos into $LIB" + mkdir -p "$(dirname "$LIB")" + git clone --quiet --branch "$REF" "$MYOS_REPOSITORY" "$LIB" +fi + +mkdir -p "$BIN" +ln -sf "$LIB/bin/myos" "$BIN/myos" +say "linked $BIN/myos" + +if [ "$WITH_STACKS" = true ]; then + SHARE=$PREFIX/share/myos + if [ -d "$SHARE/.git" ]; then + say "updating the stack catalogue in $SHARE" + git -C "$SHARE" pull --quiet --ff-only + else + say "installing the stack catalogue into $SHARE" + mkdir -p "$(dirname "$SHARE")" + git clone --quiet "$STACKS_REPOSITORY" "$SHARE" + fi +fi + +# --- machine configuration ------------------------------------------------ +# /etc/conf.d on Alpine and other OpenRC systems, /etc/default elsewhere. +if [ "$WRITE_CONF" = true ]; then + if [ -d /etc/conf.d ]; then CONF=/etc/conf.d/myos; else CONF=/etc/default/myos; fi + if [ "$(id -u)" != 0 ]; then CONF=$HOME/.config/myos/config; mkdir -p "$(dirname "$CONF")"; fi + if [ -f "$CONF" ]; then + say "keeping the existing $CONF" + else + cat > "$CONF" </dev/null || echo example.org) +# WORKDIR=/srv/myos +# a deployment created before myos 2.0 must keep the old project names: +# MYOS_PROJECT_FORMAT=user-app-env +CONFEOF + say "wrote $CONF" + fi +fi + +case :$PATH: in + *:$BIN:*) ;; + *) warn "$BIN is not on your PATH" ;; +esac + +say "" +say "myos $("$BIN/myos" version 2>/dev/null | awk '{print $2}') installed" +say "next: myos doctor" diff --git a/lib/stack.sh b/lib/stack.sh index 071dfad..e7c6b95 100644 --- a/lib/stack.sh +++ b/lib/stack.sh @@ -15,7 +15,12 @@ myos_path() { _wd=${WORKDIR:-$PWD} _name=${STACK_DIR_NAME:-stack} _out= - for _d in "$_wd" "$_wd/.." "${HOME:-/nonexistent}/.local/share" /usr/local/share /usr/share; do + # /share comes from MYOS_ROOT, so an installation under any prefix + # finds the catalogue installed beside it + _prefix= + [ -n "${MYOS_ROOT:-}" ] && _prefix=$(dirname "$(dirname "$MYOS_ROOT")")/share + for _d in "$_wd" "$_wd/.." "${HOME:-/nonexistent}/.local/share" \ + ${_prefix:+"$_prefix"} /usr/local/share /usr/share; do for _c in "$_d/$_name" "$_d/myos/$_name"; do [ -d "$_c" ] || continue _c=$(cd "$_c" && pwd -P) diff --git a/spec/unit/stack_spec.sh b/spec/unit/stack_spec.sh index c0e76e5..deb8a27 100644 --- a/spec/unit/stack_spec.sh +++ b/spec/unit/stack_spec.sh @@ -168,3 +168,25 @@ Describe 'lib/stack.sh group safety' The lines of output should equal 2 End End + +Describe 'lib/stack.sh installation prefix' + setup() { + MYOS_TMP=$(mktemp -d "${TMPDIR:-/tmp}/myos-prefix.XXXXXX") + # myos resolves stack paths physically, so compare against the physical path + MYOS_TMP=$(cd "$MYOS_TMP" && pwd -P) + mkdir -p "$MYOS_TMP/lib/myos" "$MYOS_TMP/share/myos/stack/demo" + : > "$MYOS_TMP/share/myos/stack/demo/demo.yml" + MYOS_ROOT=$MYOS_TMP/lib/myos + WORKDIR=$MYOS_TMP + HOME=$MYOS_TMP/nohome + MYOS_PATH= + } + cleanup() { rm -rf "$MYOS_TMP"; } + BeforeEach setup + AfterEach cleanup + + It 'finds the catalogue installed beside the framework' + When call myos_stack_resolve demo + The output should equal "$MYOS_TMP/share/myos/stack/demo" + End +End