[[bash]]
# For extension-less files (i.e., git-remote-gcrypt)
indent_style=tab
-indent=4
+indent_size=4
[*.sh]
# For bash scripts with .sh extension
indent_style=tab
-indent=4
+indent_size=4
# python3-docutils enables rst2man
- name: Install kcov Dependencies
- if: steps.cache-kcov.outputs.cache-hit != 'true'
run: |
sudo apt-get update
sudo apt-get install -y binutils-dev build-essential cmake git \
- name: Build and Install kcov
if: steps.cache-kcov.outputs.cache-hit != 'true'
run: |
- git clone https://github.com/SimonKagstrom/kcov.git
+ git clone --branch v42 --depth 1 https://github.com/SimonKagstrom/kcov.git
cd kcov
mkdir build && cd build
cmake ..
schedule:
- cron: "0 0 * * 0" # Sunday at 12 AM
+permissions:
+ contents: read
+
jobs:
# Handles Ubuntu and macOS
install-unix:
printf "\033[1;34m✓ %s\033[0m\n" "$(1)"
endef
+
define print_info
printf "\033[1;36m%s\033[0m\n" "$(1)"
endef
+define print_target
+printf "\033[1;35m-> %s\033[0m\n" "$(1)"
+endef
+
.PHONY: check/deps
check/deps: ##H Verify kcov & shellcheck
@if command -v kcov >/dev/null 2>&1; then \
$(MAKE) test/installer test/system test/cov; \
else \
- $(call print_warn,kcov not found: skipping coverage/bash tests.); \
+ printf "\033[1;33mkcov not found: skipping coverage/bash tests.\033[0m\n"; \
$(MAKE) test/purity; \
fi
@rm -rf $(COV_SYSTEM)
@mkdir -p $(COV_SYSTEM)
@export GPG_TTY=$$(tty); \
- [ -n "$(DEBUG)$(V)" ] && export GCRYPT_DEBUG=1 && print_warn "Debug mode enabled"; \
+ [ -n "$(DEBUG)$(V)" ] && export GCRYPT_DEBUG=1 && printf "\033[1;33mDebug mode enabled\033[0m\n"; \
export GIT_CONFIG_PARAMETERS="'gcrypt.gpg-args=--pinentry-mode loopback --no-tty'"; \
sed -i 's|^#!/bin/sh|#!/bin/bash|' git-remote-gcrypt; \
trap "sed -i 's|^#!/bin/bash|#!/bin/sh|' git-remote-gcrypt" EXIT; \
(Legacy syntax ``--check`` is also supported).
-Exit status is 0
+Exit status is 0 if the remote uses gcrypt and was decrypted successfully, 1 if it
uses gcrypt but could not be decrypted, and 100 if the repo is not
encrypted with gcrypt (or could not be accessed).
# 2. Handle subcommands
case "${COMP_WORDS[1]}" in
clean)
- local remotes=$(git remote -v 2>/dev/null | grep 'gcrypt::' | awk '{print $1}' | sort -u || :)
+ local remotes=$(git remote -v 2>/dev/null | grep 'gcrypt::' | awk '{print $1}' | sort -u || :
COMPREPLY=($(compgen -W "{clean_flags_bash} $remotes" -- "$cur"))
return 0
;;
check)
- local remotes=$(git remote 2>/dev/null || :)
+ local remotes=$(git remote 2>/dev/null || :
COMPREPLY=($(compgen -W "$remotes" -- "$cur"))
return 0
;;
)
_arguments -s -S $args
- case $words[1] in
+ case $line[1] in
clean)
_arguments \
{clean_flags_zsh} \
)
_arguments -s -S $args
- case $words[1] in
+ case $line[1] in
clean)
_arguments \
- '()' {} '[flag]' \
+ {clean_flags_zsh} \
'*:gcrypt URL: _alternative "remotes:gcrypt remote:($(git remote -v 2>/dev/null | grep "gcrypt::" | awk "{print \$1}" | sort -u))" "files:file:_files"'
;;
check)
if isurl rsync "$URL"; then
r_files=$(rsync --no-motd --list-only "$(rsynclocation "$URL")/" | awk '{print $NF}' | grep -vE '^\.$|^\.\.$') || return 1
elif isurl rclone "$URL"; then
- r_files=$(rclone lsf "$(rclonelocation "$URL")") || return 1
+ r_files=$(rclone lsf "${URL#rclone://}") || return 1
elif isurl sftp "$URL"; then
r_files=$(curl -s -S -k "$URL/" | grep -vE '^\.$|^\.\.$') || return 1
elif islocalrepo "$URL"; then
r_files=""
fi
else
- # Git backend: Check safety-check ref first (most reliable if early_safety_check ran)
- # Or try to fetch master?
- # If early_safety_check ran, it fetched to refs/gcrypt/safety-check.
- if git rev-parse --verify "refs/gcrypt/safety-check" >/dev/null 2>&1; then
- r_files=$(git ls-tree -r --name-only "refs/gcrypt/safety-check") || return 1
+ # Git backend:
+ # We need to fetch the remote state to list its files.
+ # Try fetching master and main to a temporary ref.
+ if git fetch --quiet "$URL" "refs/heads/master:refs/gcrypt/list-files" 2>/dev/null || \
+ git fetch --quiet "$URL" "refs/heads/main:refs/gcrypt/list-files" 2>/dev/null; then
+ r_files=$(git ls-tree -r --name-only "refs/gcrypt/list-files") || return 1
+ git update-ref -d "refs/gcrypt/list-files"
else
- # Try fetching default branch?
- # If we can't verify emptiness, we should return error to prevent implicit init.
- # Using $Gref (refs/gcrypt/gitception...) might be empty if we haven't pushed yet.
+ # Could not fetch, or remote is empty.
+ # If checking, this might be fine, but for clean it's an issue if we expected files.
+ # Returning 1 is safer.
return 1
fi
fi
fi
VERSION=$(grep ^git-remote-gcrypt debian/changelog | head -n 1 | awk '{print $2}' | tr -d '()')
fi
-VERSION="$VERSION (deb running on $OS_IDENTIFIER)"
+VERSION="$VERSION ($OS_IDENTIFIER)"
echo "Detected version: $VERSION"
xml_file = os.environ.get("XML_FILE")
patt = os.environ.get("PATT")
+if not xml_file:
+ print("Error: XML_FILE environment variable is not set.")
+ sys.exit(1)
+
+if not patt:
+ print("Error: PATT environment variable is not set.")
+ sys.exit(1)
+
tree = E.parse(xml_file)
missed = []
total_lines = 0
(
set +e
if git clone -b "${default_branch}" "gcrypt::${tempdir}/second.git#${default_branch}" -- "${tempdir}/fail_test"; then
- print_info "ERROR: Clone succeeded unexpectedly with empty keyring!"
+ print_err "ERROR: Clone succeeded unexpectedly with empty keyring!"
exit 1
fi
) 2>&1 | indent
random_data_index=$((file_index * random_data_per_file))
echo "Writing large file $((file_index + 1))/${total_files} ($((random_data_per_file / 1024 / 1024)) MiB)"
head -c "${random_data_per_file}" >"$((file_index)).data" < \
- <(tail -c "+${random_data_index}" "${random_data_file}" || :)
+ <(tail -c "+$((random_data_index + 1))" "${random_data_file}" || :)
done
git add -- "${tempdir}/first"
git commit -m "Commit #${i}"
repo_root=$(git rev-parse --show-toplevel)
test_version=$(git describe --tags --always --dirty 2>/dev/null || echo "test")
cp "$repo_root/git-remote-gcrypt" "$tempdir/git-remote-gcrypt"
-sed -i "s/@@DEV_VERSION@@/$test_version/" "$tempdir/git-remote-gcrypt"
+sed "s/@@DEV_VERSION@@/$test_version/" "$tempdir/git-remote-gcrypt" > "$tempdir/git-remote-gcrypt.tmp"
+mv "$tempdir/git-remote-gcrypt.tmp" "$tempdir/git-remote-gcrypt"
chmod +x "$tempdir/git-remote-gcrypt"
PATH=$tempdir:${PATH}
readonly PATH
random_data_file="${tempdir}/data"
head -c "${random_data_size}" "${random_source}" > "${random_data_file}"
-# Create gpg key and subkey.
# Create gpg key and subkey.
print_info "Step 1: Creating a new GPG key and subkey to use for testing:"
(
# DEBUG: Dump directory listing to stdout
print_info "DEBUG: Listing ${tempdir}/second.git contents:"
- find "${tempdir}/second.git" -mindepth 1 -maxdepth 1 -printf '%f\n' | sort | indent
+ find "${tempdir}/second.git" -mindepth 1 -maxdepth 1 -exec basename {} \; | sort | indent
# Use find to robustly locate manifest files (56-64 hex chars)
# matching basename explicitly via grep. Using sed for portable basename extraction.
COMMIT=$(echo "Dirty commit with nested files" | $GIT commit-tree "$TREE")
$GIT update-ref refs/heads/master "$COMMIT"
-print_info "Created dirty remote with 2 unencrypted files"
+print_info "Created dirty remote with 4 unencrypted files"
# Test helper
assert_grep() {
$GIT add largeblob
$GIT commit -m "Add large blob" >/dev/null
echo "Pushing initial data..."
-git push origin master >/dev/null 2>&1 || {
+$GIT push origin master >/dev/null 2>&1 || {
echo "Push failed"
exit 1
}
fi
# Use the identified OS for the expected string
-EXPECTED_TAG="5.5.5-1 (deb running on $OS_IDENTIFIER)"
+EXPECTED_TAG="5.5.5-1 ($OS_IDENTIFIER)"
assert_version "$EXPECTED_TAG"
export DESTDIR="$SANDBOX/pkg_root"
export prefix="/usr"
-"bash" "$INSTALLER" >/dev/null 2>&1
+"bash" "$INSTALLER" >/dev/null 2>&1 || {
+ print_err "Installer FAILED"
+ exit 1
+}
if [ -f "$SANDBOX/pkg_root/usr/bin/git-remote-gcrypt" ]; then
printf " ✓ %s\n" "DESTDIR honored"
repo_root=$(git rev-parse --show-toplevel)
test_version=$(git describe --tags --always --dirty 2>/dev/null || echo "test")
cp "$repo_root/git-remote-gcrypt" "$tempdir/git-remote-gcrypt"
-sed -i "s/@@DEV_VERSION@@/$test_version/" "$tempdir/git-remote-gcrypt"
+sed "s/@@DEV_VERSION@@/$test_version/" "$tempdir/git-remote-gcrypt" >"$tempdir/git-remote-gcrypt.tmp"
+mv "$tempdir/git-remote-gcrypt.tmp" "$tempdir/git-remote-gcrypt"
chmod +x "$tempdir/git-remote-gcrypt"
PATH=$tempdir:${PATH}
export PATH
git config remote.origin.gcrypt-participants "test@example.com"
git config remote.origin.gcrypt-signingkey "test@example.com"
-# Force push is required to initialize gcrypt over an existing repo
# Force push is required to initialize gcrypt over an existing repo
# Now EXPECT FAILURE because of our new safety check!
print_info "Attempting push to dirty repo (should fail due to safety check)..."
echo "Man page not found: $MAN_PATH"
fi
+# Completions
+COMP_BASH="$DESTDIR$prefix/share/bash-completion/completions/git-remote-gcrypt"
+COMP_ZSH="$DESTDIR$prefix/share/zsh/site-functions/_git-remote-gcrypt"
+COMP_FISH="$DESTDIR$prefix/share/fish/vendor_completions.d/git-remote-gcrypt.fish"
+
+for f in "$COMP_BASH" "$COMP_ZSH" "$COMP_FISH"; do
+ if [ -f "$f" ]; then
+ verbose rm -f "$f"
+ echo "Removed completion: $f"
+ fi
+done
+
echo "Uninstallation complete."
# 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}/$(echo "$COMMANDS_HELP" | sed 's/[\/&]/\\&/g' | awk '{printf "%s\\n", $0}')/" "$README_TMPL" >"$README_OUT"
# 4. Generate Bash
echo "Generating Bash completions..."
# Zsh substitution is tricky with the complex string.
# We'll stick to replacing {commands} and {clean_flags_zsh}
# Need to escape special chars for sed
-SAFE_CMDS=$(echo "$COMMANDS_LIST" | sed 's/ / /g') # just space separated
+# safe_cmds removed as unused
# For clean_flags_zsh, since it contains quotes and braces, we need care.
# We'll read the template line by line? No, sed is standard.
# We use a temp file for the replacement string to avoid sed escaping hell for large blocks?