]> Nutra Git (v2) - gamesguru/git-remote-gcrypt.git/commitdiff
generate script generates from scratch
authorShane Jaroch <chown_tee@proton.me>
Thu, 8 Jan 2026 21:54:36 +0000 (16:54 -0500)
committerShane Jaroch <chown_tee@proton.me>
Thu, 8 Jan 2026 21:59:25 +0000 (16:59 -0500)
Makefile
completions/README.rst [deleted file]
tests/sync_docs.py

index fe19f9de4c2e8fb335af14bb09dc41a9bef20f4a..db9d41a7fa96a6ffb5bfb4e3f753a83b7233690b 100644 (file)
--- 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 (file)
index 0c8b365..0000000
+++ /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
-
index 803403ee30cbdbe3efe9d3b9e437c44b3899fab7..b03214ac0917e39870b969ca9df5bf9f171cca4a 100755 (executable)
@@ -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__":