Add sibling command for installing and updating sibling projects
`sibling` asks for a git URL, clones the repo into ~/.local/share/siblings/<name>, runs its install.sh and confirms the install. `sibling list` and `sibling remove` manage installed siblings. updates.d/71-siblings.sh pulls every sibling during `update` and runs its update.sh, reporting failures in the update summary. Document the sibling contract in skills/sibling-project-format.md and update the custom-hook guide to match. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -2,10 +2,41 @@
|
||||
|
||||
## Overview
|
||||
|
||||
CoreDesktop's `update` script sources every `*.sh` file found in
|
||||
`~/.local/share/coredesktop/updates.d/` in filename order. A sibling project
|
||||
hooks into this system by installing a numbered shell script into that directory
|
||||
during its own install step.
|
||||
There are two ways for a sibling project to plug into CoreDesktop:
|
||||
|
||||
1. **The `sibling` command (preferred).** The user runs `sibling` and gives it
|
||||
the project's git URL. The repo is cloned into
|
||||
`~/.local/share/siblings/<name>` and its `install.sh` (if any) is run once.
|
||||
On every `update`, `updates.d/71-siblings.sh` pulls each sibling and runs its
|
||||
`update.sh` (if any). The sibling only needs those two optional scripts.
|
||||
2. **A custom hook.** CoreDesktop's `update` script sources every `*.sh` file
|
||||
found in `~/.local/share/coredesktop/updates.d/` in filename order. A sibling
|
||||
project can install its own numbered shell script into that directory during
|
||||
its own install step, for full control over how and when it updates.
|
||||
|
||||
## Using the `sibling` Command
|
||||
|
||||
See `sibling-project-format.md` for the full rules, templates and testing.
|
||||
In short, give the repo these optional files at its top level:
|
||||
|
||||
| File | When it runs |
|
||||
|--------------|---------------------------------------------------|
|
||||
| `install.sh` | Once, from the repo folder, when the user runs `sibling add` (and again if they re-run it) |
|
||||
| `update.sh` | On every `update`, from the repo folder, after the repo has been pulled |
|
||||
|
||||
Both run with `bash`, and a non-zero exit is reported as a failure.
|
||||
`update.sh` should be idempotent. If you have no `update.sh`, `update` just pulls the repo.
|
||||
|
||||
Commands:
|
||||
|
||||
```bash
|
||||
sibling # asks for the git URL
|
||||
sibling add <url> # same, without the prompt
|
||||
sibling list # installed siblings, their URL and current commit
|
||||
sibling remove <name> # deletes ~/.local/share/siblings/<name>
|
||||
```
|
||||
|
||||
The rest of this document covers the custom-hook approach.
|
||||
|
||||
## How It Works
|
||||
|
||||
@@ -41,20 +72,21 @@ Existing coredesktop hooks use a numeric prefix to control execution order:
|
||||
| `60-pipx.sh` | pipx packages |
|
||||
| `65-migrate.sh` | Migrate backup tool |
|
||||
| `70-claude.sh` | Claude Code setup |
|
||||
| `71-siblings.sh` | Projects installed with `sibling` |
|
||||
| `80-gnome-extensions.sh` | GNOME extensions |
|
||||
| `85-gnome-settings.sh` | GNOME extension settings |
|
||||
| `90-firmware.sh` | Firmware update check |
|
||||
| `95-cleanup.sh` | Flatpak/pacman cache cleanup |
|
||||
| `99-reboot-check.sh` | Reboot-needed notice |
|
||||
|
||||
Sibling projects should use an unused number from **71–79** so they run after
|
||||
Sibling projects should use an unused number from **72–79** so they run after
|
||||
the core updates but before coredesktop's end-of-run hooks (80+).
|
||||
|
||||
## What to Add to a Sibling Project
|
||||
|
||||
### 1. Create the hook script
|
||||
|
||||
Add a file like `updates.d/70-myproject.sh` to the sibling repo:
|
||||
Add a file like `updates.d/72-myproject.sh` to the sibling repo:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
@@ -73,12 +105,32 @@ In the sibling's `install.sh`, copy the hook into coredesktop's `updates.d/`:
|
||||
|
||||
```bash
|
||||
echo "Registering MyProject update hook..."
|
||||
cp updates.d/70-myproject.sh ~/.local/share/coredesktop/updates.d/
|
||||
cp updates.d/72-myproject.sh ~/.local/share/coredesktop/updates.d/
|
||||
```
|
||||
|
||||
This is a one-time step that wires the sibling into every future `update`
|
||||
run on the machine.
|
||||
|
||||
### Optional: only update when installed
|
||||
|
||||
Instead of running code at the top level, a hook can define `run_update` and,
|
||||
optionally, `is_installed`. `update` calls `run_update` only when `is_installed`
|
||||
is missing or returns true, so the hook is skipped on machines where the project
|
||||
isn't installed. Return non-zero from `run_update` to report a failure:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
is_installed() {
|
||||
[ -d "$HOME/.local/share/myproject" ]
|
||||
}
|
||||
|
||||
run_update() {
|
||||
echo "Updating MyProject..."
|
||||
git -C "$HOME/.local/share/myproject" pull --ff-only
|
||||
}
|
||||
```
|
||||
|
||||
## Available Helpers
|
||||
|
||||
Hooks don't inherit functions from earlier hooks, so source `utils.sh` for its
|
||||
@@ -100,5 +152,5 @@ remove_packages "${MY_REMOVE_PACKAGES[@]}"
|
||||
- [ ] Create `updates.d/7X-<project>.sh` in the sibling repo
|
||||
- [ ] Hook script echoes its name so progress is visible during `update`
|
||||
- [ ] Install step copies the hook to `~/.local/share/coredesktop/updates.d/`
|
||||
- [ ] Numeric prefix is an unused number in 71–79
|
||||
- [ ] Numeric prefix is an unused number in 72–79
|
||||
- [ ] Script is idempotent — safe to run multiple times without side effects
|
||||
|
||||
Reference in New Issue
Block a user