Establish project foundation: domain model, MVI spec, environment reference
Capture the design work for the NixOS migration before any implementation: - .claude/CONTEXT.md: domain glossary (Host, Module, Skeleton, Auto-loader, Enable convention, unstable/stable overlay) - .claude/adr/0001-sops-nix-for-secrets.md: secrets tooling decision - .claude/spec/laptop-mvi.md: frozen minimum-viable-install spec for neogaia - reference/: read-only snapshot of the current CachyOS configs (secrets and state excluded), plus ENVIRONMENT.md profiling the live environment to guide replication
This commit is contained in:
130
reference/home/.config/fish/functions/dot.fish
Normal file
130
reference/home/.config/fish/functions/dot.fish
Normal file
@@ -0,0 +1,130 @@
|
||||
function dot --wraps=git --description 'Manage dotfiles via a bare repo checked out over $HOME'
|
||||
set -l dotfiles_dir $HOME/.dotfiles
|
||||
|
||||
if test "$argv[1]" = init
|
||||
set -e argv[1]
|
||||
__dot_init $dotfiles_dir $argv
|
||||
return $status
|
||||
end
|
||||
|
||||
if test "$argv[1]" = help
|
||||
__dot_help
|
||||
return $status
|
||||
end
|
||||
|
||||
set -l commands_dir $HOME/.config/dot/commands
|
||||
set -l command_file $commands_dir/$argv[1].fish
|
||||
set -l nested_command_file $commands_dir/$argv[1]/$argv[1].fish
|
||||
|
||||
if test -n "$argv[1]"
|
||||
if test -f "$command_file"
|
||||
source $command_file
|
||||
_dot_$argv[1] $argv[2..-1]
|
||||
return $status
|
||||
else if test -f "$nested_command_file"
|
||||
source $nested_command_file
|
||||
_dot_$argv[1] $argv[2..-1]
|
||||
return $status
|
||||
end
|
||||
end
|
||||
|
||||
git --git-dir=$dotfiles_dir --work-tree=$HOME $argv
|
||||
end
|
||||
|
||||
# Kept inline (not a separate autoloaded function file) because this is the
|
||||
# only subcommand that must work before the dotfiles repo has been cloned.
|
||||
function __dot_init
|
||||
set -l dotfiles_dir $argv[1]
|
||||
set -e argv[1]
|
||||
|
||||
argparse 'url=' -- $argv
|
||||
or return 1
|
||||
|
||||
set -l url $_flag_url
|
||||
test -n "$url"; or set url ssh://gitea@git.alexion.dev:2022/alexion/dotfiles.git
|
||||
|
||||
if test -e $dotfiles_dir
|
||||
echo "dot init: $dotfiles_dir already exists, refusing to re-initialize" >&2
|
||||
return 1
|
||||
end
|
||||
|
||||
git clone --bare $url $dotfiles_dir
|
||||
or begin
|
||||
echo "dot init: failed to clone $url" >&2
|
||||
return 1
|
||||
end
|
||||
|
||||
git --git-dir=$dotfiles_dir config status.showUntrackedFiles no
|
||||
|
||||
set -l checkout_output (git --git-dir=$dotfiles_dir --work-tree=$HOME checkout 2>&1)
|
||||
set -l checkout_status $status
|
||||
|
||||
if test $checkout_status -ne 0
|
||||
set -l conflicts
|
||||
set -l in_block 0
|
||||
|
||||
for line in $checkout_output
|
||||
if test $in_block -eq 1
|
||||
if string match -rq '^\s' -- $line
|
||||
set -a conflicts (string trim -- $line)
|
||||
continue
|
||||
else
|
||||
set in_block 0
|
||||
end
|
||||
end
|
||||
|
||||
string match -q '*would be overwritten by checkout:*' -- $line
|
||||
and set in_block 1
|
||||
end
|
||||
|
||||
if test (count $conflicts) -eq 0
|
||||
echo "dot init: checkout failed and no recoverable conflicts were found:" >&2
|
||||
printf '%s\n' $checkout_output >&2
|
||||
return 1
|
||||
end
|
||||
|
||||
set -l backup_dir $HOME/.dotfiles-backup/(date +%Y%m%dT%H%M%S)
|
||||
for f in $conflicts
|
||||
mkdir -p (path dirname $backup_dir/$f)
|
||||
mv $HOME/$f $backup_dir/$f
|
||||
echo "dot init: backed up ~/$f to $backup_dir/$f"
|
||||
end
|
||||
|
||||
git --git-dir=$dotfiles_dir --work-tree=$HOME checkout
|
||||
or begin
|
||||
echo "dot init: checkout still failing after backing up conflicts, aborting" >&2
|
||||
return 1
|
||||
end
|
||||
end
|
||||
|
||||
echo "dot init: bootstrapped $dotfiles_dir from $url"
|
||||
end
|
||||
|
||||
# The custom-subcommand glob is duplicated (not shared with
|
||||
# completions/dot.fish) because fish only autoloads a function from a file
|
||||
# named after that function; a shared helper would go undefined if `dot help`
|
||||
# ran in a completion context before `dot` itself had ever been sourced.
|
||||
function __dot_help
|
||||
echo "dot: manage dotfiles via a bare repo checked out over \$HOME
|
||||
|
||||
Commands:
|
||||
init bootstrap the dotfiles repo on a new machine
|
||||
help show this message"
|
||||
|
||||
for f in $HOME/.config/dot/commands/*.fish
|
||||
test -e $f; or continue
|
||||
echo " "(path basename $f | path change-extension '')
|
||||
end
|
||||
|
||||
for d in $HOME/.config/dot/commands/*/
|
||||
test -d $d; or continue
|
||||
set -l name (path basename $d)
|
||||
test -f $d$name.fish; or continue
|
||||
echo " $name"
|
||||
end
|
||||
|
||||
echo "
|
||||
Run 'dot <command> help' for flags on a specific command.
|
||||
|
||||
Any other command is passed through to git (dot status, dot add, dot commit, dot push, ...)."
|
||||
end
|
||||
Reference in New Issue
Block a user