From 86ccf93e36a7a4f6e64b8aa1d44cfb4cb0cfecd2 Mon Sep 17 00:00:00 2001 From: Shane Jaroch Date: Sat, 17 Jan 2026 00:57:51 -0500 Subject: [PATCH] more fixes/lint/test tidying up. --- .github/workflows/lint.yaml | 15 ++++ .github/workflows/termux-android.yml | 39 ++++++++ Makefile | 5 +- completions/fish/git-remote-gcrypt.fish | 6 +- completions/gen_docs.sh | 4 +- completions/zsh/_git-remote-gcrypt | 2 +- install.sh | 2 +- tests/system-test-clean-command.sh | 2 +- tests/system-test-clean-repack.sh | 20 ++--- utils/gen_docs.sh | 113 ------------------------ 10 files changed, 75 insertions(+), 133 deletions(-) create mode 100644 .github/workflows/termux-android.yml delete mode 100755 utils/gen_docs.sh diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index eb63f24..8690d55 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -114,3 +114,18 @@ jobs: - name: Lint [make lint] run: make lint + + - name: Check Formatting [make format] + # Requires shfmt and black. + # Assuming environment has them or we install them. + # ubuntu-latest has python3, we need shfmt. + run: | + sudo snap install shfmt + pip3 install black + make format + git diff --exit-code + + - name: Check Generation [make generate] + run: | + make generate + git diff --exit-code diff --git a/.github/workflows/termux-android.yml b/.github/workflows/termux-android.yml new file mode 100644 index 0000000..4437696 --- /dev/null +++ b/.github/workflows/termux-android.yml @@ -0,0 +1,39 @@ +--- +name: Test on Termux + +"on": + push: + workflow_dispatch: + inputs: + debug: + description: "Enable debug logging (GCRYPT_DEBUG=1)" + required: false + type: boolean + default: false + schedule: + - cron: "0 0 * * 0" # Sunday at 12 AM + +jobs: + test: + runs-on: ubuntu-latest + + steps: + # 1. Checkout code on the Ubuntu Host (Ubuntu has glibc) + - uses: actions/checkout@v4 + with: + repository: gamesguru/git-remote-gcrypt + fetch-depth: 1 + + # 2. Run your tests inside Termux using manual Docker execution + - name: Run tests in Termux + run: | + # We mount the current directory ($PWD) to /data inside the container + # We set the working directory (-w) to /data + docker run --rm \ + -v "$PWD":/data \ + -w /data \ + termux/termux-docker:latest \ + sh -c "pkg update && pkg install -y git make \ + && make install + && make check/install + && git-remote-gcrypt --version" diff --git a/Makefile b/Makefile index f3cb385..576edef 100644 --- a/Makefile +++ b/Makefile @@ -63,12 +63,13 @@ check/deps: ##H Verify kcov & shellcheck LINT_LOCS_PY ?= $(shell git ls-files '*.py') LINT_LOCS_SH ?= $(shell git ls-files '*.sh' ':!tests/system-test.sh') +FORMAT_LOCS_SH ?= completions/** .PHONY: format format: ##H Format scripts @$(call print_target,format) @$(call print_info,Formatting shell scripts...) - shfmt -ci -bn -s -w $(LINT_LOCS_SH) + shfmt -ci -bn -s -w $(LINT_LOCS_SH) $(FORMAT_LOCS_SH) @$(call print_success,OK.) @$(call print_info,Formatting Python scripts...) -black $(LINT_LOCS_PY) @@ -193,7 +194,7 @@ __VERSION__ := $(shell git describe --tags --always --dirty 2>/dev/null || echo .PHONY: generate generate: ##H Autogen man docs & shell completions @$(call print_info,Generating documentation and completions...) - ./utils/gen_docs.sh + ./completions/gen_docs.sh @$(call print_success,Generated.) diff --git a/completions/fish/git-remote-gcrypt.fish b/completions/fish/git-remote-gcrypt.fish index bdb8d42..0bb8751 100644 --- a/completions/fish/git-remote-gcrypt.fish +++ b/completions/fish/git-remote-gcrypt.fish @@ -13,6 +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" -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' +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'; diff --git a/completions/gen_docs.sh b/completions/gen_docs.sh index a635500..00d5d5d 100755 --- a/completions/gen_docs.sh +++ b/completions/gen_docs.sh @@ -29,7 +29,7 @@ RAW_HELP=$(sed -n "/^$SCRIPT_KEY=\"/,/\"$/p" "$SRC" | sed "s/^$SCRIPT_KEY=\"//;s # 1. Prepare {commands_help} for README (Indented for RST) # We want the Options and Git Protocol Commands sections -COMMANDS_HELP=$(echo "$RAW_HELP" | sed -n '/^Options:/,$p' | sed 's/^/ /') +COMMANDS_HELP=$(printf '%s\n' "$RAW_HELP" | sed -n '/^Options:/,$p' | sed 's/^/ /') # 2. Parse Commands and Flags for Completions # Extract command names (first word after 2 spaces) @@ -145,7 +145,7 @@ rm .fish_tmp # 3. Generate README echo "Generating $README_OUT..." -sed "s/{commands_help}/$(echo "$COMMANDS_HELP" | sed 's/[\/&]/\\&/g' | sed ':a;N;$!ba;s/\n/\\n/g')/" "$README_TMPL" >"$README_OUT" +sed "s/{commands_help}/$(printf '%s\n' "$COMMANDS_HELP" | sed 's/[\/&]/\\&/g' | sed ':a;N;$!ba;s/\n/\\n/g')/" "$README_TMPL" >"$README_OUT" # 4. Generate Bash echo "Generating Bash completions..." diff --git a/completions/zsh/_git-remote-gcrypt b/completions/zsh/_git-remote-gcrypt index 0b86da0..d38d020 100644 --- a/completions/zsh/_git-remote-gcrypt +++ b/completions/zsh/_git-remote-gcrypt @@ -14,7 +14,7 @@ _git_remote_gcrypt() { case $line[1] in clean) - _arguments '(--force --init --hard)'{--force,--init,--hard}'[flag]' \ + _arguments --force'[Flag]' --init'[Flag]' --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) diff --git a/install.sh b/install.sh index f410675..db7d363 100755 --- a/install.sh +++ b/install.sh @@ -65,7 +65,7 @@ trap 'rm -rf "$BUILD_DIR"' EXIT sed "s|@@DEV_VERSION@@|$VERSION|g" git-remote-gcrypt >"$BUILD_DIR/git-remote-gcrypt" # --- GENERATION --- -verbose ./utils/gen_docs.sh +verbose ./completions/gen_docs.sh # --- INSTALLATION --- # This is where the 'Permission denied' happens if not sudo diff --git a/tests/system-test-clean-command.sh b/tests/system-test-clean-command.sh index 43f35e5..68c712d 100755 --- a/tests/system-test-clean-command.sh +++ b/tests/system-test-clean-command.sh @@ -26,7 +26,7 @@ unset GIT_CONFIG_PARAMETERS # Suppress git advice messages # Note: git-remote-gcrypt reads actual config files, not just CLI -c options -GIT="git -c advice.defaultBranchName=false -c commit.gpgSign=false" +GIT="git -c advice.defaultBranchName=false -c commit.gpgSign=false -c init.defaultBranch=master" # -------------------------------------------------- # Set up test environment diff --git a/tests/system-test-clean-repack.sh b/tests/system-test-clean-repack.sh index 8491ddc..1af0536 100755 --- a/tests/system-test-clean-repack.sh +++ b/tests/system-test-clean-repack.sh @@ -44,24 +44,22 @@ EOF chmod +x "${GNUPGHOME}/gpg" # Git config isolation +# Git config isolation (Strict: no global config) export GIT_CONFIG_SYSTEM=/dev/null -export GIT_CONFIG_GLOBAL="$TEST_DIR/gitconfig" -git config user.email "test@test.com" -git config user.name "Test" -git config init.defaultBranch "master" +export GIT_CONFIG_GLOBAL=/dev/null echo "Generating GPG key..." gpg --batch --passphrase "" --quick-generate-key "Test " # Initialize repo cd "$REPO_DIR" -git init +git -c init.defaultBranch=master init git config user.email "test@test.com" git config user.name "Test User" git config advice.defaultBranchName false # Initialize local remote -git init --bare "$REMOTE_DIR" +git -c init.defaultBranch=master init --bare "$REMOTE_DIR" git remote add origin "gcrypt::$REMOTE_DIR" git config remote.origin.gcrypt-participants "test@test.com" git config remote.origin.gcrypt-signingkey "test@test.com" @@ -74,20 +72,20 @@ export PATH="$PROJECT_ROOT:$PATH" echo "Push 1" echo "data 1" >file1.txt git add file1.txt -git commit -m "Commit 1" --no-gpg-sign +git commit -m "Commit 1" # Initial push needs force to initialize remote gcrypt repo git push origin +master echo "Push 2" echo "data 2" >file2.txt git add file2.txt -git commit -m "Commit 2" --no-gpg-sign +git commit -m "Commit 2" git push origin master echo "Push 3" echo "data 3" >file3.txt git add file3.txt -git commit -m "Commit 3" --no-gpg-sign +git commit -m "Commit 3" git push origin master # Verify we have multiple pack files in remote @@ -129,7 +127,9 @@ 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" --no-gpg-sign +git config user.email "test@test.com" +git config user.name "Test User" +git commit -m "Inject unencrypted garbage" git push origin master # Verify garbage exists diff --git a/utils/gen_docs.sh b/utils/gen_docs.sh deleted file mode 100755 index 217beda..0000000 --- a/utils/gen_docs.sh +++ /dev/null @@ -1,113 +0,0 @@ -#!/bin/sh -set -e - -# gen_docs.sh -# Generates documentation and shell completions from git-remote-gcrypt source. -# Strictly POSIX sh compliant. - -SCRIPT_KEY="HELP_TEXT" -SRC="git-remote-gcrypt" -README_TMPL="completions/templates/README.rst.in" -README_OUT="README.rst" -BASH_TMPL="completions/templates/bash.in" -BASH_OUT="completions/bash/git-remote-gcrypt" -ZSH_TMPL="completions/templates/zsh.in" -ZSH_OUT="completions/zsh/_git-remote-gcrypt" -FISH_TMPL="completions/templates/fish.in" -FISH_OUT="completions/fish/git-remote-gcrypt.fish" - -# Ensure we're in the project root -if [ ! -f "$SRC" ]; then - echo "Error: Must be run from project root" >&2 - exit 1 -fi - -# Extract HELP_TEXT variable content -# Using sed to capture lines between double quotes of HELP_TEXT="..." -# Assumes HELP_TEXT="..." is a single block. -RAW_HELP=$(sed -n "/^$SCRIPT_KEY=\"/,/\"$/p" "$SRC" | sed "s/^$SCRIPT_KEY=\"//;s/\"$//") - -# 1. Prepare {commands_help} for README (Indented for RST) -# We want the Options and Git Protocol Commands sections -COMMANDS_HELP=$(echo "$RAW_HELP" | sed -n '/^Options:/,$p' | sed 's/^/ /' | sed '$d') - -# 2. Parse Commands and Flags for Completions -# Extract command names (first word after 2 spaces) -COMMANDS_LIST=$(echo "$RAW_HELP" | awk '/^ [a-z]+ / {print $1}' | grep -vE "^(help|version|capabilities|list|push|fetch)$" | sort | tr '\n' ' ' | sed 's/ $//') - -# Extract clean flags -# Text: " clean --force Actually delete files..." -# We want: "--force --init --hard" -CLEAN_FLAGS_RAW=$(echo "$RAW_HELP" | grep "^ clean -" | awk '{print $2}') -CLEAN_FLAGS_BASH=$(echo "$CLEAN_FLAGS_RAW" | tr '\n' ' ' | sed 's/ $//') - -# For Zsh: we want simple list for now as per plan, user asked for dynamic but safe. -# Constructing a simple list of flags requires parsing. -# The previous python script just injected them. -CLEAN_FLAGS_ZSH="" -# We'll just provide the flags as a list for _arguments -# ZSH format roughly: '(-f --force)'{-f,--force}'[desc]' -# Only generate if there are actual flags -COMMA_FLAGS=$(echo "$CLEAN_FLAGS_BASH" | tr ' ' ',') -if [ -n "$CLEAN_FLAGS_BASH" ]; then - # zsh _arguments requires format: '(exclusion)'{-f,--long}'[desc]' as ONE string (no spaces) - # Since we only have one flag per line now (long only), exclusion is just itself or list of all? - # Mutually exclusive? Maybe. For now, simple list. - # Actually, with single flags, no need for the {...} brace expansion for aliases. - # Just list them. - CLEAN_FLAGS_ZSH="'(${CLEAN_FLAGS_BASH})'{${COMMA_FLAGS}}'[flag]'" -else - CLEAN_FLAGS_ZSH="" -fi - -CLEAN_FLAGS_FISH="" -# Use a loop over the raw lines -IFS=" -" -newline=" -" -sep="" -for line in $CLEAN_FLAGS_RAW; do - # line is just "--force" now - long="${line#--}" - # Escape quotes if needed (none usually) - CLEAN_FLAGS_FISH="${CLEAN_FLAGS_FISH}${sep}complete -c git-remote-gcrypt -f -n \"__fish_seen_subcommand_from clean\" -l $long -d 'Flag'" - sep="$newline" -done -unset IFS - -# Helper for template substitution using awk -# Usage: replace_template "TEMPLATE_FILE" "OUT_FILE" "KEY1=VALUE1" "KEY2=VALUE2" ... -replace_template() { - _tmpl="$1" - _out="$2" - shift 2 - _awk_script="" - for _kv in "$@"; do - _key="${_kv%%=*}" - _val="${_kv#*=}" - # Export the value so awk can access it via ENVIRON - export "REPLACE_$_key"="$_val" - _awk_script="${_awk_script} gsub(/\{${_key}\}/, ENVIRON[\"REPLACE_$_key\"]);" - done - awk "{ $_awk_script print }" "$_tmpl" >"$_out" -} - -# 3. Generate README -echo "Generating $README_OUT..." -replace_template "$README_TMPL" "$README_OUT" "commands_help=$COMMANDS_HELP" - -# 4. Generate Bash -echo "Generating Bash completions..." -replace_template "$BASH_TMPL" "$BASH_OUT" "commands=$COMMANDS_LIST" "clean_flags_bash=$CLEAN_FLAGS_BASH" - -# 5. Generate Zsh -echo "Generating Zsh completions..." -replace_template "$ZSH_TMPL" "$ZSH_OUT" "commands=$COMMANDS_LIST" "clean_flags_zsh=$CLEAN_FLAGS_ZSH" - -# 6. Generate Fish -echo "Generating Fish completions..." -# Fish needs {not_sc_list} which matches {commands} (space separated) -replace_template "$FISH_TMPL" "$FISH_OUT" "not_sc_list=$COMMANDS_LIST" "clean_flags_fish=$CLEAN_FLAGS_FISH" - -echo "Done." -- 2.52.0