From a27e78af51d02cf1edb57715a052d1d9dd025722 Mon Sep 17 00:00:00 2001 From: Janik von Rotz Date: Fri, 6 Feb 2026 16:29:51 +0100 Subject: [PATCH] feat: add project initialization script and template files with dynamic help table - Added `init-project` script to setup new taskfile projects with templates - Created `.gitignore.template` and `AGENTS.md.template` for standardized project setup - Implemented dynamic help table generation in `help-table` function - Updated `library.md` and `task.template` to include new `init-project` command - Added `init-project` to taskfile help documentation - Improved AGENTS.md with comprehensive coding conventions and agent guidance --- .gitignore.template | 21 ++++++ AGENTS.md | 2 +- AGENTS.md.template | 73 +++++++++++++++++++ CHANGELOG.md | 2 + README.md | 51 +++++++++++--- bin/init-project | 24 +++++++ library.md | 168 ++++++++++++++------------------------------ task | 58 ++++++++++----- task.template | 144 +++++++++++++++++++------------------ usage.md | 2 +- 10 files changed, 333 insertions(+), 212 deletions(-) create mode 100644 .gitignore.template create mode 100644 AGENTS.md.template create mode 100755 bin/init-project diff --git a/.gitignore.template b/.gitignore.template new file mode 100644 index 0000000..4d733bd --- /dev/null +++ b/.gitignore.template @@ -0,0 +1,21 @@ +# taskfile +tmp + +# dotenv +.env + +# Hugo +_site + +# pnpm +node_modules + +# Obsidian +.obsidian/workspace.json + +# VitePress +.vitepress/dist +.vitepress/cache + +# Python +.venv \ No newline at end of file diff --git a/AGENTS.md b/AGENTS.md index e3e9ae6..e82b201 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -10,7 +10,7 @@ This section outlines the universal rules and expectations for any LLM agent wor **Maintain Context:** Before making any changes, an agent must read and understand the relevant files, including the project's main documentation and existing code structure. -**Clear Contributions:** All contributions must be submitted via a pull request with a clear, concise commit message and a brief description of the changes. +**Be Sparse:** Only introduce new code if needed. Comment only what is worth commenting. When testing focus on the business use case. ## Project structure diff --git a/AGENTS.md.template b/AGENTS.md.template new file mode 100644 index 0000000..2f89d6c --- /dev/null +++ b/AGENTS.md.template @@ -0,0 +1,73 @@ +# AGENTS.md + +## General agent guidance + +This section outlines the universal rules and expectations for any LLM agent working within this repository. + +**Safety and Quality First:** The highest priority is to produce secure, well-documented, and high-quality code. Do not introduce vulnerabilities, hardcoded secrets, or unreadable code. + +**Propose a Plan:** For any new task, first provide a brief plan of action. This plan should clearly outline the intended changes and the rationale behind them. + +**Maintain Context:** Before making any changes, an agent must read and understand the relevant files, including the project's main documentation and existing code structure. + +**Be Sparse:** Only introduce new code if needed. Comment only what is worth commenting. When testing focus on the business use case. + +## Environment & tooling + +### Taskfile + +This project uses the standard. + +The `./task` file is a bash script that provides all functions necessary to work with this project. + +**Execute**: Always try to run a command with the `./task` file script. + +## Coding conventions + +### Bash + +The following guideline is heavily based on the [Bash Style Guide | ysap.sh](https://style.ysap.sh/), which should be considered the primary reference for style. Adhere to the following principles to ensure scripts are safe, predictable, and maintainable. + +**Shebang:** Start scripts with `#!/usr/bin/env bash` for portability. + +**Quoting:** This is critical. + +- Use double quotes `"` for strings that require variable expansion. +- Use single quotes `'` for all other strings. + +**Always quote variable expansions** `"$var"` to prevent word-splitting and globbing issues. + +**Variables:** Distinct between local and environment vars. + +- Use `local` for all variables inside functions. +- Use lowercase names for local variables (e.g., `buildx_output`). +- Use uppercase names for environment variables (e.g. `export BUILDX_PLATFORM`) + +**Functions:** + +- Do not use the `function` keyword. +- Use `my-func() { ... }` syntax. +- Function names are in kebab case. + +**Conditionals:** + +- Always use `[[ ... ]]` for conditional testing, not `[ ... ]` or `test`. +- Use `((...))` for arithmetic comparisons (e.g., `((a > b))`). +- When replacing `[]` with `[[]]` make sure to escape the brackets. The `[]` is a regex filter. + +**Command Substitution:** + +- Always use `$(...)` for command substitution, not backticks. + +**Arrays:** + +- Use Bash arrays to manage lists of items instead of space-separated strings. +- Iterate over arrays using `for item in "${my_array[@]}"; do ... done`. + +**Avoid External Commands:** + +- Use Bash's built-in parameter expansion for string manipulation (e.g., `${var/foo/bar}`). +- Use globbing (`*`) to iterate over files, not `ls`. +- Avoid `cat` when a command can read a file directly (e.g., `grep "pattern" file`). + +**`eval`:** Never use `eval`. diff --git a/CHANGELOG.md b/CHANGELOG.md index c31aaaf..0f88cfe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). ### Added - New CHANGELOG.md file to document project changes following Keep a Changelog specifications +- Make help table with dynamic +- Add .gitignore and AGENTS.md template files ### Changed diff --git a/README.md b/README.md index fa076a4..0eaabe0 100644 --- a/README.md +++ b/README.md @@ -12,10 +12,17 @@ permalink: / --- -The task file is a simple bash script and standardized interface for all software projects. +The task file is a simple bash script and standardized interface for any software project. It is to be understood as a software development pattern to standardize the installation, configuration and execution of different software frameworks. +- **Package Management**: Install and configure software and tools with ease. +- **Docker Build**: Build and publish Docker imgages for your project. +- **KeePass / Pass**: Store and load secrets from KeePass and pass. +- **.env / dotenv**: Manage multiple dotenv files for your projects. +- **CI Pipelines**: Simplify CI pipelines by making the executed task reproducable. +- **Helper scripts**: There are many examples and commands that make scripting easier. + ## Specification The specification is a short guide to set up a task file for a Python project. @@ -56,17 +63,39 @@ Add a help function. ```bash help-table() { - local cmd_width=10 - local opt_width=6 - local desc_width=40 - local column="| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" + local -a rows + local max_cmd=7 max_opt=6 max_desc=11 - printf "$column" 'Command' 'Option' 'Description' - echo "|$(printf '%*s' $((cmd_width + 2)) '' | tr ' ' '-')|$(printf '%*s' $((opt_width + 2)) '' | tr ' ' '-')|$(printf '%*s' $((desc_width + 2)) '' | tr ' ' '-')|" - printf "$column" 'help' '[grep]' 'Show help for commands.' - printf "$column" 'install' '' 'Setup the local environment.' - printf "$column" 'lint' '' 'Run pre-commit and update index.html.' - printf "$column" 'version' '' 'Show version of required tools.' + rows+=("Command|Option|Description") + rows+=("help|[grep]|Show help for commands.") + rows+=("install||Setup the local environment.") + rows+=("lint||Run pre-commit and update index.html.") + rows+=("version||Show version of required tools.") + + for row in "${rows[@]}"; do + IFS='|' read -r cmd opt desc <<< "$row" + (( ${#cmd} > max_cmd )) && max_cmd=${#cmd} + (( ${#opt} > max_opt )) && max_opt=${#opt} + (( ${#desc} > max_desc )) && max_desc=${#desc} + done + + printf '| %-*s | %-*s | %-*s |\n' \ + "$max_cmd" "Command" \ + "$max_opt" "Option" \ + "$max_desc" "Description" + + printf '|-%*s-|-%*s-|-%*s-|\n' \ + "$max_cmd" "$(printf '%*s' "$max_cmd" '' | tr ' ' '-')" \ + "$max_opt" "$(printf '%*s' "$max_opt" '' | tr ' ' '-')" \ + "$max_desc" "$(printf '%*s' "$max_desc" '' | tr ' ' '-')" + + for row in "${rows[@]:1}"; do + IFS='|' read -r cmd opt desc <<< "$row" + printf '| %-*s | %-*s | %-*s |\n' \ + "$max_cmd" "$cmd" \ + "$max_opt" "$opt" \ + "$max_desc" "$desc" + done } help() { diff --git a/bin/init-project b/bin/init-project new file mode 100755 index 0000000..f2b2b34 --- /dev/null +++ b/bin/init-project @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +init-project() { + echo "Init git directory." + git init . + + echo "Create taskfile directories." + mkdir -p tmp .prompt + + echo "Copy gitgnore template." + cp "$HOME/taskfile.build/.gitignore.template" ./.gitignore + + echo "Copy taskfile template." + cp "$HOME/taskfile.build/task.template" ./task + + echo "Copy AGENTS.md template." + cp "$HOME/taskfile.build/AGENTS.md.template" ./AGENTS.md + + echo "Touch default files." + touch ./README.md ./.env + + echo "Copy license file." + cp "$HOME/taskfile.build/LICENSE" ./LICENSE +} diff --git a/library.md b/library.md index 29f823f..c79c0ad 100644 --- a/library.md +++ b/library.md @@ -1,11 +1,8 @@ --- layout: layouts/base.njk --- - # Library - The repository of this website provides a library of reusable functions. - Clone the repository into your home folder and ensure it is updated regularly. ```bash @@ -33,14 +30,12 @@ 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 enviroment. ```bash @@ -49,81 +44,72 @@ TASK_DOTENV_DIR="$HOME/Odoo-Build/config" # Default: "$HOME/.config/taskfile.bui ``` ### clone-taskfile - ```bash -printf "$column" 'clone-taskfile' '' 'Clone the taskfile.build repo.' +rows+=("clone-taskfile||Clone the taskfile.build repo.") +``` + +### init-project +```bash +rows+=("init-project||Setup a taskfile project in the current directory.") ``` ### init-config-dir - ```bash -printf "$column" 'init-dotenv-dir' '' 'Setup task dotenv dir.' +rows+=("init-dotenv-dir||Setup task dotenv dir.") ``` ### template-dotenv - ```bash -printf "$column" 'template-dotenv' '' 'Generate .env from .env.template.' +rows+=("template-dotenv||Generate .env from .env.template.") ``` ### open-with-os - ```bash -printf "$column" 'open-with-os' '' 'Open file or url with default application.' +rows+=("open-with-os||Open file or url with default application.") ``` ### open-url-with-delay - ```bash -printf "$column" 'open-url-with-delay' '[url][delay]' 'Open url after n seconds.' +rows+=("open-url-with-delay|[url][delay]|Open url after n seconds.") ``` ### show-dotenv-setup - ```bash -printf "$column" 'show-dotenv-setup' '' 'Show info about the dotenv setup.' +rows+=("show-dotenv-setup||Show info about the dotenv setup.") ``` ## Files - Managing files and directories. ### ensure-directory - ```bash -printf "$column" 'ensure-directory' '[path]' 'Ensure directory path exists.' +rows+=("ensure-directory|[path]|Ensure directory path exists.") ``` ### create-symlink - ```bash -printf "$column" 'create-symlink' '[target][source]' 'Remove existing file/directory and create symlink.' +rows+=("create-symlink|[target][source]|Remove existing file/directory and create symlink.") ``` ### create-symlink-files - ```bash -printf "$column" 'create-symlink-files' '[target][source]' 'Create symlink for files in source pattern.' +rows+=("create-symlink-files|[target][source]|Create symlink for files in source pattern.") ``` ## Python - Setup Python virtual enviroment. ### activate-venv - ```bash -printf "$column" 'activate-venv' '' 'Activate or initialize Python virtual env.' +rows+=("activate-venv||Activate or initialize Python virtual env.") ``` ### remove-venv - ```bash -printf "$column" 'remove-venv' '' 'Remove the Python virtual env.' +rows+=("remove-venv||Remove the Python virtual env.") ``` ## Environment - Manage `.env` files in the task config folder. ```bash @@ -131,177 +117,145 @@ TASK_DOTENV_DIR="$HOME/Odoo-Build/config" # Default: "$HOME/.config/taskfile.bui ``` ### create-dotenv - ```bash -printf "$column" 'create-dotenv' '[env][type]' 'Create .env file of type nextcloud, odoo, upgrade.' +rows+=("create-dotenv|[env][type]|Create .env file of type nextcloud, odoo, upgrade.") ``` ### list-dotenv - ```bash -printf "$column" 'list-dotenv' '' 'List .env files.' +rows+=("list-dotenv||List .env files.") ``` ### show-dotenv - ```bash -printf "$column" 'show-dotenv' '[env]' 'Output content of the .env file.' +rows+=("show-dotenv|[env]|Output content of the .env file.") ``` ### copy-dotenv - ```bash -printf "$column" 'copy-dotenv' '[env][env]' 'dotenv .env file.' +rows+=("copy-dotenv|[env][env]|dotenv .env file.") ``` ### edit-dotenv - ```bash -printf "$column" 'edit-dotenv' '[env]' 'Open .env file in default editor.' +rows+=("edit-dotenv|[env]|Open .env file in default editor.") ``` ### load-dotenv - ```bash -printf "$column" 'load-dotenv' '[env]' 'Load and export .env file.' +rows+=("load-dotenv|[env]|Load and export .env file.") ``` ### rename-dotenv - ```bash -printf "$column" 'rename-dotenv' '[env][env]' 'Rename .env file.' +rows+=("rename-dotenv|[env][env]|Rename .env file.") ``` ### remove-dotenv - ```bash -printf "$column" 'remove-dotenv' '[env]' 'Remove .env file.' +rows+=("remove-dotenv|[env]|Remove .env file.") ``` ### backup-dotenv-files - ```bash -printf "$column" 'backup-dotenv-files' '[path]' 'Archive and copy .env files to target location.' +rows+=("backup-dotenv-files|[path]|Archive and copy .env files to target location.") ``` ### restore-dotenv-files - ```bash -printf "$column" 'restore-dotenv-files' '[path]' 'Extract and copy .env files from backup file.' +rows+=("restore-dotenv-files|[path]|Extract and copy .env files from backup file.") ``` ## LLM - Commands that integrate the `llm` cli. ### commit-with-llm - ```bash -printf "$column" 'commit-with-llm' '' 'Commit with llm generated commit message.' +rows+=("commit-with-llm||Commit with llm generated commit message.") ``` ### update-with-llm - ```bash -printf "$column" 'update-with-llm' '[glob][prompt]' 'Feed files matching glob to LLM and apply changes.' +rows+=("update-with-llm|[glob][prompt]|Feed files matching glob to LLM and apply changes.") ``` ## Logging - Colorful logging in task commands. ### log-error - ```bash -printf "$column" 'log-error' '' 'Colored output for errors.' +rows+=("log-error||Colored output for errors.") ``` ### log-success - ```bash -printf "$column" 'log-success' '' 'Colored output for success.' +rows+=("log-success||Colored output for success.") ``` ### log-warning - ```bash -printf "$column" 'log-warning' '' 'Colored output for warnings.' +rows+=("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.' +rows+=("commit-git-folder|[message][path]|Commit all changes in git folders in path.") ``` -### commit-git-folder - +### clean-git-folder ```bash -printf "$column" 'clean-git-folder' '' 'Clean git folder.' +rows+=("clean-git-folder||Clean git folder.") ``` ### ls-git-folder - ```bash -printf "$column" 'ls-git-folder' '[path]' 'Space separated list of git folders in path.' +rows+=("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.' +rows+=("push-git-folder||Push all git folders in path.") ``` ### reset-git-folder - ```bash -printf "$column" 'reset-git-folder' '' 'Abort, rebase and reset git folder.' +rows+=("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.' +rows+=("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.' +rows+=("status-git-folder|[path]|Show status of git folders in path.") ``` ### update-submodule - ```bash -printf "$column" 'update-submodule' '' 'Update git submodules.' +rows+=("update-submodule||Update git submodules.") ``` ## Pass - Load and store secrets from pass. - The name of the entry will resolve dynamically depending on the current directory / project. Use `show-dotenv` to show info about the dotenv setup. ### save-dotenv-to-pass - ```bash -printf "$column" 'save-dotenv-to-pass' '[file]' 'Store content of .env in pass entry.' +rows+=("save-dotenv-to-pass|[file]|Store content of .env in pass entry.") ``` ### load-dotenv-from-pass - ```bash -printf "$column" 'load-dotenv-from-pass' '[file]' 'Restore content to .env from pass entry.' +rows+=("load-dotenv-from-pass|[file]|Restore content to .env from pass entry.") ``` ## KeePass - Load and store secrets from KeePassXC. - Set path to KeePassXC database and entry: ```bash @@ -312,59 +266,49 @@ KEEPASS_DATABASE_KEY_FILE="/path/to/keepass.key" The name of the entry will resolve dynamically depending on the current directory / project. Use `show-dotenv` to show info about the dotenv setup. ### save-pass-to-keepass - ```bash -printf "$column" 'save-pass-to-keepass' '[pass][entry]' 'Store password to KeePass entry.' +rows+=("save-pass-to-keepass|[pass][entry]|Store password to KeePass entry.") ``` ### get-pass-from-keepass - ```bash -printf "$column" 'get-pass-from-keepass' '[entry]' 'Get password from KeePass entry.' +rows+=("get-pass-from-keepass|[entry]|Get password from KeePass entry.") ``` ### save-dotenv-to-keepass - ```bash -printf "$column" 'save-dotenv-to-keepass' '[file]' 'Store content of .env in KeePass entry.' +rows+=("save-dotenv-to-keepass|[file]|Store content of .env in KeePass entry.") ``` ### load-dotenv-from-keepass - ```bash -printf "$column" 'load-dotenv-from-keepass' '[file]' 'Restore content to .env from KeePass entry.' +rows+=("load-dotenv-from-keepass|[file]|Restore content to .env from KeePass entry.") ``` ## Kubernetes ### save-kubeconfig-to-pass - ```bash -printf "$column" 'save-kubeconfig-to-pass' '[ctx]' 'Save kubeconfig file in pass.' +rows+=("save-kubeconfig-to-pass|[ctx]|Save kubeconfig file in pass.") ``` ### save-kubeconfig-to-keepass - ```bash -printf "$column" 'save-kubeconfig-to-keepass' '[ctx]' 'Save kubeconfig file in KeePass.' +rows+=("save-kubeconfig-to-keepass|[ctx]|Save kubeconfig file in KeePass.") ``` ### load-kubeconfig-from-pass - ```bash -printf "$column" 'load-kubeconfig-from-pass' '[ctx]' 'Load kubeconfig file from pass.' +rows+=("load-kubeconfig-from-pass|[ctx]|Load kubeconfig file from pass.") ``` ### load-kubeconfig-from-keepass - ```bash -printf "$column" 'load-kubeconfig-from-keepass' '[ctx]' 'Load kubeconfig file from KeePass.' +rows+=("load-kubeconfig-from-keepass|[ctx]|Load kubeconfig file from KeePass.") ``` ## Docker - Build and push Docker images. - Set Docker env vars. ```bash @@ -376,25 +320,21 @@ DOCKER_CONFIG="$HOME/.docker/$CONTAINER_REGISTRY/" ``` ### login-docker - ```bash -printf "$column" 'login-docker' '[user][token]' 'Run Docker login and create docker config.' +rows+=("login-docker|[user][token]|Run Docker login and create docker config.") ``` ### build-image - ```bash -printf "$column" 'build-image' '[output]' 'Build Docker image with buildx.' +rows+=("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: ```bash -printf "$column" 'install-ansible-build-scripts' '[role]' 'Install scripts of the specified Ansbile role.' -``` +rows+=("install-ansible-build-scripts|[role]|Install scripts of the specified Ansbile role.") +``` \ No newline at end of file diff --git a/task b/task index 057f692..2c76f28 100755 --- a/task +++ b/task @@ -2,25 +2,47 @@ set -e help-table() { - local cmd_width=20 - local opt_width=10 - local desc_width=42 - local column="| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" + local -a rows + local max_cmd=7 max_opt=6 max_desc=11 - printf "$column" 'Command' 'Option' 'Description' - echo "|$(printf '%*s' $((cmd_width + 2)) '' | tr ' ' '-')|$(printf '%*s' $((opt_width + 2)) '' | tr ' ' '-')|$(printf '%*s' $((desc_width + 2)) '' | tr ' ' '-')|" - printf "$column" 'all' '' 'Run all tasks.' - printf "$column" 'build-11ty' '' 'Build the 11ty website.' - printf "$column" 'build-image' '[output]' 'Build Docker image with buildx.' - printf "$column" 'commit-with-llm' '' 'Commit with llm generated commit message.' - printf "$column" 'dev-11ty' '' 'Run 11ty server.' - printf "$column" 'help' '[grep]' 'Show help for commands.' - printf "$column" 'install' '' 'Install node packages.' - printf "$column" 'lint' '' 'Lint code with prettier.' - printf "$column" 'run' '' 'Run Docker image.' - printf "$column" 'run-tests' '' 'Test with shellcheck.' - printf "$column" 'serve-11ty' '' 'Serve the 11ty output folder.' - printf "$column" 'version' '' 'Show version of required tools.' + rows+=("Command|Option|Description") + rows+=("all||Run all tasks.") + rows+=("build-11ty||Build the 11ty website.") + rows+=("build-image|[output]|Build Docker image with buildx.") + rows+=("commit-with-llm||Commit with llm generated commit message.") + rows+=("dev-11ty||Run 11ty server.") + rows+=("help|[grep]|Show help for commands.") + rows+=("install||Install node packages.") + rows+=("lint||Lint code with prettier.") + rows+=("run||Run Docker image.") + rows+=("run-tests||Test with shellcheck.") + rows+=("serve-11ty||Serve the 11ty output folder.") + rows+=("version||Show version of required tools.") + + for row in "${rows[@]}"; do + IFS='|' read -r cmd opt desc <<< "$row" + (( ${#cmd} > max_cmd )) && max_cmd=${#cmd} + (( ${#opt} > max_opt )) && max_opt=${#opt} + (( ${#desc} > max_desc )) && max_desc=${#desc} + done + + printf '| %-*s | %-*s | %-*s |\n' \ + "$max_cmd" "Command" \ + "$max_opt" "Option" \ + "$max_desc" "Description" + + printf '|-%*s-|-%*s-|-%*s-|\n' \ + "$max_cmd" "$(printf '%*s' "$max_cmd" '' | tr ' ' '-')" \ + "$max_opt" "$(printf '%*s' "$max_opt" '' | tr ' ' '-')" \ + "$max_desc" "$(printf '%*s' "$max_desc" '' | tr ' ' '-')" + + for row in "${rows[@]:1}"; do + IFS='|' read -r cmd opt desc <<< "$row" + printf '| %-*s | %-*s | %-*s |\n' \ + "$max_cmd" "$cmd" \ + "$max_opt" "$opt" \ + "$max_desc" "$desc" + done } help() { diff --git a/task.template b/task.template index 8c57160..6352c3c 100755 --- a/task.template +++ b/task.template @@ -1,5 +1,4 @@ #!/usr/bin/env bash - set -e if [[ -a ".env" ]]; then @@ -7,72 +6,83 @@ if [[ -a ".env" ]]; then fi help-table() { - local cmd_width=30 - local opt_width=16 - local desc_width=50 - local column="| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n" - - printf "$column" "Command" "Option" "Description" - echo "|$(printf '%*s' $((cmd_width + 2)) '' | tr ' ' '-')|$(printf '%*s' $((opt_width + 2)) '' | tr ' ' '-')|$(printf '%*s' $((desc_width + 2)) '' | tr ' ' '-')|" - # Task - printf "$column" 'clone-taskfile' '' 'Clone the taskfile.build repo.' - printf "$column" 'init-dotenv-dir' '' 'Setup task dotenv dir.' - printf "$column" 'template-dotenv' '' 'Generate .env from .env.template.' - printf "$column" 'open-with-os' '' 'Open file or url with default application.' - printf "$column" 'open-url-with-delay' '[url][delay]' 'Open url after n seconds.' - printf "$column" 'show-dotenv' '' 'Show info about the dotenv setup.' - # Files - printf "$column" 'ensure-directory' '[path]' 'Ensure directory path exists.' - printf "$column" 'create-symlink' '[target][source]' 'Remove existing file/directory and create symlink.' - printf "$column" 'create-symlink-files' '[target][source]' 'Create symlink for files in source pattern.' - # Python - printf "$column" 'activate-venv' '' 'Activate or initialize Python virtual env.' - printf "$column" 'remove-venv' '' 'Remove the Python virtual env.' - # Environment - printf "$column" 'create-dotenv' '[env][type]' 'Create env file of type nextcloud, odoo, upgrade.' - printf "$column" 'list-dotenv' '' 'List .env files.' - printf "$column" 'show-dotenv' '[env]' 'Output content of the .env file.' - printf "$column" 'copy-dotenv' '[env][env]' 'Copy .env file.' - printf "$column" 'edit-dotenv' '[env]' 'Open env file in default editor.' - printf "$column" 'load-dotenv' '[env]' 'Load and export .env file.' - printf "$column" 'rename-dotenv' '[env][env]' 'Rename .env file.' - printf "$column" 'remove-dotenv' '[env]' 'Remove environment config.' - printf "$column" 'backup-dotenv-files' '[path]' 'Archive and copy .env files to target location.' - printf "$column" 'restore-dotenv-files' '[path]' 'Extract and copy .env files from backup file.' - # LLM - printf "$column" 'commit-with-llm' '' 'Commit with llm generated commit message.' - printf "$column" 'update-with-llm' '[glob][prompt]' 'Feed files matching glob to LLM and apply changes.' - # Logging - printf "$column" 'log-error' '' 'Colored output for errors.' - printf "$column" 'log-success' '' 'Colored output for success.' - 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.' - printf "$column" 'load-dotenv-from-pass' '' 'Restore content to .env from pass entry.' - # KeePass - printf "$column" 'save-pass-to-keepass' '[pass][entry]' 'Store password to KeePass entry.' - printf "$column" 'get-pass-from-keepass' '[entry]' 'Get password from KeePass entry.' - printf "$column" 'save-dotenv-to-keepass' '[file]' 'Store content of .env in KeePass entry.' - printf "$column" 'load-dotenv-from-keepass' '[file]' 'Restore content to .env from KeePass entry.' - # Kubernetes - printf "$column" 'save-kubeconfig-to-pass' '[ctx]' 'Save kubeconfig file in pass.' - printf "$column" 'save-kubeconfig-to-keepass' '[ctx]' 'Save kubeconfig file in KeePass.' - printf "$column" 'load-kubeconfig-from-pass' '[ctx]' 'Load kubeconfig file from pass.' - printf "$column" 'load-kubeconfig-from-keepass' '[ctx]' 'Load kubeconfig file from KeePass.' - # Docker - printf "$column" 'login-docker' '[user][token]' 'Run Docker login and create docker config.' - printf "$column" 'build-image' '[output]' 'Build Docker image with buildx.' - # Ansible - printf "$column" 'install-ansible-build-scripts' '[role]' 'Install scripts of the specified Ansbile role.' + local -a rows + local max_cmd=7 max_opt=6 max_desc=11 + + rows+=("Command|Option|Description") + rows+=("init-project||Setup a taskfile project in the current directory.") + rows+=("clone-taskfile||Clone the taskfile.build repo.") + rows+=("init-dotenv-dir||Setup task dotenv dir.") + rows+=("template-dotenv||Generate .env from .env.template.") + rows+=("open-with-os||Open file or url with default application.") + rows+=("open-url-with-delay|[url][delay]|Open url after n seconds.") + rows+=("show-dotenv||Show info about the dotenv setup.") + rows+=("ensure-directory|[path]|Ensure directory path exists.") + rows+=("create-symlink|[target][source]|Remove existing file/directory and create symlink.") + rows+=("create-symlink-files|[target][source]|Create symlink for files in source pattern.") + rows+=("activate-venv||Activate or initialize Python virtual env.") + rows+=("remove-venv||Remove the Python virtual env.") + rows+=("create-dotenv|[env][type]|Create env file of type nextcloud, odoo, upgrade.") + rows+=("list-dotenv||List .env files.") + rows+=("show-dotenv|[env]|Output content of the .env file.") + rows+=("copy-dotenv|[env][env]|Copy .env file.") + rows+=("edit-dotenv|[env]|Open env file in default editor.") + rows+=("load-dotenv|[env]|Load and export .env file.") + rows+=("rename-dotenv|[env][env]|Rename .env file.") + rows+=("remove-dotenv|[env]|Remove environment config.") + rows+=("backup-dotenv-files|[path]|Archive and copy .env files to target location.") + rows+=("restore-dotenv-files|[path]|Extract and copy .env files from backup file.") + rows+=("commit-with-llm||Commit with llm generated commit message.") + rows+=("update-with-llm|[glob][prompt]|Feed files matching glob to LLM and apply changes.") + rows+=("log-error||Colored output for errors.") + rows+=("log-success||Colored output for success.") + rows+=("log-warning||Colored output for warnings.") + rows+=("commit-git-folder|[message][path]|Commit all changes in git folders in path.") + rows+=("clean-git-folder||Clean git folder.") + rows+=("ls-git-folder|[path]|Space separated list of git folders in path.") + rows+=("push-git-folder||Push all git folders in path.") + rows+=("reset-git-folder||Abort, rebase and reset git folder.") + rows+=("stage-git-folder|[path]|Stage all files in git folders in path.") + rows+=("status-git-folder|[path]|Show status of git folders in path.") + rows+=("update-submodule||Update git submodules.") + rows+=("save-dotenv-to-pass||Store content of .env in pass entry.") + rows+=("load-dotenv-from-pass||Restore content to .env from pass entry.") + rows+=("save-pass-to-keepass|[pass][entry]|Store password to KeePass entry.") + rows+=("get-pass-from-keepass|[entry]|Get password from KeePass entry.") + rows+=("save-dotenv-to-keepass|[file]|Store content of .env in KeePass entry.") + rows+=("load-dotenv-from-keepass|[file]|Restore content to .env from KeePass entry.") + rows+=("save-kubeconfig-to-pass|[ctx]|Save kubeconfig file in pass.") + rows+=("save-kubeconfig-to-keepass|[ctx]|Save kubeconfig file in KeePass.") + rows+=("load-kubeconfig-from-pass|[ctx]|Load kubeconfig file from pass.") + rows+=("load-kubeconfig-from-keepass|[ctx]|Load kubeconfig file from KeePass.") + rows+=("login-docker|[user][token]|Run Docker login and create docker config.") + rows+=("build-image|[output]|Build Docker image with buildx.") + rows+=("install-ansible-build-scripts|[role]|Install scripts of the specified Ansbile role.") + + for row in "${rows[@]}"; do + IFS='|' read -r cmd opt desc <<< "$row" + (( ${#cmd} > max_cmd )) && max_cmd=${#cmd} + (( ${#opt} > max_opt )) && max_opt=${#opt} + (( ${#desc} > max_desc )) && max_desc=${#desc} + done + + printf '| %-*s | %-*s | %-*s |\n' \ + "$max_cmd" "Command" \ + "$max_opt" "Option" \ + "$max_desc" "Description" + + printf '|-%*s-|-%*s-|-%*s-|\n' \ + "$max_cmd" "$(printf '%*s' "$max_cmd" '' | tr ' ' '-')" \ + "$max_opt" "$(printf '%*s' "$max_opt" '' | tr ' ' '-')" \ + "$max_desc" "$(printf '%*s' "$max_desc" '' | tr ' ' '-')" + + for row in "${rows[@]:1}"; do + IFS='|' read -r cmd opt desc <<< "$row" + printf '| %-*s | %-*s | %-*s |\n' \ + "$max_cmd" "$cmd" \ + "$max_opt" "$opt" \ + "$max_desc" "$desc" + done } help() { diff --git a/usage.md b/usage.md index 296cc52..4ea6e22 100644 --- a/usage.md +++ b/usage.md @@ -80,7 +80,7 @@ The completion also works for task alias `alias t='./task'`. See [taskfile.build/image](/image) for details. -## Default +## Global default Instead of setting up a task file for every ptoject, you can also set up only one with a fallback to the task file in the `$PWD`.