Files
fish-config/conf.d/auto-pull.fish
T
rootiest 859f14a6e9 feat(functions): tag CLASSIFICATION across functions/ and conf.d/
Audits every function's interaction with the C1-shadowed commands
(uses-shadow/bypasses-shadow) and general hazards (destructive,
network, blocking-prompt) per the CLASSIFICATION schema.

Delegated the initial mechanical sweep to agy, then reviewed every
file by hand: fixed a systemic double-blank-comment-line formatting
bug from the delegate pass, and corrected several judgment errors
found on review -- three false blocking-prompt tags where a fish
'read' was consuming piped input rather than waiting on a terminal
(open-url.fish, sbver.fish, play-media.fish, now untagged entirely),
a blocking-prompt tag on mkrep.fish despite its documented --yes
escape hatch, an untagged read in jobrunner.fish's own baseless
blocking-prompt claim (removed, along with a destructive tag on
cleanup of its own mktemp output -- the schema explicitly excludes
that), the same own-output-cleanup false positive on
_zellij_dump_log.fish's destructive tag, an interactive fzf-gated
confirmation on logs.fish and replay.fish's piped read misread the
same way as the first three, and a uses-shadow(mkdir) on mkcd.fish
that actually belongs to the _fish_mkdir_p helper it delegates to,
not to mkcd itself.
2026-09-21 21:26:44 -04:00

74 lines
3.2 KiB
Fish

# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
# ╭──────────────────────────────────────────────────────────╮
# │ Auto-Pull (C2 — Autoexec) │
# ╰──────────────────────────────────────────────────────────╯
#
# Background, fast-forward-only `git pull` for opted-in repositories. Fires
# when the working directory enters the fish-config repo (always covered as a
# baseline) or any repository registered via the `auto-pull` command. The
# actual sync is delegated to `_auto_pull_sync`, which only ever fast-forwards
# a clean repo — see that function for the full safety contract.
#
# Manage the registry with: auto-pull add / remove / list / status
# Registers an --on-variable PWD handler that backgrounds a git fetch. In a
# script that cd's, that is both wasted work and AGENTS.md Task #4's
# credential-prompt hazard fired from a background job.
status is-interactive; or return
# C2 guard: when auto-execution is disabled, do not register the handler.
__fish_config_op_enabled (status basename); or exit
# COMPONENT
# autoexec/sync
#
# CLASSIFICATION
# bypasses-shadow(cat)
#
# SYNOPSIS
# __auto_pull_on_pwd (event handler, --on-variable PWD)
#
# DESCRIPTION
# On every directory change, checks whether the new $PWD is inside a
# registered repository (or the fish-config baseline) and, if so, kicks a
# background fast-forward. A throttle global ensures it fires once per
# repository entry rather than on every sub-directory change.
function __auto_pull_on_pwd --on-variable PWD
set -q __fish_config_dir; or set -g __fish_config_dir $XDG_CONFIG_HOME/fish
set -q __fish_user_dots_path; or set -l __fish_user_dots_path "$XDG_CONFIG_HOME/.user-dots/fish"
set -l list "$__fish_user_dots_path/auto-pull.list"
# Candidate roots: the fish-config repo plus the user's registry.
set -l roots $__fish_config_dir
test -r "$list"; and set -a roots (command cat "$list" 2>/dev/null)
# Find the registered root containing $PWD (exact match or a sub-directory).
set -l hit
for r in $roots
test -n "$r"; or continue
if test "$PWD" = "$r"; or string match -q -- "$r/*" "$PWD"
set hit "$r"
break
end
end
# Outside every registered repo: clear the throttle so re-entry re-syncs.
if test -z "$hit"
set -e __auto_pull_last
return
end
# Already synced for this repo entry — skip until we leave and return.
test "$hit" = "$__auto_pull_last"; and return
set -g __auto_pull_last "$hit"
# Background fast-forward. A --no-config child sources just the worker so
# it stays fast and free of shell side-effects; real `git`, no shadows.
set -l worker "$__fish_config_dir/functions/_auto_pull_sync.fish"
test -r "$worker"; or return
fish --no-config -c 'source $argv[1]; _auto_pull_sync $argv[2]' -- "$worker" "$hit" &
disown 2>/dev/null
end