From: Shane Jaroch Date: Thu, 8 Jan 2026 21:54:36 +0000 (-0500) Subject: generate script generates from scratch X-Git-Url: https://git.nutra.tk/v1?a=commitdiff_plain;h=386ebc032fea5cf30178999b7736ad4322c817b3;p=gamesguru%2Fgit-remote-gcrypt.git generate script generates from scratch --- diff --git a/Makefile b/Makefile index fe19f9d..db9d41a 100644 --- a/Makefile +++ b/Makefile @@ -202,7 +202,7 @@ clean: ##H Clean up .PHONY: generate generate: ##H Autogenerate README usage & completions @$(call print_info,Generating documentation and completions...) - @python3 tests/sync_docs.py + python3 tests/sync_docs.py @# Update README.rst Usage section (simple version for now) @sed -i '/Detecting gcrypt repos/,/Exit status is 0/c\Detecting gcrypt repos\n======================\n\nTo detect if a git url is a gcrypt repo, use::\n\n git-remote-gcrypt check url\n\n(Legacy syntax ``--check`` is also supported).\n\nExit status is 0' README.rst @sed -i '/Cleaning gcrypt repos/,/Known issues/c\Cleaning gcrypt repos\n=====================\n\nTo scan for unencrypted files in a remote gcrypt repo, use::\n\n git-remote-gcrypt clean [url|remote]\n\nIf no URL or remote is specified, ``git-remote-gcrypt`` will list all\navailable ``gcrypt::`` remotes.\n\nBy default, this command only performs a scan. To actually remove the\nunencrypted files, you must use the ``--force`` (or ``-f``) flag::\n\n git-remote-gcrypt clean url --force\n\nKnown issues' README.rst diff --git a/completions/README.rst b/completions/README.rst deleted file mode 100644 index 0c8b365..0000000 --- a/completions/README.rst +++ /dev/null @@ -1,59 +0,0 @@ -====================================== -Shell Completion for git-remote-gcrypt -====================================== - -This directory contains shell completion scripts for ``git-remote-gcrypt``. - -Installation -============ - -Bash ----- - -System-wide (requires sudo):: - - sudo cp completions/bash/git-remote-gcrypt /etc/bash_completion.d/ - -User-only:: - - mkdir -p ~/.local/share/bash-completion/completions - cp completions/bash/git-remote-gcrypt ~/.local/share/bash-completion/completions/ - -Zsh ---- - -System-wide (requires sudo):: - - sudo cp completions/zsh/_git-remote-gcrypt /usr/share/zsh/site-functions/ - -User-only:: - - mkdir -p ~/.zsh/completions - cp completions/zsh/_git-remote-gcrypt ~/.zsh/completions/ - # Add to ~/.zshrc: fpath=(~/.zsh/completions $fpath) - -Fish ----- - -User-only (Fish doesn't have system-wide completions):: - - mkdir -p ~/.config/fish/completions - cp completions/fish/git-remote-gcrypt.fish ~/.config/fish/completions/ - -Supported Completions -===================== - -- ``-h``, ``--help`` - Show help message -- ``-v``, ``--version`` - Show version information -- ``check`` - Check if URL is a gcrypt repository -- ``clean`` - Scan/Clean unencrypted files from remote - - ``-f``, ``--force`` - Actually delete files during clean -- ``--check`` - (Legacy) Check if URL is a gcrypt repository - -Notes -===== - -- Completions are optional and not required for normal operation -- ``git-remote-gcrypt`` is typically invoked by git automatically -- These completions are useful for manual invocation and testing - diff --git a/tests/sync_docs.py b/tests/sync_docs.py index 803403e..b03214a 100755 --- a/tests/sync_docs.py +++ b/tests/sync_docs.py @@ -39,43 +39,182 @@ def parse_commands(help_text): return sorted(list(set(commands))) -def update_bash_completion(path, commands): +BASH_TEMPLATE = r'''# Bash completion for git-remote-gcrypt +# Install to: /etc/bash_completion.d/ or ~/.local/share/bash-completion/completions/ + +_git_remote_gcrypt() {{ + local cur prev opts commands + COMPREPLY=() + cur="${{COMP_WORDS[COMP_CWORD]}}" + prev="${{COMP_WORDS[COMP_CWORD - 1]}}" + opts="-h --help -v --version --check" + commands="{commands}" + + # 1. First argument: complete commands and global options + if [[ $COMP_CWORD -eq 1 ]]; then + COMPREPLY=($(compgen -W "$commands $opts" -- "$cur")) + if [[ "$cur" == gcrypt::* ]]; then + COMPREPLY+=("$cur") + fi + return 0 + fi + + # 2. Handle subcommands + case "${{COMP_WORDS[1]}}" in + clean) + local remotes=$(git remote -v 2>/dev/null | grep 'gcrypt::' | awk '{{print $1}}' | sort -u || :) + COMPREPLY=($(compgen -W "-f --force -h --help $remotes" -- "$cur")) + return 0 + ;; + check|--check) + COMPREPLY=($(compgen -f -- "$cur")) + return 0 + ;; + capabilities|fetch|list|push) + COMPREPLY=($(compgen -W "-h --help" -- "$cur")) + return 0 + ;; + esac + + # 3. Fallback (global flags if not in a known subcommand?) + if [[ "$cur" == -* ]]; then + COMPREPLY=($(compgen -W "$opts" -- "$cur")) + return 0 + fi +}} + +complete -F _git_remote_gcrypt git-remote-gcrypt +''' + +ZSH_TEMPLATE = r'''#compdef git-remote-gcrypt +# Zsh completion for git-remote-gcrypt +# Install to: ~/.zsh/completions/ or /usr/share/zsh/site-functions/ + +_git_remote_gcrypt() {{ + local -a args + args=( + '(- *)'{{-h,--help}}'[show help message]' + '(- *)'{{-v,--version}}'[show version information]' + '--check[check if URL is a gcrypt repository]:URL:_files' + '1:command:({commands})' + '*::subcommand arguments:->args' + ) + _arguments -s -S $args + + case $words[1] in + clean) + _arguments \ + '(-f --force)'{{-f,--force}}'[actually delete files]' \ + '*:gcrypt URL: _alternative "remotes:gcrypt remote:($(git remote -v 2>/dev/null | grep "gcrypt::" | awk "{{print \$1}}" | sort -u))" "files:file:_files"' + ;; + check) + _arguments \ + '1:gcrypt URL:_files' + ;; + *) + _arguments \ + '*:gcrypt URL:' + ;; + esac +}} + +_git_remote_gcrypt "$@" +''' + +FISH_TEMPLATE = r'''# Fish completion for git-remote-gcrypt +# Install to: ~/.config/fish/completions/ + +complete -c git-remote-gcrypt -s h -l help -d 'Show help message' +complete -c git-remote-gcrypt -s v -l version -d 'Show version information' +complete -c git-remote-gcrypt -l check -d '(Legacy) Check if URL is a gcrypt repository' -r -F + +# Subcommands +complete -c git-remote-gcrypt -f -n "not __fish_seen_subcommand_from {not_sc_list}" -a 'check' -d 'Check if URL is a gcrypt repository' +complete -c git-remote-gcrypt -f -n "not __fish_seen_subcommand_from {not_sc_list}" -a 'clean' -d 'Scan/Clean unencrypted files from remote' +complete -c git-remote-gcrypt -n "__fish_seen_subcommand_from clean check" -a "(git remote -v 2>/dev/null | grep 'gcrypt::' | awk '{{print \$1}}' | sort -u)" -d 'Gcrypt Remote' + +# Clean flags +complete -c git-remote-gcrypt -f -n "__fish_seen_subcommand_from {not_sc_list}" -s f -l force -d 'Actually delete files during clean' + +# Git protocol commands +complete -c git-remote-gcrypt -f -n "not __fish_seen_subcommand_from {not_sc_list}" -a 'capabilities' -d 'Show git remote helper capabilities' +complete -c git-remote-gcrypt -f -n "not __fish_seen_subcommand_from {not_sc_list}" -a 'list' -d 'List refs in remote repository' +complete -c git-remote-gcrypt -f -n "not __fish_seen_subcommand_from {not_sc_list}" -a 'push' -d 'Push refs to remote repository' +complete -c git-remote-gcrypt -f -n "not __fish_seen_subcommand_from {not_sc_list}" -a 'fetch' -d 'Fetch refs from remote repository' +''' + +DETECT_SECTION = r'''Detecting gcrypt repos +====================== + +To detect if a git url is a gcrypt repo, use:: + + git-remote-gcrypt check url + +(Legacy syntax ``--check`` is also supported). + +Exit status is 0''' + +CLEAN_SECTION = r'''Cleaning gcrypt repos +===================== + +To scan for unencrypted files in a remote gcrypt repo, use:: + + git-remote-gcrypt clean [url|remote] + +If no URL or remote is specified, ``git-remote-gcrypt`` will list all +available ``gcrypt::`` remotes. + +By default, this command only performs a scan. To actually remove the +unencrypted files, you must use the ``--force`` (or ``-f``) flag:: + + git-remote-gcrypt clean url --force + +''' + + +def update_readme(path): if not os.path.exists(path): return with open(path, "r") as f: content = f.read() + + # robustly replace sections + pattern1 = r"(Detecting gcrypt repos\n======================.*?Exit status is 0)" + new_content = re.sub(pattern1, DETECT_SECTION, content, flags=re.DOTALL) + + pattern2 = r"(Cleaning gcrypt repos\n=====================.*?)(?=\nKnown issues)" + new_content = re.sub(pattern2, CLEAN_SECTION, new_content, flags=re.DOTALL) + + if content != new_content: + print(f"Updating README sections at: {path}") + with open(path, "w") as f: + f.write(new_content) + else: + print(f"README at {path} is up to date.") + + +def update_bash_completion(path, commands): + os.makedirs(os.path.dirname(path), exist_ok=True) cmd_str = " ".join(commands) - new_content = re.sub(r'commands="[^"]+"', f'commands="{cmd_str}"', content) + content = BASH_TEMPLATE.format(commands=cmd_str) with open(path, "w") as f: - f.write(new_content) + f.write(content) def update_zsh_completion(path, commands): - if not os.path.exists(path): - return - with open(path, "r") as f: - content = f.read() + os.makedirs(os.path.dirname(path), exist_ok=True) cmd_str = " ".join(commands) - # Match 1:command:(capabilities list push fetch check clean) - new_content = re.sub(r"1:command:\([^)]+\)", f"1:command:({cmd_str})", content) + content = ZSH_TEMPLATE.format(commands=cmd_str) with open(path, "w") as f: - f.write(new_content) + f.write(content) def update_fish_completion(path, commands): - if not os.path.exists(path): - return - with open(path, "r") as f: - content = f.read() - # Replace the list in "not __fish_seen_subcommand_from ..." + os.makedirs(os.path.dirname(path), exist_ok=True) cmd_str = " ".join(commands) - new_content = re.sub( - r'not __fish_seen_subcommand_from [^"]+', - f"not __fish_seen_subcommand_from {cmd_str}", - content, - ) + content = FISH_TEMPLATE.format(not_sc_list=cmd_str) with open(path, "w") as f: - f.write(new_content) + f.write(content) def main(): @@ -92,18 +231,23 @@ def main(): ) print(f"Detected commands: {' '.join(comp_commands)}") - - update_bash_completion( - os.path.join(root_dir, "completions/bash/git-remote-gcrypt"), comp_commands - ) - update_zsh_completion( - os.path.join(root_dir, "completions/zsh/_git-remote-gcrypt"), comp_commands - ) - update_fish_completion( - os.path.join(root_dir, "completions/fish/git-remote-gcrypt.fish"), comp_commands - ) - - print("Completions updated.") + + bash_path = os.path.join(root_dir, "completions/bash/git-remote-gcrypt") + print(f"Updating Bash completions at: {bash_path}") + update_bash_completion(bash_path, comp_commands) + + zsh_path = os.path.join(root_dir, "completions/zsh/_git-remote-gcrypt") + print(f"Updating Zsh completions at: {zsh_path}") + update_zsh_completion(zsh_path, comp_commands) + + fish_path = os.path.join(root_dir, "completions/fish/git-remote-gcrypt.fish") + print(f"Updating Fish completions at: {fish_path}") + update_fish_completion(fish_path, comp_commands) + + readme_path = os.path.join(root_dir, "README.rst") + update_readme(readme_path) + + print("Completions and Documentation updated.") if __name__ == "__main__":