Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .github/workflows/workstation-scripts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,22 @@ jobs:
bash -n "$f"
done <<<"$files"

- name: Smoke: patch-shell idempotent
run: |
set -euo pipefail
p='profiles/linux-dev/workstation-v0/bin/patch-shell.sh'
bash -n "$p"

tmp=$(mktemp)
printf '# rc\n' > "$tmp"

SOURCEOS_RC_FILES="$tmp" bash "$p" apply
SOURCEOS_RC_FILES="$tmp" bash "$p" apply

test "$(grep -cF '# >>> sourceos workstation-v0 >>>' "$tmp")" -eq 1
test "$(grep -cF '# <<< sourceos workstation-v0 <<<' "$tmp")" -eq 1
grep -F 'export PATH="$HOME/.local/bin:$PATH"' "$tmp" >/dev/null

- name: Smoke: sourceos help exits cleanly
run: |
set -euo pipefail
Expand Down
35 changes: 32 additions & 3 deletions docs/workstation/RUNBOOK.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,7 @@ Quick checks:
uname -a && echo "XDG_CURRENT_DESKTOP=${XDG_CURRENT_DESKTOP:-}" && command -v rpm-ostree || true && command -v dnf || true
```

If Homebrew/Linuxbrew is not installed, install it first (inspect scripts before running):
- https://brew.sh
- https://docs.brew.sh/Homebrew-on-Linux
If Homebrew/Linuxbrew is not installed, install it first.

---

Expand All @@ -45,10 +43,41 @@ Notes:
- SYSTEM baseline (git/ssh/podman/toolbox/wl-clipboard/jq/xclip)
- USER toolset via `brew` (manifest-driven)
- shell spine config to `$XDG_CONFIG_HOME/sourceos/shell/common.sh`
- fish spine config to `$XDG_CONFIG_HOME/sourceos/shell/common.fish`
- GNOME baseline + extensions
- open-source launcher (fuzzel preferred) + SourceOS palette hotkey
- `sourceos` helper wrapper into `~/.local/bin`

### Optional: autopatch shell rc

If you want the installer to also patch your shell rc files:
- bash/zsh: `~/.bashrc`, `~/.zshrc`
- fish: `$XDG_CONFIG_HOME/fish/config.fish` (if present)

It will:
- ensure `$HOME/.local/bin` is on PATH
- source the SourceOS shell spine

Run:

```bash
SOURCEOS_AUTOPATCH_SHELL=1 ./profiles/linux-dev/workstation-v0/install.sh
```

Or via the palette:

```bash
sourceos fix shell dry-run
sourceos fix shell apply
```

For fish:

```bash
./profiles/linux-dev/workstation-v0/bin/patch-fish.sh dry-run
./profiles/linux-dev/workstation-v0/bin/patch-fish.sh apply
```

---

## 2) Launcher palette (open-source)
Expand Down
78 changes: 78 additions & 0 deletions profiles/linux-dev/workstation-v0/bin/patch-fish.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#!/usr/bin/env bash
set -euo pipefail

# Patch fish config to source SourceOS fish spine.
# Idempotent marker block.

MODE="${1:-apply}" # apply|dry-run

info(){ printf "INFO: %s\n" "$*" >&2; }
warn(){ printf "WARN: %s\n" "$*" >&2; }
err(){ printf "ERROR: %s\n" "$*" >&2; }

marker_start="# >>> sourceos workstation-v0 (fish) >>>"
marker_end="# <<< sourceos workstation-v0 (fish) <<<"

fish_cfg(){
echo "${XDG_CONFIG_HOME:-$HOME/.config}/fish/config.fish"
}

has_block(){
local f=$1
grep -Fqx "$marker_start" "$f" 2>/dev/null
}

block(){
cat <<'EOF'
# >>> sourceos workstation-v0 (fish) >>>
# Added by SourceOS Workstation v0
set spine_path "${XDG_CONFIG_HOME:-$HOME/.config}/sourceos/shell/common.fish"
if test -f "$spine_path"
source "$spine_path"
end
# <<< sourceos workstation-v0 (fish) <<<
EOF
}

apply(){
local f
f="$(fish_cfg)"

if [[ ! -e "$f" ]]; then
warn "fish config not found (skipping): $f"
return 0
fi

if has_block "$f"; then
info "already patched: $f"
return 0
fi

if [[ "$MODE" == "dry-run" ]]; then
info "would patch: $f"
return 0
fi

{
printf '\n'
block
printf '\n'
} >> "$f"

info "patched: $f"
}

main(){
case "$MODE" in
apply|dry-run) ;;
*)
err "unknown mode: $MODE (use apply|dry-run)"
exit 2
;;
esac

apply
info "done"
}

main "$@"
99 changes: 99 additions & 0 deletions profiles/linux-dev/workstation-v0/bin/patch-shell.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#!/usr/bin/env bash
set -euo pipefail

# Patch shell rc files to:
# - ensure $HOME/.local/bin is on PATH
# - source the SourceOS shell spine (`$XDG_CONFIG_HOME/sourceos/shell/common.sh`)
#
# Idempotent: uses a marker block.
# CI/test hook: SOURCEOS_RC_FILES may be set to a colon-separated list of rc files.

MODE="${1:-apply}" # apply|dry-run

info(){ printf "INFO: %s\n" "$*" >&2; }
warn(){ printf "WARN: %s\n" "$*" >&2; }
err(){ printf "ERROR: %s\n" "$*" >&2; }

marker_start="# >>> sourceos workstation-v0 >>>"
marker_end="# <<< sourceos workstation-v0 <<<"

block() {
# NOTE: Dollar signs are escaped so we do not bake the *current* PATH into the rc file.
cat <<EOF
${marker_start}
# Added by SourceOS Workstation v0
export PATH="\$HOME/.local/bin:\$PATH"
spine_path="\${XDG_CONFIG_HOME:-\$HOME/.config}/sourceos/shell/common.sh"
if [ -f "\$spine_path" ]; then
. "\$spine_path"
fi
${marker_end}
EOF
}

rc_candidates() {
if [[ -n "${SOURCEOS_RC_FILES:-}" ]]; then
local IFS=':'
# shellcheck disable=SC2206
read -r -a arr <<<"${SOURCEOS_RC_FILES}"
for f in "${arr[@]}"; do
[[ -n "$f" ]] && printf '%s\n' "$f"
done
return 0
fi

printf '%s\n' "$HOME/.bashrc" "$HOME/.zshrc"
}

has_block() {
local f=$1
grep -Fqx "$marker_start" "$f" 2>/dev/null
}

apply_to_file() {
local f=$1

if [[ ! -e "$f" ]]; then
warn "rc file not found (skipping): $f"
return 0
fi

if has_block "$f"; then
info "already patched: $f"
return 0
fi

if [[ "$MODE" == "dry-run" ]]; then
info "would patch: $f"
return 0
fi

{
printf '\n'
block
printf '\n'
} >> "$f"

info "patched: $f"
}

main(){
case "$MODE" in
apply|dry-run) ;;
*)
err "unknown mode: $MODE (use apply|dry-run)"
exit 2
;;
esac

while IFS= read -r rc; do
apply_to_file "$rc"
done < <(rc_candidates)

info "done"
if [[ "$MODE" == "dry-run" ]]; then
info "re-run with: $0 apply"
fi
}

main "$@"
25 changes: 25 additions & 0 deletions profiles/linux-dev/workstation-v0/bin/sourceos
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ sourceos (workstation helper)

Usage:
sourceos palette
sourceos fix shell [apply|dry-run]
sourceos doctor [--open]
sourceos status [--json|--open|--write <path>]
sourceos profile apply
Expand Down Expand Up @@ -88,6 +89,13 @@ profile_path(){
echo "$PROFILE_DIR"
}

run_fix_shell(){
local mode=${1:-apply}
local s="$PROFILE_DIR/bin/patch-shell.sh"
[[ -x "$s" ]] || { err "patch-shell helper missing: $s"; exit 2; }
exec "$s" "$mode"
}

gnome_detect(){
[[ "${XDG_CURRENT_DESKTOP:-}" == *GNOME* ]] && return 0
[[ "${DESKTOP_SESSION:-}" == *gnome* ]] && return 0
Expand Down Expand Up @@ -253,6 +261,8 @@ status_write(){
palette_menu(){
# Print menu entries as: label<TAB>command
cat <<'EOF'
Palette: Fix shell rc (dry-run) sourceos fix shell dry-run
Palette: Fix shell rc (apply) sourceos fix shell apply
Status (open report) sourceos status --open
Doctor (open report) sourceos doctor --open
Apply profile sourceos profile apply
Expand Down Expand Up @@ -306,6 +316,21 @@ main(){
run_palette
;;

fix)
shift || true
case "${1:-}" in
shell)
shift || true
run_fix_shell "${1:-apply}"
;;
*)
err "unknown fix target: ${1:-}"
usage
exit 2
;;
esac
;;

doctor)
shift || true
case "${1:-}" in
Expand Down
31 changes: 30 additions & 1 deletion profiles/linux-dev/workstation-v0/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ warn(){ printf "WARN: %s\n" "$*" >&2; }

have(){ command -v "$1" >/dev/null 2>&1; }

autopatch_enabled(){
case "${SOURCEOS_AUTOPATCH_SHELL:-0}" in
1|true|TRUE|yes|YES) return 0 ;;
*) return 1 ;;
esac
}

install_system(){
if have rpm-ostree; then
info "rpm-ostree detected: installing minimal SYSTEM layer (may require reboot)"
Expand All @@ -27,7 +34,7 @@ install_system(){
}

install_brew(){
err "brew not found. Install brew first, then re-run."
err "brew not found. Install brew first, then re-run."
exit 2
}

Expand Down Expand Up @@ -65,6 +72,27 @@ install_sourceos_cli(){
fi
}

patch_shell_rc_if_enabled(){
if ! autopatch_enabled; then
return 0
fi

local sh_script="$PROFILE_DIR/bin/patch-shell.sh"
if [[ -x "$sh_script" ]]; then
info "Autopatch enabled: patching shell rc files"
"$sh_script" apply || warn "shell rc patch failed (non-fatal)"
else
warn "autopatch enabled but patch helper missing: $sh_script"
fi

# Optional: patch fish config if present.
local fish_script="$PROFILE_DIR/bin/patch-fish.sh"
if [[ -x "$fish_script" ]]; then
info "Autopatch enabled: patching fish config (if present)"
"$fish_script" apply || warn "fish config patch failed (non-fatal)"
fi
}

apply_gnome_baseline(){
local script="$PROFILE_DIR/gnome/apply.sh"
if [[ -x "$script" ]]; then
Expand Down Expand Up @@ -111,6 +139,7 @@ main(){
install_user
install_shell_spine
install_sourceos_cli
patch_shell_rc_if_enabled
apply_gnome_baseline
apply_gnome_extensions
apply_launcher_install
Expand Down
Loading