feat(bin): add git folder management utilities and enhance task command parsing
- Introduce new git folder management functions: `clean-git-folder`, `commit-git-folder`, `ls-git-folder`, `push-git-folder`, `reset-git-folder`, `stage-git-folder`, `status-git-folder` - Add `.prompt/update-switch-case-for-all-task-files` script to update task files with comma-separated command support - Enhance task command parsing to support comma-separated commands with whitespace trimming and error handling - Document all new git folder functions in `library.md` under Git section - Add all new git folder functions to help table in `task.template` - Update `library.md` to include folder structure overview and fix typos - Maintain consistent formatting and structure with existing code
This commit is contained in:
10 files changed
+258
-3
No files matched your search
+78
@@ -0,0 +1,78 @@
|
||||
#!/bin/bash
|
||||
|
||||
DRY_RUN=false
|
||||
|
||||
SEARCH_PATTERN=$(cat <<'EOF'
|
||||
if declare -f "$1" > /dev/null; then
|
||||
activate-venv
|
||||
"$1" "${@:2}"
|
||||
EOF
|
||||
)
|
||||
|
||||
REPLACE_BLOCK=$(cat <<'EOF'
|
||||
if [[ "$1" == *","* ]]; then
|
||||
# Split comma-separated commands
|
||||
IFS=',' read -ra COMMANDS <<< "$1"
|
||||
for cmd in "${COMMANDS[@]}"; do
|
||||
# Trim whitespace
|
||||
cmd=$(echo "$cmd" | xargs)
|
||||
if declare -f "$cmd" > /dev/null; then
|
||||
"$cmd"
|
||||
else
|
||||
echo "Unknown command: $cmd"
|
||||
help
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
elif declare -f "$1" > /dev/null; then
|
||||
"$1" "${@:2}"
|
||||
EOF
|
||||
)
|
||||
|
||||
# Find all 'task' files, excluding specified subtrees
|
||||
find "$HOME" -type f -name 'task' \
|
||||
-not -path '*/janikv.cloud/*' \
|
||||
-not -path '*/cloud.mint-system.ch/*' \
|
||||
-not -path '*/tmp/*' \
|
||||
| while read -r file; do
|
||||
|
||||
# Only process if the exact block exists
|
||||
if grep -qF "$SEARCH_PATTERN" "$file"; then
|
||||
echo "Processing: $file"
|
||||
|
||||
task_dir="$(dirname "$file")"
|
||||
tmp_dir="$task_dir/tmp"
|
||||
mkdir -p "$tmp_dir"
|
||||
|
||||
# Add tmp/ to .gitignore if not already there
|
||||
gitignore="$task_dir/.gitignore"
|
||||
if [[ -f "$gitignore" ]]; then
|
||||
if ! grep -q "^tmp/$" "$gitignore" && ! grep -q "^tmp$" "$gitignore"; then
|
||||
echo "tmp/" >> "$gitignore"
|
||||
echo "✅ Added 'tmp/' to $gitignore"
|
||||
fi
|
||||
else
|
||||
echo "tmp/" > "$gitignore"
|
||||
echo "✅ Created $gitignore with 'tmp/'"
|
||||
fi
|
||||
|
||||
backup_path="$tmp_dir/task"
|
||||
cp "$file" "$backup_path"
|
||||
echo "💾 Backup saved to: $backup_path"
|
||||
|
||||
if [[ "$DRY_RUN" == false ]]; then
|
||||
sed -i -E "
|
||||
s|$(printf '%s' "$SEARCH_PATTERN" | sed 's/[]\/$*.^[]/\\&/g; s/\n/\\n/g')|$(
|
||||
printf '%s' "$REPLACE_BLOCK" | sed 's/[]\/$*.^[]/\\&/g; s/\n/\\n/g'
|
||||
)|g
|
||||
" "$file"
|
||||
echo "✅ Done: $file"
|
||||
else
|
||||
echo "🟡 Dry-run: No changes made to $file"
|
||||
fi
|
||||
else
|
||||
echo "⚠️ Skipping (pattern not found): $file"
|
||||
fi
|
||||
done
|
||||
|
||||
echo "🎉 All exact 'task' files processed (excluding janikv.cloud, cloud.mint-system.ch, and tmp subtrees)."
|
||||
Executable
+9
@@ -0,0 +1,9 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
clean-git-folder() {
|
||||
local git_folders=$(ls-git-folder)
|
||||
for git_folder in $git_folders; do
|
||||
echo "Clean git folder $git_folder."
|
||||
git -C "$git_folder" clean -df
|
||||
done
|
||||
}
|
||||
Executable
+12
@@ -0,0 +1,12 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
commit-git-folder() {
|
||||
if [[ -z "$1" ]]; then echo "\$1 is empty."; exit; fi
|
||||
if [[ -z "$2" ]]; then echo "\$2 is empty."; exit; fi
|
||||
local git_folders=$(ls-git-folder "$1")
|
||||
|
||||
for git_folder in $git_folders; do
|
||||
echo "Commit in $git_folder."
|
||||
git -C "$git_folder" commit --message "$2"
|
||||
done
|
||||
}
|
||||
Executable
+23
@@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
#!/usr/bin/env bash
|
||||
|
||||
ls-git-folder() {
|
||||
[[ -z "$1" ]] && { echo '$1 is empty.' >&2; return 1; }
|
||||
[[ ! -d "$1" ]] && { echo "Error: '$1' is not a directory." >&2; return 1; }
|
||||
|
||||
local excludes="${GIT_FOLDER_EXCLUDE:-.cache,node_modules,venv,__pycache__,.vim,.fzf,.password-store,.oh-my-zsh}"
|
||||
local find_cmd="find \"$1\" -maxdepth 3"
|
||||
|
||||
IFS=',' read -ra patterns <<< "$excludes"
|
||||
for pattern in "${patterns[@]}"; do
|
||||
pattern=$(echo "$pattern" | xargs)
|
||||
[[ -n "$pattern" ]] && find_cmd="$find_cmd \( -name '$pattern' -o -path \"*/$pattern/*\" \) -prune -o"
|
||||
done
|
||||
|
||||
find_cmd="$find_cmd -type d -name '.git' -print"
|
||||
|
||||
eval "$find_cmd" 2>/dev/null | while IFS= read -r git_dir; do
|
||||
dirname "$git_dir"
|
||||
done
|
||||
}
|
||||
Executable
+11
@@ -0,0 +1,11 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
push-git-folder() {
|
||||
if [[ -z "$1" ]]; then echo "\$1 is empty."; exit; fi
|
||||
local git_folders=$(ls-git-folder "$1")
|
||||
|
||||
for git_folder in $git_folders; do
|
||||
echo "Push in $git_folder."
|
||||
git -C "$git_folder" push
|
||||
done
|
||||
}
|
||||
Executable
+10
@@ -0,0 +1,10 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
reset-git-folder() {
|
||||
local git_folders=$(ls-git-folder)
|
||||
for git_folder in $git_folders; do
|
||||
echo "Abort rebase and reset git folder $git_folder."
|
||||
git -C "$git_folder" rebase --abort
|
||||
git -C "$git_folder" reset --hard
|
||||
done
|
||||
}
|
||||
Executable
+11
@@ -0,0 +1,11 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
stage-git-folder() {
|
||||
if [[ -z "$1" ]]; then echo "\$1 is empty."; exit; fi
|
||||
local git_folders=$(ls-git-folder "$1")
|
||||
|
||||
for git_folder in $git_folders; do
|
||||
echo "Stage all files in $git_folder."
|
||||
git -C "$git_folder" add --all
|
||||
done
|
||||
}
|
||||
Executable
+12
@@ -0,0 +1,12 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
status-git-folder() {
|
||||
if [[ -z "$1" ]]; then echo "\$1 is empty."; exit; fi
|
||||
local git_folders=$(ls-git-folder "$1")
|
||||
|
||||
echo 'Show status in git folders.'
|
||||
for git_folder in $git_folders; do
|
||||
git -C "$git_folder" status
|
||||
done
|
||||
}
|
||||
|
||||
+70
-2
@@ -32,9 +32,16 @@ if [[ -d "$HOME/taskfile.build/bin" ]]; then
|
||||
fi
|
||||
```
|
||||
|
||||
These commands create folder in the directory of the task file and the home directory. Here is an overview of these folders:
|
||||
|
||||
* `$PWD/tmp`: Temporary directory for the task commands.
|
||||
* `$PWD/.prompt`: LLM prompts stored as markdown files.
|
||||
* `$HOME/.config/taskfile.build`: Default path for storing dotenv files.
|
||||
* `$HOME/.docker/$CONTAINER_REGISTRY`: Default path for storing container registry credentials.
|
||||
|
||||
## Task
|
||||
|
||||
Configure the task commands.
|
||||
Configure the task enviroment.
|
||||
|
||||
```bash
|
||||
OPEN_BROWSER=False # Default: True
|
||||
@@ -67,6 +74,8 @@ printf "$column" 'open-url-with-delay' '[url][delay]' 'Open url after n seconds.
|
||||
|
||||
## Files
|
||||
|
||||
Managing files and directories.
|
||||
|
||||
### ensure-directory
|
||||
|
||||
```bash
|
||||
@@ -87,6 +96,8 @@ printf "$column" 'create-symlink-files' '[source][target]' 'Create symlink for f
|
||||
|
||||
## Python
|
||||
|
||||
Setup Python virtual enviroment.
|
||||
|
||||
### activate-venv
|
||||
|
||||
```bash
|
||||
@@ -169,6 +180,8 @@ printf "$column" 'restore-env-files' '[path]' 'Extract and copy env files from b
|
||||
|
||||
## LLM
|
||||
|
||||
Commands that integrate the `llm` cli.
|
||||
|
||||
### commit-with-llm
|
||||
|
||||
```bash
|
||||
@@ -183,6 +196,8 @@ printf "$column" 'update-with-llm' '[glob][prompt]' 'Feed files matching glob to
|
||||
|
||||
## Logging
|
||||
|
||||
Colorful logging in task commands.
|
||||
|
||||
### log-warning
|
||||
|
||||
```bash
|
||||
@@ -191,14 +206,61 @@ printf "$column" 'log-warning' '' 'Colored output for warnings.'
|
||||
|
||||
## Git
|
||||
|
||||
Manage git folders and submodules.
|
||||
|
||||
### commit-git-folder
|
||||
|
||||
```bash
|
||||
printf "$column" 'commit-git-folder' '[message][path]' 'Commit all changes in git folders in path.'
|
||||
```
|
||||
|
||||
### commit-git-folder
|
||||
|
||||
```bash
|
||||
printf "$column" 'clean-git-folder' '' 'Clean git folder.'
|
||||
```
|
||||
|
||||
### ls-git-folder
|
||||
|
||||
```bash
|
||||
printf "$column" 'ls-git-folder' '[path]' 'Space separated list of git folders in path.'
|
||||
```
|
||||
|
||||
### push-git-folder
|
||||
|
||||
```bash
|
||||
printf "$column" 'push-git-folder' '' 'Push all git folders in path.'
|
||||
```
|
||||
|
||||
### reset-git-folder
|
||||
|
||||
```bash
|
||||
printf "$column" 'reset-git-folder' '' 'Abort, rebase and reset git folder.'
|
||||
```
|
||||
|
||||
### stage-git-folder
|
||||
|
||||
```bash
|
||||
printf "$column" 'stage-git-folder' '[path]' 'Stage all files in git folders in path.'
|
||||
```
|
||||
|
||||
### status-git-folder
|
||||
|
||||
```bash
|
||||
printf "$column" 'status-git-folder' '[path]' 'Show status of git folders in path.'
|
||||
```
|
||||
|
||||
### update-submodule
|
||||
|
||||
```bash
|
||||
printf "$column" 'update-submodule' '' 'Update git submodules.'
|
||||
```
|
||||
|
||||
|
||||
## Pass
|
||||
|
||||
Load and store secrets from pass.
|
||||
|
||||
Set path to pass entry.
|
||||
|
||||
```bash
|
||||
@@ -219,7 +281,9 @@ printf "$column" 'load-dotenv-from-pass' '' 'Restore content to .env from pass e
|
||||
|
||||
## KeePass
|
||||
|
||||
Set path to KeePass database and entry.
|
||||
Load and store secrets from KeePassXC.
|
||||
|
||||
Set path to KeePassXC database and entry.
|
||||
|
||||
```bash
|
||||
KEEPASS_DATABASE_FILE="/path/to/database.kdbx"
|
||||
@@ -253,6 +317,8 @@ printf "$column" 'load-dotenv-from-keepass' '' 'Restore content to .env from Kee
|
||||
|
||||
## Docker
|
||||
|
||||
Build and push Docker images.
|
||||
|
||||
Set Docker env vars.
|
||||
|
||||
```bash
|
||||
@@ -277,6 +343,8 @@ printf "$column" 'build-image' '[output]' 'Build Docker image with buildx.'
|
||||
|
||||
## Ansible
|
||||
|
||||
Install scripts from the Ansible Build project.
|
||||
|
||||
### install-ansible-build-scripts
|
||||
|
||||
The available roles with scripts are listed here: <https://ansible.build/scripts.html>
|
||||
|
||||
+22
-1
@@ -37,6 +37,13 @@ help-table() {
|
||||
# Logging
|
||||
printf "$column" 'log-warning' '' 'Colored output for warnings.'
|
||||
# Git
|
||||
printf "$column" 'commit-git-folder' '[message][path]' 'Commit all changes in git folders in path.'
|
||||
printf "$column" 'clean-git-folder' '' 'Clean git folder.'
|
||||
printf "$column" 'ls-git-folder' '[path]' 'Space separated list of git folders in path.'
|
||||
printf "$column" 'push-git-folder' '' 'Push all git folders in path.'
|
||||
printf "$column" 'reset-git-folder' '' 'Abort, rebase and reset git folder.'
|
||||
printf "$column" 'stage-git-folder' '[path]' 'Stage all files in git folders in path.'
|
||||
printf "$column" 'status-git-folder' '[path]' 'Show status of git folders in path.'
|
||||
printf "$column" 'update-submodule' '' 'Update git submodules.'
|
||||
# Pass
|
||||
printf "$column" 'save-dotenv-to-pass' '' 'Store content of .env in pass entry.'
|
||||
@@ -73,7 +80,21 @@ if [[ -d "$HOME/taskfile.build/bin" ]]; then
|
||||
done
|
||||
fi
|
||||
|
||||
if declare -f "$1" > /dev/null; then
|
||||
if [[ "$1" == *","* ]]; then
|
||||
# Split comma-separated commands
|
||||
IFS=',' read -ra COMMANDS <<< "$1"
|
||||
for cmd in "${COMMANDS[@]}"; do
|
||||
# Trim whitespace
|
||||
cmd=$(echo "$cmd" | xargs)
|
||||
if declare -f "$cmd" > /dev/null; then
|
||||
"$cmd"
|
||||
else
|
||||
echo "Unknown command: $cmd"
|
||||
help
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
elif declare -f "$1" > /dev/null; then
|
||||
"$1" "${@:2}"
|
||||
else
|
||||
case "$1" in
|
||||
|
||||
Reference in new issue
Block a user