fix(mkrep): stop the test suite creating real repos, and confirm implicit ones #152

Merged
rootiest merged 1 commits from fix/mkrep-implicit-remote-confirm into main 2026-09-16 08:20:06 +00:00
4 changed files with 2444 additions and 2738 deletions
+2282 -2702
View File
File diff suppressed because it is too large Load Diff
+20 -3
View File
@@ -1275,7 +1275,7 @@ functions). They are active in all interactive sessions.
[-c | --clean | --no-clean] [--strict] [-v | --verbose]
[-s | --silent] [--template <path>] [--branch <name>]
[--remote <url>] [--new-remote [<cmd>]] [--server <type>]
[--check-existing] [--name <name>] [-h | --help] <dir>
[--check-existing] [-y | --yes] [--name <name>] [-h | --help] <dir>
Creates a directory, cds into it, and git-inits it -- mkcd plus a git
repo in one step. All three actions are on by default and each has a
@@ -1323,6 +1323,19 @@ functions). They are active in all interactive sessions.
requires a resolved server and is mutually exclusive with --remote
and --new-remote.
Creating a repository on a live forge is the only outward-facing thing
mkrep does, and on the $GIT_SERVER path an exported variable is all it
takes to reach it -- so a plain mkrep call, which reads as purely
local, would otherwise make a repo on a server without ever saying so.
That case therefore asks for confirmation first, defaulting to no.
Declining leaves the local repo in place with no remote and still
exits 0. Linking an existing repo is not affected, and neither is an
explicitly requested remote: --server, --remote and --new-remote all
say outright what they are going to do, so none of them prompts. Pass
--yes to skip the question. Where it cannot be asked -- a script, a
pipe, any non-interactive shell -- creation is skipped rather than
assumed, with a note on stderr naming the flags that would allow it.
Arguments:
<dir> Directory to create and enter
--cd, --no-cd Change into <dir> (default: --cd)
@@ -1344,12 +1357,15 @@ functions). They are active in all interactive sessions.
--server <type> Auto-create/link a remote on gitea, gitlab, or github
--check-existing Report whether the repo exists on the resolved
server; creates or links nothing
-y, --yes Create the remote without confirming, on the
$GIT_SERVER path that would otherwise ask
--name <name> {name} substitution for --new-remote/--server
(default: <dir>'s basename)
-h, --help Show this help message
Exit Status:
0 All requested steps completed
0 All requested steps completed, or a $GIT_SERVER remote-create was
declined at the prompt (the local repo is still set up)
1 Bad arguments, or a step (mkdir, cd, git init, remote) failed
Example:
@@ -1360,7 +1376,8 @@ functions). They are active in all interactive sessions.
mkrep --new-remote ~/projects/foo
set -gx GITEA_URL https://git.example.com
set -gx GIT_SERVER gitea
mkrep ~/projects/foo
mkrep ~/projects/foo # asks before creating the remote
mkrep --yes ~/projects/foo # creates it without asking
mkrep --server gitlab --check-existing ~/projects/foo
Starting points for $MKREP_REMOTE_CMD, one per host CLI -- each assumes
+71 -26
View File
@@ -13,7 +13,7 @@
# [-c | --clean | --no-clean] [--strict] [-v | --verbose]
# [-s | --silent] [--template <path>] [--branch <name>]
# [--remote <url>] [--new-remote [<cmd>]] [--server <type>]
# [--check-existing] [--name <name>] [-h | --help] <dir>
# [--check-existing] [-y | --yes] [--name <name>] [-h | --help] <dir>
#
# DESCRIPTION
# Creates a directory, cds into it, and git-inits it -- mkcd plus a git
@@ -62,6 +62,19 @@
# requires a resolved server and is mutually exclusive with --remote
# and --new-remote.
#
# Creating a repository on a live forge is the only outward-facing thing
# mkrep does, and on the $GIT_SERVER path an exported variable is all it
# takes to reach it -- so a plain mkrep call, which reads as purely
# local, would otherwise make a repo on a server without ever saying so.
# That case therefore asks for confirmation first, defaulting to no.
# Declining leaves the local repo in place with no remote and still
# exits 0. Linking an existing repo is not affected, and neither is an
# explicitly requested remote: --server, --remote and --new-remote all
# say outright what they are going to do, so none of them prompts. Pass
# --yes to skip the question. Where it cannot be asked -- a script, a
# pipe, any non-interactive shell -- creation is skipped rather than
# assumed, with a note on stderr naming the flags that would allow it.
#
# ARGUMENTS
# <dir> Directory to create and enter
# --cd, --no-cd Change into <dir> (default: --cd)
@@ -83,12 +96,15 @@
# --server <type> Auto-create/link a remote on gitea, gitlab, or github
# --check-existing Report whether the repo exists on the resolved
# server; creates or links nothing
# -y, --yes Create the remote without confirming, on the
# $GIT_SERVER path that would otherwise ask
# --name <name> {name} substitution for --new-remote/--server
# (default: <dir>'s basename)
# -h, --help Show this help message
#
# EXIT STATUS
# 0 All requested steps completed
# 0 All requested steps completed, or a $GIT_SERVER remote-create was
# declined at the prompt (the local repo is still set up)
# 1 Bad arguments, or a step (mkdir, cd, git init, remote) failed
#
# EXAMPLE
@@ -99,7 +115,8 @@
# mkrep --new-remote ~/projects/foo
# set -gx GITEA_URL https://git.example.com
# set -gx GIT_SERVER gitea
# mkrep ~/projects/foo
# mkrep ~/projects/foo # asks before creating the remote
# mkrep --yes ~/projects/foo # creates it without asking
# mkrep --server gitlab --check-existing ~/projects/foo
#
# Starting points for $MKREP_REMOTE_CMD, one per host CLI -- each assumes
@@ -119,7 +136,7 @@ function mkrep --description 'Create a directory, cd into it, and git init it'
__fish_palette
argparse h/help cd no-cd mkdir no-mkdir git no-git c/clean no-clean strict \
v/verbose s/silent template= branch= remote= new-remote=? server= \
v/verbose s/silent y/yes template= branch= remote= new-remote=? server= \
check-existing name= \
-- $argv
or return 1
@@ -144,6 +161,7 @@ function mkrep --description 'Create a directory, cd into it, and git init it'
echo " $c_flag--new-remote$c_reset $c_arg<cmd>$c_reset (optional) Create + link a remote"
echo " $c_flag--server$c_reset $c_arg<type>$c_reset Auto-create/link a remote (gitea, gitlab, github)"
echo " $c_flag--check-existing$c_reset Report whether the repo exists; creates nothing"
echo " $c_flag-y$c_reset, $c_flag--yes$c_reset Skip the \$GIT_SERVER remote-create confirmation"
echo " $c_flag--name$c_reset $c_arg<name>$c_reset {name} substitution for --new-remote/--server"
echo " $c_flag-h$c_reset, $c_flag--help$c_reset Show this help message"
echo
@@ -189,10 +207,15 @@ function mkrep --description 'Create a directory, cd into it, and git init it'
set -l srv_type ''
set -l srv_url ''
# Track HOW the server was resolved, not just that it was. --server is an
# explicit request to auto-create; an ambient $GIT_SERVER is not, and only
# the latter needs confirming before we create a repo on a live forge.
set -l srv_implicit 0
if set -q _flag_server
set srv_type $_flag_server
else if test -n "$GIT_SERVER"
set srv_type $GIT_SERVER
set srv_implicit 1
end
if test -n "$srv_type"
switch $srv_type
@@ -369,33 +392,55 @@ function mkrep --description 'Create a directory, cd into it, and git init it'
end
_mkrep_say $silent "$c_ok""✔$c_reset Linked remote $c_arg$url$c_reset"
else
set -l cmd $MKREP_REMOTE_CMD
test -z "$cmd"; and set cmd (_mkrep_default_remote_cmd $srv_type)
# Creating a repository on a live forge is the only outward-facing
# thing mkrep does, and an exported $GIT_SERVER alone is enough to
# reach here -- so a plain `mkrep foo`, which reads as purely
# local, would silently make a repo on someone's server. Confirm
# first. Skipped when the remote was asked for explicitly
# (--server/--new-remote never reach this check) or with --yes.
set -l do_create 1
if test $srv_implicit -eq 1; and not set -q _flag_yes
set do_create 0
if status is-interactive; and isatty stdin
read -l -P (set_color yellow)"?"(set_color normal)" Create new remote "(set_color --bold)"$USER/$name"(set_color normal)" on $srv_type? [y/N] " _reply
string match -qr '^[Yy]' -- "$_reply"; and set do_create 1
end
# Not gated on $silent: declining to do something the caller
# may be expecting is a diagnostic, and mkrep already writes
# its errors to stderr regardless of -s.
test $do_create -eq 0
and echo "$c_warn""→$c_reset Skipped creating $c_arg$USER/$name$c_reset on $srv_type — pass $c_flag--yes$c_reset or $c_flag--server $srv_type$c_reset to create it" >&2
end
if string match -q '*{server}*' -- $cmd
if test -z "$srv_url"
echo "$c_err""✘$c_reset No base URL resolved for $srv_type (set \$GITEA_URL/\$GITEA_HOST or \$GITLAB_URL/\$GITLAB_HOST)" >&2
if test $do_create -eq 1
set -l cmd $MKREP_REMOTE_CMD
test -z "$cmd"; and set cmd (_mkrep_default_remote_cmd $srv_type)
if string match -q '*{server}*' -- $cmd
if test -z "$srv_url"
echo "$c_err""✘$c_reset No base URL resolved for $srv_type (set \$GITEA_URL/\$GITEA_HOST or \$GITLAB_URL/\$GITLAB_HOST)" >&2
cd $orig_pwd
return 1
end
set cmd (string replace -a '{server}' $srv_url -- $cmd)
end
set cmd (string replace -a '{name}' $name -- $cmd)
set cmd (string replace -a '{user}' $USER -- $cmd)
_mkrep_verbose $silent $verbose "$c_dim""Running: $cmd$c_reset"
if test $silent -eq 1
eval $cmd >/dev/null 2>&1
else
eval $cmd
end
or begin
echo "$c_err""✘$c_reset Remote-create command failed" >&2
cd $orig_pwd
return 1
end
set cmd (string replace -a '{server}' $srv_url -- $cmd)
set -l url (_mkrep_remote_url $srv_type $USER $name $srv_url)
_mkrep_say $silent "$c_ok""✔$c_reset Created new remote $c_arg$url$c_reset on $srv_type"
end
set cmd (string replace -a '{name}' $name -- $cmd)
set cmd (string replace -a '{user}' $USER -- $cmd)
_mkrep_verbose $silent $verbose "$c_dim""Running: $cmd$c_reset"
if test $silent -eq 1
eval $cmd >/dev/null 2>&1
else
eval $cmd
end
or begin
echo "$c_err""✘$c_reset Remote-create command failed" >&2
cd $orig_pwd
return 1
end
set -l url (_mkrep_remote_url $srv_type $USER $name $srv_url)
_mkrep_say $silent "$c_ok""✔$c_reset Created new remote $c_arg$url$c_reset on $srv_type"
end
end
end
+71 -7
View File
@@ -6,15 +6,35 @@
# matrix (--clean/--strict interaction, --no-* precedence, remote linking
# and remote creation via a user command template).
#
# Runs isolated (no `# MODE:` marker). mkrep does real filesystem
# mutations and cds, so every case works inside its own mktemp -d sandbox
# and restores $PWD afterward -- this suite runs autoloaded straight in
# the driver's own process (like test-guards.fish), so a stray cd or a
# leftover sandbox would leak into later cases/suites.
# Runs isolated (no `# MODE:` marker), which run-tests.fish executes as its
# own `fish --no-config` process with a throwaway XDG_CONFIG_HOME. mkrep does
# real filesystem mutations and cds, so every case works inside its own
# mktemp -d sandbox and restores $PWD afterward -- a stray cd or a leftover
# sandbox would still leak into later cases in this same file.
source (realpath (dirname (status filename)))/lib.fish
set -p fish_function_path $repo_root/functions
# mkrep resolves a server from $GIT_SERVER plus
# $GITEA_URL/$GITEA_HOST/$GITLAB_URL/$GITLAB_HOST, and this repo doubles as a
# real ~/.config/fish where all of them are exported for day-to-day use. Left
# ambient, a bare `mkrep <dir>` with no remote flag takes the auto-create
# branch and contacts the live forge: that is how an empty `rootiest/repo` came
# to exist on git.rootiest.dev on 2026-09-14, and why these cases then passed
# standalone (the repo exists, so mkrep links instead of creating) while
# failing under run-tests.fish (throwaway XDG_CONFIG_HOME, so `tea` has no
# login). Neutralize all five for the whole suite.
#
# Empty reads the same as unset to mkrep, so this is a clean slate without
# erasing the caller's real globals, and every section that wants a server sets
# its own `set -lx GIT_SERVER ...`, which still wins. Each isolated suite runs
# as its own `fish --no-config` process, so these cannot leak to another suite.
set -gx GIT_SERVER ''
set -gx GITEA_URL ''
set -gx GITEA_HOST ''
set -gx GITLAB_URL ''
set -gx GITLAB_HOST ''
function _mkrep_sandbox
set -l tmp (mktemp -d)
# Resolve symlinks (e.g. macOS/NixOS /tmp) so path comparisons against
@@ -366,13 +386,57 @@ begin
set -lx GIT_SERVER gitea
set -lx GITEA_URL https://gitea.example.invalid
set -lx MKREP_REMOTE_CMD 'echo {name} >created.txt'
mkrep $target >/dev/null
check "\$GIT_SERVER + \$GITEA_URL exits 0" 0 $status
mkrep --yes $target >/dev/null
check "--yes on the \$GIT_SERVER path exits 0" 0 $status
check "\$GIT_SERVER picked gitea" repo (cat $target/created.txt)
cd $start
rm -rf $base
end
# The $GIT_SERVER path creates a repo on a live forge off nothing but an
# exported variable, so it confirms first. These cases run non-interactively
# (run-tests.fish uses `fish --no-config`), which is itself one of the
# behaviors under test: with no tty to ask, creation is skipped rather than
# assumed. The interactive y/N read is not covered here -- that needs a PTY,
# and the answer parsing it guards is a single `string match`.
section "mkrep: an implicit \$GIT_SERVER remote-create is not silently performed"
begin
_mkrep_stub_tool tea 1
set -l base (_mkrep_sandbox)
set -l target $base/repo
set -lx PATH $stub_bin $PATH
set -lx GIT_SERVER gitea
set -lx GITEA_URL https://gitea.example.invalid
set -lx MKREP_REMOTE_CMD 'echo {name} >created.txt'
mkrep $target >/dev/null 2>$base/err
check "unconfirmed \$GIT_SERVER create exits 0" 0 $status
check "unconfirmed \$GIT_SERVER create ran no command" false (test -e $target/created.txt; and echo true; or echo false)
check "unconfirmed \$GIT_SERVER create added no remote" 0 (count (git -C $target remote))
check "the local repo is still set up" true (test -d $target/.git; and echo true; or echo false)
check "the skip is reported on stderr" true (string match -q '*Skipped creating*' -- (cat $base/err); and echo true; or echo false)
check "the note names --yes" true (string match -q '*--yes*' -- (cat $base/err); and echo true; or echo false)
cd $start
rm -rf $base
end
section "mkrep: an explicit --server never prompts"
begin
_mkrep_stub_tool tea 1
set -l base (_mkrep_sandbox)
set -l target $base/repo
set -lx PATH $stub_bin $PATH
set -lx GITEA_URL https://gitea.example.invalid
set -lx MKREP_REMOTE_CMD 'echo {name} >created.txt'
mkrep --server gitea $target >/dev/null 2>$base/err
check "--server exits 0 with no tty" 0 $status
check "--server created without confirming" repo (cat $target/created.txt)
check "--server printed no skip note" false (string match -q '*Skipped creating*' -- (cat $base/err); and echo true; or echo false)
cd $start
rm -rf $base
end
section "mkrep: an explicit --remote overrides \$GIT_SERVER/\$GITEA_URL"
begin