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
21 changes: 20 additions & 1 deletion crates/uffs-cli/src/commands/update/binaries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,15 @@ use super::model::BinaryInfo;

/// Logical stems of every UFFS binary the updater knows about — i.e. the
/// engine binaries this repo builds and publishes as release assets, so
/// each can be acquired + swapped. The platform `.exe` suffix is added by
/// each can be acquired + swapped.
///
/// **This is the single source of truth for the UFFS core binary set.**
/// Every flow honours it: detection, self-update completeness, and tooling
/// (the `just` deploy recipes query it via `uffs --update bins` rather than
/// keeping their own list). Do not hardcode this set anywhere else — add a
/// stem here and all flows pick it up.
///
/// The platform `.exe` suffix is added by
/// [`exe_file_name`].
///
/// `uffs-tui` is deliberately **excluded**: it ships from the separate
Expand Down Expand Up @@ -58,6 +66,17 @@ pub(crate) fn exe_file_name(stem: &str) -> String {
}
}

/// Print the canonical core binary stems, one per line (platform-aware:
/// `uffs-broker` only on Windows). The machine-readable accessor behind
/// `uffs --update bins`, so shell tooling (the `just` deploy recipes) reads
/// the set from here instead of keeping a hardcoded copy that can drift.
#[expect(clippy::print_stdout, reason = "machine-readable list for scripts")]
pub(crate) fn print_core_stems() {
for stem in KNOWN_BINARIES {
println!("{stem}");
}
}

/// Enumerate the UFFS binaries actually present in `dir`, probing each
/// one's version. Binaries that are not present are simply absent from
/// the result (honor-what-is-installed).
Expand Down
17 changes: 14 additions & 3 deletions crates/uffs-cli/src/commands/update/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,11 @@ pub(crate) fn run_update(args: &[String]) -> Result<()> {
if let Some(act) = action
&& !matches!(
act,
"check" | "snapshot" | "acquire" | "apply" | "doctor" | "repair" | "recover"
"check" | "snapshot" | "acquire" | "apply" | "doctor" | "repair" | "recover" | "bins"
)
{
bail!(
"unknown `--update` action `{act}` — expected: check | snapshot | acquire | apply | doctor | repair | recover"
"unknown `--update` action `{act}` — expected: check | snapshot | acquire | apply | doctor | repair | recover | bins"
);
}

Expand All @@ -79,6 +79,15 @@ pub(crate) fn run_update(args: &[String]) -> Result<()> {
// a few plain-language lines for someone who just wants the gist.
let verbose = args.iter().any(|arg| arg == "-v" || arg == "--verbose");

// `bins` prints the canonical core binary stems (the single source of
// truth in `binaries::KNOWN_BINARIES`) for tooling — e.g. the `just`
// deploy recipes read the set from here instead of hardcoding it.
// Pure + non-mutating: no detection needed.
if action == Some("bins") {
binaries::print_core_stems();
return Ok(());
}

// `recover` finishes (or rolls back) an interrupted update in the
// foreground — the on-demand twin of the startup best-effort self-heal.
if action == Some("recover") {
Expand Down Expand Up @@ -439,7 +448,9 @@ fn print_help() {
\x20 resume/roll back an interrupted update, sweep\n\
\x20 stale backups, restart stopped services.\n\
\x20 recover Finish or roll back an interrupted update now\n\
\x20 (foreground; the on-demand self-heal).\n\n\
\x20 (foreground; the on-demand self-heal).\n\
\x20 bins Print the core binary stems (one per line) —\n\
\x20 the canonical set, for scripts/tooling.\n\n\
OPTIONS:\n\
\x20 -v, --verbose Show the full breakdown — per-binary versions,\n\
\x20 PIDs, launch commands, every doctor check.\n\
Expand Down
14 changes: 10 additions & 4 deletions just/build.just
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,16 @@ copy-binary profile:
if [[ "$OSTYPE" == "msys"* ]] || [[ "$OSTYPE" == "cygwin"* ]] || [[ -n "$WINDIR" ]]; then EXT=".exe"; printf "\033[0;34m → Windows detected\033[0m\n"; else EXT=""; printf "\033[0;34m → Unix-like system detected\033[0m\n"; fi
SOURCE_DIR="target/{{ profile }}"
mkdir -p ~/bin
# uffs-update is the self-update helper (`uffs update` spawns it as a
# sibling). uffs-broker is the elevated handle service — Windows only.
BINS=(uffs uffsd uffsmcp uffs-mft uffs-update)
if [[ -n "$EXT" ]]; then BINS+=(uffs-broker); fi
# The core binary set is owned by `uffs --update bins` (single source of
# truth in uffs-cli) — query the just-built binary instead of hardcoding,
# so this list never drifts. The printer is platform-aware: it emits
# uffs-broker only on Windows (the self-update helper + elevated handle
# service are included automatically).
UFFS_BIN="$SOURCE_DIR/uffs${EXT}"
if [[ ! -x "$UFFS_BIN" ]]; then
printf "\033[0;31m❌ %s not built — run a build first\033[0m\n" "$UFFS_BIN"; exit 1
fi
mapfile -t BINS < <("$UFFS_BIN" --update bins)
for BIN in "${BINS[@]}"; do
SOURCE_PATH="$SOURCE_DIR/${BIN}${EXT}"
DEST_PATH="$HOME/bin/${BIN}${EXT}"
Expand Down
Loading