sibling · sibling add · sibling list · sibling remove

Build your own layer on top.

A sibling project is a git repository that builds on CoreDesktop. Install one with a single command, and every update keeps it current along with everything else.

~ $ sibling add https://gitea.example.com/someone/my-tools.git Running
  1. Clone my-tools into ~/.local/share/siblings/my-tools
  2. install Running install.sh from the repo folder
  3. pacman Installing jq and ripgrep
  4. Bin Installed ~/.local/bin/my-tools
  5. Done my-tools installed. update keeps it current.

What's a sibling?

Your tools, updated with CoreDesktop.

CoreDesktop covers what most people need. A sibling covers the rest: your team’s tools, your dotfiles, the extra apps your work depends on. It’s an ordinary git repository with two optional scripts at its top level, install.sh and update.sh.

sibling clones the repository into ~/.local/share/siblings/ and runs its install.sh once. After that, every update pulls the latest version of each sibling and runs its update.sh, so the people using your project get your changes without doing anything.

A repository needs no special files to be installable. Without the scripts, update just keeps the clone up to date.

Install one

One command to add a sibling.

It asks for the repository’s git URL, clones it, runs its install.sh (if it has one), and confirms the install.

Terminal
sibling

Any URL or path git clone accepts will do. Private repositories work too, as long as you can already clone them (SSH key, credential helper or password), and every later update needs the same access.

Commands

Everything sibling does.

CommandWhat it does
siblingAsks for a git URL, then installs that project
sibling add <url>The same, without the prompt. Run it again to repair an install
sibling listShows the installed siblings, their URLs and current commits
sibling remove <name>Deletes ~/.local/share/siblings/<name>. Anything its install.sh set up elsewhere stays

Directory

Sibling projects.

Projects that build on CoreDesktop. Copy a command into a terminal to install one.

  • Everything you need to turn CoreDesktop into a great ham radio computer: fldigi, flrig, WSJT-X, QLog, CHIRP, GridTracker, Pat for Winlink and more, plus VARA through Wine. hampackremove uninstalls it all.

    • ham radio
    • digital modes
    • logging
    sibling add https://gitea.young.computer/david/HamPack.git

Make your own

Turn a repository into a sibling.

Both scripts are optional, and both go at the top level of the repository. Other names or locations are ignored.

  1. Add install.sh

    001

    Runs once, when someone runs sibling add, and again if they re-run it. Use it for one-time setup: prompts, accounts, initial config.

  2. Add update.sh

    002

    Runs on every update, right after the repository has been pulled. Use it to apply what changed since the last update.

  3. Tell people how to install it

    003

    In your README, tell users to install with sibling add <url>. Then submit it to the directory.

The rules

How to use the sibling function: two scripts.

Both run with bash, from the repository folder, so they don’t need to be executable. A #!/bin/bash line keeps them runnable by hand.

install.sh

  • Exit non-zero on failure. set -e near the top is the simplest way. sibling then tells the user it failed and how to retry.
  • Make it safe to re-run. Re-running sibling add is how users repair an install, so skip work that’s already done instead of failing on it.
  • It may prompt the user, since it runs in their terminal.
  • Install commands into ~/.local/bin (already on PATH) with install_script.

update.sh

  • Make it idempotent. It runs on every update, usually with nothing to do.
  • Don’t prompt. Users expect update to run through without questions, apart from sudo passwords.
  • Exit non-zero only for real failures, so that update’s error summary stays meaningful.
  • Print what it’s doing. CoreDesktop prints only the project’s name before it runs.
  • It’s fine to leave it out if pulling the repository is enough, for example when ~/.local/bin holds symlinks into the repo.

Good to know

The environment your scripts run in.

  • Nothing is inheritedEach script runs as its own bash process, with no variables or functions from CoreDesktop. $COREDESKTOP is not set, so set it yourself: COREDESKTOP="$HOME/.local/share/coredesktop".
  • Find your own filesLocate files relative to the script, not a hard-coded path. People may clone the repository somewhere else and run install.sh by hand.
  • Keep pulls workingupdate pulls with --ff-only and never merges or resets. Never force-push the default branch, and never write into tracked files: put generated files and per-machine state in ~/.config/<name>/ or in paths listed in .gitignore.
  • sudo works as normalsudo prompts for a password as usual. CoreDesktop doesn’t give siblings passwordless sudo.

Helpers

CoreDesktop’s helpers, from utils.sh.

Source $COREDESKTOP/utils.sh to use them.

FunctionWhat it does
install_packages ...Installs pacman and AUR packages with yay, skipping installed ones
remove_packages ...Removes installed pacman and AUR packages
remove_flatpaks ...Uninstalls Flatpaks that are installed
enable_services ...Enables systemd services not yet enabled
install_script src dstCopies a file atomically and makes it executable
is_installed pkgTrue if a pacman package is installed

Templates

Start from these.

Share the install logic between the two scripts, so packages or commands you add later reach existing machines through update, not just new installs.

install.sh

#!/bin/bash
#
# Purpose : Install <project> (run by CoreDesktop's `sibling add`)

set -e

SELF="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
COREDESKTOP="$HOME/.local/share/coredesktop"
source "$COREDESKTOP/utils.sh"

# One-time setup: prompts, accounts, initial config...
mkdir -p "$HOME/.config/<project>"

# Everything that update.sh also needs to keep current
bash "$SELF/update.sh"

echo "<project> installed."

update.sh

#!/bin/bash
#
# Purpose : Keep <project> current (run by CoreDesktop's `update`)

set -e

SELF="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
COREDESKTOP="$HOME/.local/share/coredesktop"
source "$COREDESKTOP/utils.sh"

PACKAGES=(
  jq
  ripgrep
)
install_packages "${PACKAGES[@]}"

mkdir -p "$HOME/.local/bin"
install_script "$SELF/bin/<project>" "$HOME/.local/bin/<project>"

Testing

Try it in a throwaway home folder.

Point sibling at a local clone, with a temporary HOME so nothing touches your real one:

export HOME="$(mktemp -d)"
mkdir -p "$HOME/.local/share"
ln -s /path/to/real/coredesktop "$HOME/.local/share/coredesktop"

# Install
bash "$HOME/.local/share/coredesktop/sibling" add /path/to/sibling-repo

# Commit a change in /path/to/sibling-repo, then run the update hook the way update does
( source "$HOME/.local/share/coredesktop/updates.d/71-siblings.sh"; is_installed && run_update )

# Re-run the install to check it's safe to repeat
bash "$HOME/.local/share/coredesktop/sibling" add /path/to/sibling-repo

Scripts that call sudo, yay or systemctl still change the real system, even with a temporary HOME. Test those on a machine or VM you don’t mind changing.

Advanced

Full control with an update hook.

Instead of update.sh, a project can install its own hook into CoreDesktop’s updates.d/, which update runs in filename order. Use one approach or the other, not both, or the project updates twice.

Name the hook with an unused number from 72 to 79, so it runs after CoreDesktop’s own updates but before its end-of-run steps (80 and up), and copy it in from your install.sh:

cp updates.d/72-myproject.sh ~/.local/share/coredesktop/updates.d/

A hook can define run_update, and optionally is_installed, so it’s skipped on machines where the project isn’t installed. The full guide is in sibling-project-updates.md.

Checklist

Before you share it.

  • The repository can be cloned by URL by the people who will install it.
  • install.sh (optional) is at the top level, exits non-zero on failure, and is safe to re-run.
  • update.sh (optional) is at the top level, idempotent, doesn’t prompt, and prints what it’s doing.
  • Scripts find their own files relative to the script and set COREDESKTOP="$HOME/.local/share/coredesktop" themselves.
  • Nothing writes to tracked files in the clone, and the default branch is never force-pushed.
  • The project doesn’t also copy a hook into CoreDesktop’s updates.d/.
  • The README tells users to install with sibling add <url>.

Submit

Get your project in the directory.

Built a sibling other people could use? Tell us about it, and we’ll add it to the directory.

  1. Check it

    001

    Go through the checklist. The repository must be public, so anyone can install it with sibling add, and should have a license.

  2. Open an issue

    002

    Open an issue on the CoreDesktop repository titled Sibling: your project’s name, with its git URL, a one-line description, and your name or handle.

  3. We'll take a look

    003

    We’ll install it on a test machine, and once it works, add it to the directory. We’ll reply on the issue either way.