wip
authorShane Jaroch <chown_tee@proton.me>
Sat, 17 Jan 2026 04:57:37 +0000 (23:57 -0500)
committerShane Jaroch <chown_tee@proton.me>
Sat, 17 Jan 2026 04:58:14 +0000 (23:58 -0500)
completions/fish/git-remote-gcrypt.fish
completions/gen_docs.sh
completions/zsh/_git-remote-gcrypt
tests/system-test-clean-repack.sh

index 9b86f70e80a0876f743cb71d1ed8aab86714301f..bdb8d42f4aa392ba3d5d7be567a680245134e591 100644 (file)
@@ -13,7 +13,6 @@ complete -c git-remote-gcrypt -n "__fish_seen_subcommand_from check" -a "(git re
 complete -c git-remote-gcrypt -n "__fish_seen_subcommand_from stat" -a "(git remote 2>/dev/null)" -d 'Git Remote'
 
 # Clean flags
-complete -c git-remote-gcrypt -f -n "__fish_seen_subcommand_from clean" -s -force -l  -d 'Flag';
-complete -c git-remote-gcrypt -f -n "__fish_seen_subcommand_from clean" -s -init -l  -d 'Flag';
-complete -c git-remote-gcrypt -f -n "__fish_seen_subcommand_from clean" -s -hard -l  -d 'Flag';
-
+complete -c git-remote-gcrypt -f -n "__fish_seen_subcommand_from clean" -l force -d 'Flag'
+complete -c git-remote-gcrypt -f -n "__fish_seen_subcommand_from clean" -l init -d 'Flag'
+complete -c git-remote-gcrypt -f -n "__fish_seen_subcommand_from clean" -l hard -d 'Flag'
index 4e03f2998ac71493af3eab09cca76f79443697ae..0608a910ff7b91d3f2ce93d91daafa7fc0705d89 100755 (executable)
@@ -50,9 +50,9 @@ CLEAN_FLAGS_BASH=$(echo "$CLEAN_FLAGS_RAW" | tr '\n' ' ' | sed 's/  */ /g; s/ $/
 
 # For Zsh: Generate proper spec strings
 CLEAN_FLAGS_ZSH=""
-IFS="
-"
-for line in $CLEAN_FLAGS_RAW; do
+# Use while read loop to handle lines safely
+echo "$CLEAN_FLAGS_RAW" | while read -r line; do
+       [ -z "$line" ] && continue
        # line is "-f --force" or "--hard"
        # simple split
        flags=$(echo "$line" | tr ' ' '\n')
@@ -66,26 +66,58 @@ for line in $CLEAN_FLAGS_RAW; do
        else
                fspec="$line"
        fi
-       # Description - we could extract it but for now generic
-       CLEAN_FLAGS_ZSH="${CLEAN_FLAGS_ZSH} '${excl}'${fspec}'[flag]'"
-done
-unset IFS
+       # Description - just generic
+       # Use printf to avoid newline issues in variable
+       printf " '%s'${fspec}'[flag]'" "$excl"
+done >.zsh_flags_tmp
+CLEAN_FLAGS_ZSH=$(cat .zsh_flags_tmp)
+rm .zsh_flags_tmp
 
 # For Fish
-# We need to turn "-f, --force" into:
-# complete ... -s f -l force ...
+# We need to turn "-f --force" into: -s f -l force
+# And "--hard" into: -l hard
 CLEAN_FLAGS_FISH=""
-# Use a loop over the raw lines
-IFS="
-"
-for line in $CLEAN_FLAGS_RAW; do
-       # line is like "-f --force"
-       short=$(echo "$line" | awk '{print $1}' | sed 's/-//')
-       long=$(echo "$line" | awk '{print $2}' | sed 's/--//')
-       # Escape quotes if needed (none usually)
-       CLEAN_FLAGS_FISH="${CLEAN_FLAGS_FISH}complete -c git-remote-gcrypt -f -n \"__fish_seen_subcommand_from clean\" -s $short -l $long -d 'Flag';\n"
-done
-unset IFS
+echo "$CLEAN_FLAGS_RAW" | while read -r line; do
+       [ -z "$line" ] && continue
+
+       short=""
+       long=""
+
+       # Split by space
+       # Case 1: "-f --force" -> field1=-f, field2=--force
+       # Case 2: "--hard" -> field1=--hard
+       f1=$(echo "$line" | awk '{print $1}')
+       f2=$(echo "$line" | awk '{print $2}')
+
+       if echo "$f1" | grep -q "^--"; then
+               # Starts with --, so it's a long flag.
+               long=${f1#--}
+               # f2 is likely empty or next flag (but we assume cleaned format)
+               if [ -n "$f2" ]; then
+                       # Should be descriptor or unexpected? Our parser above extracts only flags.
+                       # But our parser above might extract "-f --force" as "$2 $3".
+                       # If $2 is -f and $3 is --force.
+                       # Just in case, let's treat f2 as potentially another flag if we didn't handle it?
+                       # Actually, the parser at top produces "flag1 flag2".
+                       :
+               fi
+       else
+               # Starts with - (short)
+               short=${f1#-}
+               if [ -n "$f2" ] && echo "$f2" | grep -q "^--"; then
+                       long=${f2#--}
+               fi
+       fi
+
+       cmd='complete -c git-remote-gcrypt -f -n "__fish_seen_subcommand_from clean"'
+       [ -n "$short" ] && cmd="$cmd -s $short"
+       [ -n "$long" ] && cmd="$cmd -l $long"
+       cmd="$cmd -d 'Flag';"
+
+       printf "%s\n" "$cmd"
+done >.fish_tmp
+CLEAN_FLAGS_FISH=$(cat .fish_tmp)
+rm .fish_tmp
 
 # 3. Generate README
 echo "Generating $README_OUT..."
@@ -111,10 +143,13 @@ sed "s/{commands}/$COMMANDS_LIST/" "$ZSH_TMPL" \
 # 6. Generate Fish
 echo "Generating Fish completions..."
 # Fish needs {not_sc_list} which matches {commands} (space separated)
-sed "s/{not_sc_list}/$COMMANDS_LIST/g" "$FISH_TMPL" \
-       |
-       # Multi-line replacement in sed is hard. Use awk?
-       # Or just injecting the string with escaped newlines.
-       sed "s|{clean_flags_fish}|$CLEAN_FLAGS_FISH|" >"$FISH_OUT"
+# Use awk for safe replacement of multi-line string
+awk -v cmds="$COMMANDS_LIST" -v flags="$CLEAN_FLAGS_FISH" '
+       {
+               gsub(/{not_sc_list}/, cmds)
+               gsub(/{clean_flags_fish}/, flags)
+               print
+       }
+' "$FISH_TMPL" >"$FISH_OUT"
 
 echo "Done."
index 29845ea01eedd56945d287dfae26c90b0155d4fc..0b86da0044c54f27b32ecc09f93487cdaaa465ea 100644 (file)
@@ -14,7 +14,7 @@ _git_remote_gcrypt() {
 
        case $line[1] in
        clean)
-               _arguments  '(--force)'--force'[flag]' '(--init)'--init'[flag]' '(--hard)'--hard'[flag]' \
+               _arguments '(--force --init --hard)'{--force,--init,--hard}'[flag]' \
                        '*:gcrypt URL: _alternative "remotes:gcrypt remote:($(git remote -v 2>/dev/null | grep "gcrypt::" | awk "{print \$1}" | sort -u))" "files:file:_files"'
                ;;
        check | stat)
index edeb0f78619c15e74b7bac84098a9f22ee612fc3..d3f1fa20ece69269714bd19ad4794fa3266b8431 100755 (executable)
@@ -43,6 +43,13 @@ exec gpg "${args[@]}"
 EOF
 chmod +x "${GNUPGHOME}/gpg"
 
+# Git config isolation
+export GIT_CONFIG_SYSTEM=/dev/null
+export GIT_CONFIG_GLOBAL="$TEST_DIR/gitconfig"
+git config --global user.email "test@test.com"
+git config --global user.name "Test"
+git config --global init.defaultBranch "master"
+
 echo "Generating GPG key..."
 gpg --batch --passphrase "" --quick-generate-key "Test <test@test.com>"
 
@@ -51,7 +58,7 @@ cd "$REPO_DIR"
 git init
 git config user.email "test@test.com"
 git config user.name "Test User"
-git config --global advice.defaultBranchName false
+git config advice.defaultBranchName false
 
 # Initialize local remote
 git init --bare "$REMOTE_DIR"
@@ -122,7 +129,7 @@ echo "Created garbage blob: $GARBAGE_BLOB"
 cd "$TEST_DIR/raw_backend"
 echo "Garbage Data" >".garbage (file)"
 git add ".garbage (file)"
-git commit -m "Inject unencrypted garbage"
+git commit -m "Inject unencrypted garbage" --no-gpg-sign
 git push origin master
 
 # Verify garbage exists
@@ -133,7 +140,8 @@ git-remote-gcrypt clean --repack --force origin
 
 # Verify garbage removal from backend
 cd "$TEST_DIR/raw_backend"
-git pull origin master
+git fetch origin master
+git reset --hard origin/master
 
 if [ -f ".garbage (file)" ]; then
        echo "Failure: .garbage (file) still exists in backend!"