{"id":28227724,"url":"https://github.com/tegonal/scripts","last_synced_at":"2025-06-10T22:32:10.124Z","repository":{"id":37715965,"uuid":"499170646","full_name":"tegonal/scripts","owner":"tegonal","description":"scripts which we use in multiple projects and want to share with you as well","archived":false,"fork":false,"pushed_at":"2025-06-04T13:07:56.000Z","size":2927,"stargazers_count":2,"open_issues_count":3,"forks_count":1,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-06-09T23:15:37.327Z","etag":null,"topics":["bash","hacktoberfest"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tegonal.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE.txt","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2022-06-02T14:34:35.000Z","updated_at":"2025-06-04T13:07:58.000Z","dependencies_parsed_at":"2023-01-19T13:03:03.902Z","dependency_job_id":"c1b4c4ff-dfc0-42cd-b4bd-3dc500ae60a3","html_url":"https://github.com/tegonal/scripts","commit_stats":null,"previous_names":[],"tags_count":66,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tegonal%2Fscripts","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tegonal%2Fscripts/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tegonal%2Fscripts/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tegonal%2Fscripts/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tegonal","download_url":"https://codeload.github.com/tegonal/scripts/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tegonal%2Fscripts/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259163339,"owners_count":22815149,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bash","hacktoberfest"],"created_at":"2025-05-18T13:16:21.981Z","updated_at":"2025-06-10T22:32:10.106Z","avatar_url":"https://github.com/tegonal.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003c!-- for main --\u003e\n\n[![Download](https://img.shields.io/badge/Download-v4.8.1-%23007ec6)](https://github.com/tegonal/scripts/releases/tag/v4.8.1)\n[![Apache 2.0](https://img.shields.io/badge/%E2%9A%96-Apache%202.0-%230b45a6)](http://opensource.org/licenses/Apache2.0 \"License\")\n[![Quality Assurance](https://github.com/tegonal/scripts/actions/workflows/quality-assurance.yml/badge.svg?event=push\u0026branch=main)](https://github.com/tegonal/scripts/actions/workflows/quality-assurance.yml?query=branch%3Amain)\n[![Newcomers Welcome](https://img.shields.io/badge/%F0%9F%91%8B-Newcomers%20Welcome-blueviolet)](https://github.com/tegonal/scripts/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22 \"Ask in discussions for help\")\n\n\u003c!-- for main end --\u003e\n\u003c!-- for release --\u003e\n\u003c!--\n[![Download](https://img.shields.io/badge/Download-v4.8.1-%23007ec6)](https://github.com/tegonal/scripts/releases/tag/v4.8.1)\n[![Apache 2.0](https://img.shields.io/badge/%E2%9A%96-Apache%202.0-%230b45a6)](http://opensource.org/licenses/Apache2.0 \"License\")\n[![Newcomers Welcome](https://img.shields.io/badge/%F0%9F%91%8B-Newcomers%20Welcome-blueviolet)](https://github.com/tegonal/scripts/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22 \"Ask in discussions for help\")\n--\u003e\n\u003c!-- for release end --\u003e\n\n# Scripts of Tegonal\n\nThere are scripts which we use over and over again in different projects.\nAs they might be usable for you as well, we are publishing them here.\nFeel free to use it and report bugs if you should find one.\n\n---\n❗ You are taking a *sneak peek* at the next version. It could be that some features you find on this page are not\nreleased yet.  \nPlease have a look at the README of the corresponding release/git tag. Latest\nversion: [README of v4.8.1](https://github.com/tegonal/scripts/tree/v4.8.1/README.md).\n\n---\n\n**Table of Content**\n\n- [Installation](#Installation)\n- [Documentation](#documentation)\n- [Contributors and contribute](#contributors-and-contribute)\n- [License](#license)\n\n# Installation\n\nWe recommend you pull the scripts with the help of [gt](https://github.com/tegonal/gt).  \nAlternatively you can\n[![Download](https://img.shields.io/badge/Download-v4.8.1-%23007ec6)](https://github.com/tegonal/scripts/releases/tag/v4.8.1)\nthe sources.\n\nFollowing the commands you need to execute to set up tegonal scripts via [gt](https://github.com/tegonal/gt).\n\n```bash\ngt remote add -r tegonal-scripts -u https://github.com/tegonal/scripts\n````\n\nNow you can pull the scripts you want in the latest version via:\n```bash\ngt pull -r tegonal-scripts -p ...\n````\n\nOr specify a version via `-t` as follows:\n```bash\nexport TEGONAL_SCRIPTS_VERSION=\"v4.8.1\"\ngt pull -r tegonal-scripts -t \"$TEGONAL_SCRIPTS_VERSION\" -p ...\n```\n\nNote that dependencies have to be pulled manually and almost all scripts depend on `src/setup.sh`\nwhich in turn depends on `src/utility/source-once.sh` and this one depends on `src/utility/log.sh`.\nMany of the scripts depend on further scripts located in `src/utility`.\nTherefore, for simplicity reasons, we recommend you pull `src/setup.sh` and all files in `src/utility` in addition:\n\n```\nexport TEGONAL_SCRIPTS_VERSION=\"v4.8.1\" \ngt pull -r tegonal-scripts -t \"$TEGONAL_SCRIPTS_VERSION\" -p src/setup.sh\ngt pull -r tegonal-scripts -t \"$TEGONAL_SCRIPTS_VERSION\" -p src/utility/\n```\n\n## Sourcing functions\n\nWe recommend you use the following code at the beginning of your script in case you want to `source` a file/function\n(in the example below we want to use tegonal's io functions located in `utility/io.sh`):\n\n\u003csetup\u003e\n\n\u003c!-- auto-generated, do not modify here but in src/setup.sh.doc --\u003e\n```bash\n#!/usr/bin/env bash\nset -euo pipefail\nshopt -s inherit_errexit || { echo \u003e\u00262 \"please update to bash 5, see errors above\" \u0026\u0026 exit 1; }\n\nif ! [[ -v dir_of_tegonal_scripts ]]; then\n\t# Assumes your script is in (root is project folder) e.g. /src or /scripts and\n\t# the tegonal scripts have been pulled via gt and put into /lib/tegonal-scripts\n\tdir_of_tegonal_scripts=\"$(cd -- \"$(dirname -- \"${BASH_SOURCE[0]:-$0}\")\" \u003e/dev/null \u0026\u0026 pwd 2\u003e/dev/null)/../lib/tegonal-scripts/src\"\n\tsource \"$dir_of_tegonal_scripts/setup.sh\" \"$dir_of_tegonal_scripts\"\nfi\n\nsourceOnce \"$dir_of_tegonal_scripts/utility/io.sh\"\n```\n\n\u003c/setup\u003e\n\nNote that `source \"$dir_of_tegonal_scripts/setup.sh\"` will automatically source `utility/source-once.sh`\nand `utility/log.sh`\n\n# Documentation\n\nThe scripts are ordered by topic:\n\n- [CI](#continuous-integration)\n\t- [install shellcheck](#install-shellcheck)\n\t- [install shellspec](#install-shellspec)\n\t- [Jelastic](#jelastic)\n\t\t- [deploy](#deploy-to-jelastic)\n\t\t- [utils](#jelastic-utils)\n- [Quality Assurance](#quality-assurance)\n\t- [runShellcheck](#runshellcheck)\n    - [runShellcheckPullHooks](#runshellcheck-on-pull-hookssh)\n    - [runShellspecIfInstalled](#runshellspecifinstalled)\n- [Releasing](#releasing)\n\t- [Releasing Files](#release-files)\n\t- [Prepare Files Next Dev Cycle](#prepare-files-next-dev-cycle)\n\t- [Release Template](#release-template)\n    - [Prepare Next Dev Cycle Template](#prepare-next-dev-cycle-template)\n\t- [git Pre-Release checks](#git-pre-release-checks)\n    - [sbt sonatype publish](#sbt-sonatype-publish)\n\t- [Update Version common steps](#update-version-common-steps)\n\t- [Update Version in README](#update-version-in-readme)\n\t- [Update Version in bash scripts](#update-version-in-bash-scripts)\n\t- [Update Version in issue templates](#update-version-in-issue-templates)\n\t- [Toggle main/release sections](#toggle-mainrelease-sections)\n\t- [Hide/Show sneak-peek banner](#hideshow-sneak-peek-banner)\n\n- [Script Utilities](#script-utilities)\n\t- [array utils](#array-utils)\n\t- [Ask functions](#ask-functions)\n    - [cleanups](#cleanups)\n\t- [Checks](#checks)\n    - [date utils](#date-utils)\n\t- [git utils](#git-utils)\n\t- [GPG Utils](#gpg-utils)\n\t- [Http functions](#http-functions)\n\t- [IO functions](#io-functions)\n\t- [Log functions](#log-functions)\n\t- [Parse arguments](#parse-arguments)\n\t- [Parse utils](#parse-utils)\n\t- [Recursive `declare -p`](#recursive-declare--p)\n\t- [Replace Snippets](#replace-snippets)\n\t- [Secret utils](#secret-utils)\n\t- [`source` once](#source-once)\n    - [string utils](#string-utils)\n\t- [Update Documentation](#update-bash-documentation)\n\n# Continuous Integration\n\nThe scripts under this topic (in directory `ci`) help out in performing CI steps.\n\n## Install shellcheck\n\nInstalls shellcheck. Most likely, you want to use it together with [runShellcheck](#runshellcheck).\nFollowing an example:\n\n\u003cci-install-shellcheck\u003e\n\n\u003c!-- auto-generated, do not modify here but in src/ci/install-shellcheck.sh.doc --\u003e\n```bash\n# run the install-shellcheck.sh in your github/gitlab workflow\n# for instance, assuming you fetched this file via gt and remote name is tegonal-scripts\n# then in a github workflow you would have\n\njobs:\n  steps:\n    - name: install shellcheck\n      run: ./lib/tegonal-scripts/src/ci/install-shellcheck.sh\n    # and most likely as well\n    - name: run shellcheck\n      run: ./scripts/run-shellcheck.sh\n```\n\n\u003c/ci-install-shellcheck\u003e\n\n## Install shellspec\n\n\u003cci-install-shellspec\u003e\n\n\u003c!-- auto-generated, do not modify here but in src/ci/install-shellspec.sh.doc --\u003e\n```bash\n# run the install-shellspec in your github/gitlab workflow\n# for instance, assuming you fetched this file via gt and remote name is tegonal-scripts\n# then in a github workflow you would have\n\njobs:\n  steps:\n    - name: install shellspec\n      run: ./lib/tegonal-scripts/src/ci/install-shellspec.sh\n    # and most likely as well\n    - name: run shellspec\n      run: shellspec\n```\n\n\u003c/ci-install-shellspec\u003e\n\n## Jelastic\n\nThe scripts under this topic (in directory `ci/jelastic`) help out when dealing with jelastic cli\n\n### Deploy to jelastic\n\nHelper function which performs a signin and redeploycontainers\n\n\u003cci-jelastic-deploy\u003e\n\n\u003c!-- auto-generated, do not modify here but in src/ci/jelastic/deploy.sh.doc --\u003e\n```bash\n#!/usr/bin/env bash\nset -euo pipefail\nshopt -s inherit_errexit || { echo \u003e\u00262 \"please update to bash 5, see errors above\" \u0026\u0026 exit 1; }\n# Assumes tegonal's scripts were fetched with gt - adjust location accordingly\ndir_of_tegonal_scripts=\"$(cd -- \"$(dirname -- \"${BASH_SOURCE[0]:-$0}\")\" \u003e/dev/null \u0026\u0026 pwd 2\u003e/dev/null)/../lib/tegonal-scripts/src\"\nsource \"$dir_of_tegonal_scripts/setup.sh\" \"$dir_of_tegonal_scripts\"\n\n# typically you would define those via secrets (GitHub) or Variables (Gitlab)\nJELASTIC_LOGIN='my-user'\nJELASTIC_PASSWORD='access-token'\nJELASTIC_PLATFORM_URL='https://...'\n\n# the label of the docker image as pushed to the docker registry configured for the environment test\nDOCKER_IMAGE_VERSION=bebea131\n\n# executes signin and redeploycontainers via jelastic_cli\n\"$dir_of_tegonal_scripts/ci/jelastic/deploy.sh\" -l \"$JELASTIC_LOGIN\" -p \"$JELASTIC_PASSWORD\" -u \"$JELASTIC_PLATFORM_URL\" -e \"test\" -n cp -t \"$DOCKER_IMAGE_VERSION\"\n\n# you can also source\nsourceOnce \"$dir_of_tegonal_scripts/ci/jelastic/deploy.sh\"\njelastic_deploy -l \"$JELASTIC_LOGIN\" -p \"$JELASTIC_PASSWORD\" -u \"$JELASTIC_PLATFORM_URL\" -e \"test\" -n cp -t \"$DOCKER_IMAGE_VERSION\"\n```\n\n\u003c/ci-jelastic-deploy\u003e\n\nIn a GitHub workflow you would use it as follows:\n\n```yaml\njobs:\n  steps:\n    - name: deploy shellcheck v0.8.0\n      run: |\n        ./lib/tegonal-scripts/src/ci/jelastic/deploy.sh \\\n          -l \"$JELASTIC_LOGIN\" -p \"$JELASTIC_PASSWORD\" -u \"$JELASTIC_PLATFORM_URL\" \\\n          -e \"test\" -n cp \\\n          -t \"$DOCKER_IMAGE_VERSION\"\n```\n\nHelp:\n\n\u003cci-jelastic-deploy-help\u003e\n\n\u003c!-- auto-generated, do not modify here but in src/ci/jelastic/deploy.sh --\u003e\n```text\nParameters:\n-l|--login       The user who logs in\n-p|--password    The access token of the user\n-u|--url         The platformUrl to the jelastic instance\n-e|--env         The environment to use\n-n|--nodeGroup   The nodeGroup to use\n-t|--tag         The tag which shall be deployed\n\n--help     prints this help\n--version  prints the version of this script\n\nINFO: Version of deploy.sh is:\nv4.9.0-SNAPSHOT\n```\n\n\u003c/ci-jelastic-deploy-help\u003e\n\n### Jelastic utils\n\nThe most important functions are defined in this file: jelastic_signin which in turn uses the generic jelastic_exec\n\n\u003cci-jelastic-utils\u003e\n\n\u003c!-- auto-generated, do not modify here but in src/ci/jelastic/utils.sh.doc --\u003e\n```bash\n#!/usr/bin/env bash\nset -euo pipefail\nshopt -s inherit_errexit || { echo \u003e\u00262 \"please update to bash 5, see errors above\" \u0026\u0026 exit 1; }\n# Assumes tegonal's scripts were fetched with gt - adjust location accordingly\ndir_of_tegonal_scripts=\"$(cd -- \"$(dirname -- \"${BASH_SOURCE[0]:-$0}\")\" \u003e/dev/null \u0026\u0026 pwd 2\u003e/dev/null)/../lib/tegonal-scripts/src\"\nsource \"$dir_of_tegonal_scripts/setup.sh\" \"$dir_of_tegonal_scripts\"\n\nsourceOnce \"$dir_of_tegonal_scripts/ci/jelastic/jelastic-utils.sh\"\n\n# typically you would define those via secrets (GitHub) or Variables (Gitlab)\nJELASTIC_LOGIN='my-user'\nJELASTIC_PASSWORD='access-token'\nJELASTIC_PLATFORM_URL='https://...'\n\n# before doing anything with jelastic cli, you need to signin\n# this is just a helper function you could also use jelastic_exec and pass users/authentication/signin as command\njelastic_signin \"$JELASTIC_PLATFORM_URL\" \"$JELASTIC_LOGIN\" \"$JELASTIC_PASSWORD\"\n\n# generic utility which executes the jelastic_cli with the corresponding command and args but,\n# in contrast to the cli, it checks whether the response contained `result: 0` or not\njelastic_exec \"environment/control/redeploycontainers\" --envName \"test\" --nodeGroup \"cp\" --tag \"a123e2\"\n```\n\n\u003c/ci-jelastic-utils\u003e\n\n# Quality Assurance\n\nThe scripts under this topic (in directory `qa`) perform checks or execute qa tools.\n\n## runShellcheck\n\nA function which expects the name of an array of dirs as first argument and a source path as second argument (which is\npassed to shellcheck via -P parameter). It then executes shellcheck for each *.sh in these directories with predefined\nsettings for shellcheck.\n\n\u003cqa-run-shellcheck\u003e\n\n\u003c!-- auto-generated, do not modify here but in src/qa/run-shellcheck.sh.doc --\u003e\n```bash\n#!/usr/bin/env bash\nset -euo pipefail\nshopt -s inherit_errexit || { echo \u003e\u00262 \"please update to bash 5, see errors above\" \u0026\u0026 exit 1; }\n# Assumes tegonal's scripts were fetched with gt - adjust location accordingly\ndir_of_tegonal_scripts=\"$(cd -- \"$(dirname -- \"${BASH_SOURCE[0]:-$0}\")\" \u003e/dev/null \u0026\u0026 pwd 2\u003e/dev/null)/../lib/tegonal-scripts/src\"\nsource \"$dir_of_tegonal_scripts/setup.sh\" \"$dir_of_tegonal_scripts\"\n\nsource \"$dir_of_tegonal_scripts/qa/run-shellcheck.sh\"\n\n# shellcheck disable=SC2034   # is passed by name to runShellcheck\ndeclare -a dirs=(\n\t\"$dir_of_tegonal_scripts\"\n\t\"$dir_of_tegonal_scripts/../scripts\"\n\t\"$dir_of_tegonal_scripts/../spec\"\n)\ndeclare sourcePath=\"$dir_of_tegonal_scripts\"\nrunShellcheck dirs \"$sourcePath\"\n\n# pass the working directory of gt which usually is .gt in the root of your repository\n# this will run shellcheck on all pull-hook.sh files\nrunShellcheckPullHooks \".gt\"\n```\n\n\u003c/qa-run-shellcheck\u003e\n\n## runShellCheck on pull-hooks.sh\n\n*Deprecated*, source `run-shellcheck.sh` instead of `run-shellcheck-pull-hooks.sh` which now includes \n`runShellcheckPullHooks` as well.\n\n## runShellSpecIfInstalled\n\nUtility function which checks if shellspec is installed and if so executes it and prints a warning otherwise.\nIntended to be used in before-pr.sh where contributors shall not be forced to have shellspec installed\n\n\u003cqa-run-shellspec-if-installed\u003e\n\n\u003c!-- auto-generated, do not modify here but in src/qa/run-shellspec-if-installed.sh.doc --\u003e\n```bash\n#!/usr/bin/env bash\nset -euo pipefail\nshopt -s inherit_errexit || { echo \u003e\u00262 \"please update to bash 5, see errors above\" \u0026\u0026 exit 1; }\n# Assumes tegonal's scripts were fetched with gt - adjust location accordingly\ndir_of_tegonal_scripts=\"$(cd -- \"$(dirname -- \"${BASH_SOURCE[0]:-$0}\")\" \u003e/dev/null \u0026\u0026 pwd 2\u003e/dev/null)/../lib/tegonal-scripts/src\"\nsource \"$dir_of_tegonal_scripts/setup.sh\" \"$dir_of_tegonal_scripts\"\n\nsource \"$dir_of_tegonal_scripts/qa/run-shellspec-if-installed.sh\"\n\nrunShellspecIfInstalled\n\n# you can also pass arguments to shellspec\nrunShellspecIfInstalled --jobs 2\n```\n\n\u003c/qa-run-shellspec-if-installed\u003e\n\n# Releasing\n\nThe scripts under this topic (in directory `releasing`) perform some steps of your release process.\n\n## Release Files\n\nScript which releases a version for a repository containing files which don't need to be compiled or packaged.\nInstead, they will be signed by a specified gpg key where its public key, defined in .gt/signing-key.public.asc,\nwill be used to verify the signatures.\n\nThis script is useful if you want to release e.g. scripts which can then be fetched\nvia [gt](https://github.com/tegonal/gt).\n\nIt uses [release-template](#release-template) internally and thus applies the same conventions + the mentioned public\nkey\nwhich needs to be defined in .gt/signing-key.public.asc\n\nIt executes the same steps as in release-template where scripts located in projectRootDir/src are also updated\nregarding the version and as explained, in the releaseHook, it signs the files the given --sign-fn finds.\n\nHelp:\n\n\u003creleasing-release-files-help\u003e\n\n\u003c!-- auto-generated, do not modify here but in src/releasing/release-files.sh --\u003e\n```text\nParameters:\n-v                            The version to release in the format vX.Y.Z(-RC...)\n-k|key                        The GPG private key which shall be used to sign the files\n--sign-fn                     Function which is called to determine what files should be signed. It should be based find and allow to pass further arguments (we will i.a. pass -print0)\n-b|--branch                   (optional) The expected branch which is currently checked out -- default: main\n--project-dir                 (optional) The projects directory -- default: .\n-p|--pattern                  (optional) pattern which is used in a perl command (separator /) to search \u0026 replace additional occurrences. It should define two match groups and the replace operation looks as follows: \\${1}$version\\${2}\n-nv|--next-version            (optional) the version to use for prepare-next-dev-cycle -- default: is next minor based on version\n--prepare-only                (optional) defines whether the release shall only be prepared (i.e. no push, no tag, no prepare-next-dev-cycle) -- default: false\n--before-pr-fn                (optional) defines the function which is executed before preparing the release (to see if we should release) and after preparing the release -- default: beforePr (per convention defined in scripts/before-pr.sh). No arguments are passed\n--prepare-next-dev-cycle-fn   (optional) defines the function which is executed to prepare the next dev cycle -- default: perpareNextDevCycle (per convention defined in scripts/prepareNextDevCycle). The following arguments are passed: -v nextVersion --pattern additionalPattern --project-dir projectsRootDir --before-pr-fn beforePrFn\n--after-version-update-hook   (optional) if defined, then this function is called after versions were updated and before calling beforePr. The following arguments are passed: -v version --project-dir projectsRootDir and --pattern additionalPattern\n\n--help     prints this help\n--version  prints the version of this script\n\nINFO: Version of release-files.sh is:\nv4.9.0-SNAPSHOT\n```\n\n\u003c/releasing-release-files-help\u003e\n\nFull usage example:\n\n\u003creleasing-release-files\u003e\n\n\u003c!-- auto-generated, do not modify here but in src/releasing/release-files.sh.doc --\u003e\n```bash\n#!/usr/bin/env bash\nset -euo pipefail\nshopt -s inherit_errexit || { echo \u003e\u00262 \"please update to bash 5, see errors above\" \u0026\u0026 exit 1; }\n# Assumes tegonal's scripts were fetched with gt - adjust location accordingly\ndir_of_tegonal_scripts=\"$(cd -- \"$(dirname -- \"${BASH_SOURCE[0]:-$0}\")\" \u003e/dev/null \u0026\u0026 pwd 2\u003e/dev/null)/../lib/tegonal-scripts/src\"\nsource \"$dir_of_tegonal_scripts/setup.sh\" \"$dir_of_tegonal_scripts\"\n\nscriptsDir=\"$(cd -- \"$(dirname -- \"${BASH_SOURCE[0]:-$0}\")\" \u003e/dev/null \u0026\u0026 pwd 2\u003e/dev/null)\"\nsourceOnce \"$scriptsDir/before-pr.sh\"\n\nfunction findScripts() {\n\tfind \"src\" -name \"*.sh\" -not -name \"*.doc.sh\" \"$@\"\n}\n# make the function visible to release-files.sh / not necessary if you source release-files.sh, see further below\ndeclare -fx findScripts\n\n# releases version v0.1.0 using the key 0x945FE615904E5C85 for signing and function findScripts to find the files which\n# should be signed (and thus released). Assumes that a function named beforePr is in scope (which we sourced above)\n\"$dir_of_tegonal_scripts/releasing/release-files.sh\" -v v0.1.0 -k \"0x945FE615904E5C85\" --sign-fn findScripts\n\n# releases version v0.1.0 using the key 0x945FE615904E5C85 for signing and function findScripts to find the files which\n ## should be signed (and thus released). Moreover, searches for additional occurrences where the version should be\n# replaced via the specified pattern\n\"$dir_of_tegonal_scripts/releasing/release-files.sh\" \\\n\t-v v0.1.0 -k \"0x945FE615904E5C85\" --sign-fn findScripts \\\n\t-p \"(TEGONAL_SCRIPTS_VERSION=['\\\"])[^'\\\"]+(['\\\"])\"\n\nfunction specialBeforePr(){\n\tbeforePr \u0026\u0026 echo \"imagine some additional work\"\n}\n# make the function visible to release-files.sh / not necessary if you source prepare-files-next-dev-cycle.sh\n# see further below\ndeclare -fx specialBeforePr\n\n# releases version v0.1.0 using the key 0x945FE615904E5C85 for signing and\n\"$dir_of_tegonal_scripts/releasing/release-files.sh\" \\\n\t-v v0.1.0 -k \"0x945FE615904E5C85\" --sign-fn findScripts \\\n\t--before-pr-fn specialBeforePr\n\n\n# in case you want to provide your own release.sh and only want to do some pre-configuration\n# then you might want to source it instead\nsourceOnce \"$dir_of_tegonal_scripts/releasing/release-files.sh\"\n\n# and then call the function with your pre-configuration settings:\n# here we define the function which shall be used to find the files to be signed\n# since \"$@\" follows afterwards, one could still override it via command line arguments.\n# put \"$@\" first, if you don't want that a user can override your pre-configuration\nreleaseFiles --sign-fn findScripts \"$@\"\n\n# call the function define --before-pr-fn, don't allow to override via command line arguments\nreleaseFiles \"$@\" --before-pr-fn specialBeforePr\n```\n\n\u003c/releasing-release-files\u003e\n\n## Prepare Files Next Dev Cycle\n\nScript which prepares files for a next development cycle (typically used together with [release files](#release-files)).\nit uses the [prepare next dev cycle template](#prepare-next-dev-cycle-template) and thus is based on the same conventions.\n\n\u003creleasing-prepare-files-next-dev-cycle-help\u003e\n\n\u003c!-- auto-generated, do not modify here but in src/releasing/prepare-files-next-dev-cycle.sh --\u003e\n```text\nParameters:\n-v                            the version for which we prepare the dev cycle\n--project-dir                 (optional) The projects directory -- default: .\n-p|--pattern                  (optional) pattern which is used in a perl command (separator /) to search \u0026 replace additional occurrences. It should define two match groups and the replace operation looks as follows: \\${1}$version\\${2}\n--before-pr-fn                (optional) defines the function which is executed before preparing the release (to see if we should release) and after preparing the release -- default: beforePr (per convention defined in scripts/before-pr.sh). No arguments are passed\n--after-version-update-hook   (optional) if defined, then this function is called after versions were updated and before calling beforePr. The following arguments are passed: -v version --project-dir projectsRootDir and --pattern additionalPattern\n\n--help     prints this help\n--version  prints the version of this script\n\nINFO: Version of prepare-files-next-dev-cycle.sh is:\nv4.9.0-SNAPSHOT\n```\n\n\u003c/releasing-prepare-files-next-dev-cycle-help\u003e\n\nFull usage example:\n\n\u003creleasing-prepare-files-next-dev-cycle\u003e\n\n\u003c!-- auto-generated, do not modify here but in src/releasing/prepare-files-next-dev-cycle.sh.doc --\u003e\n```bash\n#!/usr/bin/env bash\nset -euo pipefail\nshopt -s inherit_errexit || { echo \u003e\u00262 \"please update to bash 5, see errors above\" \u0026\u0026 exit 1; }\n# Assumes tegonal's scripts were fetched with gt - adjust location accordingly\ndir_of_tegonal_scripts=\"$(cd -- \"$(dirname -- \"${BASH_SOURCE[0]:-$0}\")\" \u003e/dev/null \u0026\u0026 pwd 2\u003e/dev/null)/../lib/tegonal-scripts/src\"\nsource \"$dir_of_tegonal_scripts/setup.sh\" \"$dir_of_tegonal_scripts\"\n\nscriptsDir=\"$(cd -- \"$(dirname -- \"${BASH_SOURCE[0]:-$0}\")\" \u003e/dev/null \u0026\u0026 pwd 2\u003e/dev/null)\"\nsourceOnce \"$scriptsDir/before-pr.sh\"\n\n# prepare dev cycle for version v0.2.0, assumes a function beforePr is in scope which we sourced above\n\"$dir_of_tegonal_scripts/releasing/prepare-files-next-dev-cycle.sh\" -v v0.2.0\n\nfunction specialBeforePr(){\n\tbeforePr \u0026\u0026 echo \"imagine some additional work\"\n}\n# make the function visible to release-files.sh / not necessary if you source prepare-files-next-dev-cycle.sh, see further below\ndeclare -fx specialBeforePr\n\n# prepare dev cycle for version v0.2.0 and\n# searches for additional occurrences where the version should be replaced via the specified pattern in:\n# - script files in ./src and ./scripts\n# - ./README.md\n# uses specialBeforePr instead of beforePr\n\"$dir_of_tegonal_scripts/releasing/prepare-files-next-dev-cycle.sh\" -v v0.2.0 \\\n\t-p \"(TEGONAL_SCRIPTS_VERSION=['\\\"])[^'\\\"]+(['\\\"])\" \\\n\t--before-pr-fn specialBeforePr\n\n# in case you want to provide your own release.sh and only want to do some pre-configuration\n# then you might want to source it instead\nsourceOnce \"$dir_of_tegonal_scripts/releasing/prepare-files-next-dev-cycle.sh\"\n\n# and then call the function with your pre-configuration settings:\n# here we define the pattern which shall be used to replace further version occurrences\n# since \"$@\" follows afterwards, one could still override it via command line arguments.\n# put \"$@\" first, if you don't want that a user can override your pre-configuration\nprepareNextDevCycle -p \"(TEGONAL_SCRIPTS_VERSION=['\\\"])[^'\\\"]+(['\\\"])\" \"$@\"\n\n# call the function define --before-pr-fn, don't allow to override via command line arguments\nprepareNextDevCycle \"$@\" --before-pr-fn specialBeforePr\n```\n\n\u003c/releasing-prepare-files-next-dev-cycle\u003e\n\n## Release Template\n\nDefines a release process template where some conventions are defined:\n\n- expects a version in format vX.Y.Z(-RC...)\n- main is your default branch (or you use --branch to define another)\n- requires you to have a function beforePr in scope (or you define another one via --before-pr-fn)\n- requires you to have a function prepareNextDevCycle in scope (or you define another one via\n  --prepare-next-dev-cycle-fn)\n\nIt then executes the following steps:\n\n\n- [git pre-release checks](#git-pre-release-checks)\n- check `beforePrFn` can be executed without problems\n- [update version common release steps](#update-version-common-release-steps)\n- call the afterVersionUpdateHook if defined\n-  check again `beforePrFn`  is not broken\n- call the releaseHook\n- commit changes, create tag\n- execute `prepareNextDevCycleFn` (which typically creates a commit as well)\n- push tag and commits\n\n\nHelp:\n\n\u003creleasing-release-template-help\u003e\n\n\u003c!-- auto-generated, do not modify here but in src/releasing/release-template.sh --\u003e\n```text\nParameters:\n-v                            The version to release in the format vX.Y.Z(-RC...)\n--release-hook                performs the main release task such as (run tests) create artifacts, deploy artifacts\n-b|--branch                   (optional) The expected branch which is currently checked out -- default: main\n--project-dir                 (optional) The projects directory -- default: .\n-p|--pattern                  (optional) pattern which is used in a perl command (separator /) to search \u0026 replace additional occurrences. It should define two match groups and the replace operation looks as follows: \\${1}$version\\${2}\n-nv|--next-version            (optional) the version to use for prepare-next-dev-cycle -- default: is next minor based on version\n--prepare-only                (optional) defines whether the release shall only be prepared (i.e. no push, no tag, no prepare-next-dev-cycle) -- default: false\n--before-pr-fn                (optional) defines the function which is executed before preparing the release (to see if we should release) and after preparing the release -- default: beforePr (per convention defined in scripts/before-pr.sh). No arguments are passed\n--prepare-next-dev-cycle-fn   (optional) defines the function which is executed to prepare the next dev cycle -- default: perpareNextDevCycle (per convention defined in scripts/prepareNextDevCycle). The following arguments are passed: -v nextVersion --pattern additionalPattern --project-dir projectsRootDir --before-pr-fn beforePrFn\n--after-version-update-hook   (optional) if defined, then this function is called after versions were updated and before calling beforePr. The following arguments are passed: -v version --project-dir projectsRootDir and --pattern additionalPattern\n\n--help     prints this help\n--version  prints the version of this script\n\nINFO: Version of release-template.sh is:\nv4.9.0-SNAPSHOT\n```\n\n\u003c/releasing-release-template-help\u003e\n\nFull example:\n\n\u003creleasing-release-template\u003e\n\n\u003c!-- auto-generated, do not modify here but in src/releasing/release-template.sh.doc --\u003e\n```bash\n#!/usr/bin/env bash\nset -euo pipefail\nshopt -s inherit_errexit || { echo \u003e\u00262 \"please update to bash 5, see errors above\" \u0026\u0026 exit 1; }\n# Assumes tegonal's scripts were fetched with gt - adjust location accordingly\ndir_of_tegonal_scripts=\"$(cd -- \"$(dirname -- \"${BASH_SOURCE[0]:-$0}\")\" \u003e/dev/null \u0026\u0026 pwd 2\u003e/dev/null)/../lib/tegonal-scripts/src\"\nsource \"$dir_of_tegonal_scripts/setup.sh\" \"$dir_of_tegonal_scripts\"\n\nfunction releaseScalaLib() {\n\tsbt publishSigned\n\t# or\n\tsbt test publishedSigned\n}\n# make the function visible to release-templates.sh / not necessary if you source release-templates.sh, see further below\ndeclare -fx releaseScalaLib\n\n# releases version v0.1.0 using releaseScalaLib as hook\n\"$dir_of_tegonal_scripts/releasing/release-template.sh\" \\\n\t-v v0.1.0 -k \"0x945FE615904E5C85\" --release-hook releaseScalaLib\n\n# releases version v0.1.0 using releaseScalaLib as hook and\n# searches for additional occurrences where the version should be replaced via the specified pattern in:\n# - script files in ./src and ./scripts\n# - ./README.md\n\"$dir_of_tegonal_scripts/releasing/release-template.sh\" \\\n\t-v v0.1.0 -k \"0x945FE615904E5C85\" --release-hook releaseScalaLib \\\n\t-p \"(TEGONAL_SCRIPTS_VERSION=['\\\"])[^'\\\"]+(['\\\"])\"\n\n# in case you want to provide your own release.sh and only want to do some pre-configuration\n# (such as specify the release-hook) then you might want to source it instead\nsourceOnce \"$dir_of_tegonal_scripts/releasing/release-template.sh\"\n\n# and then call the function with your pre-configuration settings:\n# here we define the function which shall be used as release-hook after \"$@\" this way one cannot override it.\n# put --release-hook before \"$@\" if you want to define only a default\nreleaseTemplates \"$@\" --release-hook releaseScalaLib\n\nfunction releaseScalaLib_afterVersionUpdateHook() {\n\t# some additional version bumps (assuming version is in scope)\n\tlocal version\n\tperl -0777 -i -pe \"s/.../$version/g\" \"build.sbt\"\n}\n\n# and then call the function with your pre-configuration settings:\n# here we define the function which shall be used as release-hook after \"$@\" this way one cannot override it.\n# put --release-hook before \"$@\" if you want to define only a default\nreleaseTemplate \"$@\" --release-hook releaseScalaLib \\\n\t--after-version-update-hook releaseScalaLib_afterVersionUpdateHook\n```\n\n\u003c/releasing-release-template\u003e\n\n## Prepare next dev cycle template\n\ntemplate to prepare a next releases, updating version and such using [update-version-common-steps.sh](#update-version-common-release-steps)\n\nHelp:\n\n\u003creleasing-prepare-next-dev-cycle-template-help\u003e\n\n\u003c!-- auto-generated, do not modify here but in src/releasing/prepare-next-dev-cycle-template.sh --\u003e\n```text\nParameters:\n-v                            the version for which we prepare the dev cycle\n--project-dir                 (optional) The projects directory -- default: .\n-p|--pattern                  (optional) pattern which is used in a perl command (separator /) to search \u0026 replace additional occurrences. It should define two match groups and the replace operation looks as follows: \\${1}$version\\${2}\n--before-pr-fn                (optional) defines the function which is executed before preparing the release (to see if we should release) and after preparing the release -- default: beforePr (per convention defined in scripts/before-pr.sh). No arguments are passed\n--after-version-update-hook   (optional) if defined, then this function is called after versions were updated and before calling beforePr. The following arguments are passed: -v version --project-dir projectsRootDir and --pattern additionalPattern\n\n--help     prints this help\n--version  prints the version of this script\n\nINFO: Version of prepare-next-dev-cycle-template.sh is:\nv4.9.0-SNAPSHOT\n```\n\n\u003c/releasing-prepare-next-dev-cycle-template-help\u003e\n\n\nFull example:\n\n\u003creleasing-prepare-next-dev-cycle-template\u003e\n\n\u003c!-- auto-generated, do not modify here but in src/releasing/prepare-next-dev-cycle-template.sh.doc --\u003e\n```bash\n#!/usr/bin/env bash\nset -euo pipefail\nshopt -s inherit_errexit || { echo \u003e\u00262 \"please update to bash 5, see errors above\" \u0026\u0026 exit 1; }\n# Assumes tegonal's scripts were fetched with gt - adjust location accordingly\ndir_of_tegonal_scripts=\"$(cd -- \"$(dirname -- \"${BASH_SOURCE[0]:-$0}\")\" \u003e/dev/null \u0026\u0026 pwd 2\u003e/dev/null)/../lib/tegonal-scripts/src\"\nsource \"$dir_of_tegonal_scripts/setup.sh\" \"$dir_of_tegonal_scripts\"\n\n\nfunction prepareNextAfterVersionUpdateHook() {\n\t# some additional version bumps e.g. using perl\n\tperl -0777 -i #...\n}\n# make the function visible to release-templates.sh / not necessary if you source release-templates.sh, see further below\ndeclare -fx releaseScalaLib\n\n# releases version v0.1.0 using releaseScalaLib as hook\n\"$dir_of_tegonal_scripts/releasing/release-template.sh\" \\\n\t-v v0.1.0 -k \"0x945FE615904E5C85\" --release-hook releaseScalaLib\n\n# releases version v0.1.0 using releaseScalaLib as hook and\n# searches for additional occurrences where the version should be replaced via the specified pattern in:\n# - script files in ./src and ./scripts\n# - ./README.md\n\"$dir_of_tegonal_scripts/releasing/release-files.sh\" \\\n\t-v v0.1.0 -k \"0x945FE615904E5C85\" --release-hook releaseScalaLib \\\n\t-p \"(TEGONAL_SCRIPTS_VERSION=['\\\"])[^'\\\"]+(['\\\"])\"\n\n# in case you want to provide your own release.sh and only want to do some pre-configuration\n# (such as specify the release-hook) then you might want to source it instead\nsourceOnce \"$dir_of_tegonal_scripts/releasing/release-template.sh\"\n\n# and then call the function with your pre-configuration settings:\n# here we define the function which shall be used as release-hook after \"$@\" this way one cannot override it.\n# put --release-hook before \"$@\" if you want to define only a default\nreleaseTemplates \"$@\" --release-hook releaseScalaLib\n```\n\n\u003c/releasing-prepare-next-dev-cycle-template\u003e\n\n## git Pre-Release checks\n\nchecks if the repo is ready to be released for a given version\n\n- expects a version in format vX.Y.Z(-RC...)\n- you are currently on `main` (or use `--branch` to define a different expected branch)\n- your branch is up-to-date with `origin`\n\nit assists you in pulling/rebasing etc. in case you are on the wrong branch or behind origin.\n\nHelp:\n\n\u003creleasing-pre-release-checks-git-help\u003e\n\n\u003c!-- auto-generated, do not modify here but in src/releasing/pre-release-checks-git.sh --\u003e\n```text\nParameters:\n-v            The version to release in the format vX.Y.Z(-RC...)\n-b|--branch   (optional) The expected branch which is currently checked out -- default: main\n\n--help     prints this help\n--version  prints the version of this script\n\nINFO: Version of pre-release-checks-git.sh is:\nv4.9.0-SNAPSHOT\n```\n\n\u003c/releasing-pre-release-checks-git-help\u003e\n\nFull usage example:\n\n\u003creleasing-pre-release-checks-git\u003e\n\n\u003c!-- auto-generated, do not modify here but in src/releasing/pre-release-checks-git.sh.doc --\u003e\n```bash\n#!/usr/bin/env bash\nset -euo pipefail\nshopt -s inherit_errexit || { echo \u003e\u00262 \"please update to bash 5, see errors above\" \u0026\u0026 exit 1; }\n# Assumes tegonal's scripts were fetched with gt - adjust location accordingly\ndir_of_tegonal_scripts=\"$(cd -- \"$(dirname -- \"${BASH_SOURCE[0]:-$0}\")\" \u003e/dev/null \u0026\u0026 pwd 2\u003e/dev/null)/../lib/tegonal-scripts/src\"\nsource \"$dir_of_tegonal_scripts/setup.sh\" \"$dir_of_tegonal_scripts\"\n\n# checks releasing v0.1.0 makes sense and the current branch is main\n\"$dir_of_tegonal_scripts/releasing/pre-release-checks-git.sh\" -v v0.1.0\n\n# checks releasing v0.1.0 makes sense and the current branch is hotfix-1.0\n\"$dir_of_tegonal_scripts/releasing/pre-release-checks-git.sh\" -v v0.1.0 -b hotfix-1.0\n```\n\n\u003c/releasing-pre-release-checks-git\u003e\n\n## SBT Sonatype publish\n\nAssumes you have configured your sbt project to publish to sonatype (or any other repo) where you have defined to \nuse SONATYPE_USER and SONATYPE_PW as env vars for your credentials. I.e. your build.sbt file will contain something like:\n```sbt\ncredentials += Credentials(\n  \"Sonatype Nexus Repository Manager\",\n  \"oss.sonatype.org\",\n  sys.env.getOrElse(\"SONATYPE_USER\", \"\"),\n  sys.env.getOrElse(\"SONATYPE_PW\", \"\")\n)\n```\n\nThis script asks to fill in those to env vars if not already given an calls `sbt publishSigned` afterwards passing\nthem in without exporting them.\n\nFull example:\n\n\u003creleasing-sbt-publish-to-sonatype\u003e\n\n\u003c!-- auto-generated, do not modify here but in src/releasing/sbt-publish-to-sonatype.sh.doc --\u003e\n```bash\n#!/usr/bin/env bash\nset -euo pipefail\nshopt -s inherit_errexit || { echo \u003e\u00262 \"please update to bash 5, see errors above\" \u0026\u0026 exit 1; }\n# Assumes tegonal's scripts were fetched with gt - adjust location accordingly\ndir_of_tegonal_scripts=\"$(cd -- \"$(dirname -- \"${BASH_SOURCE[0]:-$0}\")\" \u003e/dev/null \u0026\u0026 pwd 2\u003e/dev/null)/../lib/tegonal-scripts/src\"\nsource \"$dir_of_tegonal_scripts/setup.sh\" \"$dir_of_tegonal_scripts\"\n\n# ask for SONATYPE_USER and SONATYPE_PW (unless already exported beforehand) and calls sbt publishSigned\n\"$dir_of_tegonal_scripts/releasing/sbt-publish-to-sonatype.sh\"\n\n# predefine SONATYPE_USER, asks for SONATYPE_PW (unless already exported beforehand) and calls sbt publishSigned\nSONATYPE_USER=\"kshjwo2\" \"$dir_of_tegonal_scripts/releasing/sbt-publish-to-sonatype.sh\"\n\n# if you use it in combination with other files, then you might want to source it instead\nsourceOnce \"$dir_of_tegonal_scripts/releasing/sbt-publish-to-sonatype.sh\"\n\n# and then call the function\nsbtPublishToSonatype\nSONATYPE_USER=\"kshjwo2\" sbtPublishToSonatype\n```\n\n\u003c/releasing-sbt-publish-to-sonatype\u003e\n\n\n## Update Version Common Steps\n\nPerforms several `releasing` scripts defined in the following sections:\n\n- Updates the version in *.sh (see [Update Version in bash scripts](#update-version-in-bash-scripts))\n  defined in /scripts and .gt/**/pull-hook.sh\n- Updates the version in .github/ISSUE_TEMPLATE/**.y(a)ml files (\n  see [Update Version in issue templates](#update-version-in-issue-templates))\n- Updates the version in the README.md (see next section [Update Version in README](#update-version-in-readme)).\n- [activates the release section and hides the main section](#toggle-mainrelease-sections) if `-for-release` is `true` (the opposite otherwise)\n- [hides the sneak-peek banner](#hideshow-sneak-peek-banner) (or shows it if `--for-release` is `false`)\n\nHelp:\n\n\u003creleasing-update-version-common-steps-help\u003e\n\n\u003c!-- auto-generated, do not modify here but in src/releasing/update-version-common-steps.sh --\u003e\n```text\nParameters:\n--for-release   true if update is for release in which case we hide the sneak-peek banner and toggle sections for release, if false then we show the sneak-peek banner and toggle the section for development\n-v              The version to release in the format vX.Y.Z(-RC...)\n--project-dir   (optional) The projects directory -- default: .\n-p|--pattern    (optional) pattern which is used in a perl command (separator /) to search \u0026 replace additional occurrences. It should define two match groups and the replace operation looks as follows: \\${1}$version\\${2}\n\n--help     prints this help\n--version  prints the version of this script\n\nINFO: Version of update-version-common-steps.sh is:\nv4.9.0-SNAPSHOT\n```\n\n\u003c/releasing-update-version-common-steps-help\u003e\n\nFull usage example:\n\n\u003creleasing-update-version-common-steps\u003e\n\n\u003c!-- auto-generated, do not modify here but in src/releasing/update-version-common-steps.sh.doc --\u003e\n```bash\n#!/usr/bin/env bash\nset -euo pipefail\nshopt -s inherit_errexit || { echo \u003e\u00262 \"please update to bash 5, see errors above\" \u0026\u0026 exit 1; }\n# Assumes tegonal's scripts were fetched with gt - adjust location accordingly\ndir_of_tegonal_scripts=\"$(cd -- \"$(dirname -- \"${BASH_SOURCE[0]:-$0}\")\" \u003e/dev/null \u0026\u0026 pwd 2\u003e/dev/null)/../lib/tegonal-scripts/src\"\nsource \"$dir_of_tegonal_scripts/setup.sh\" \"$dir_of_tegonal_scripts\"\n\n# updates the version in headers of different files, hides the sneak-peek banner and\n# toggles sections in README.md for release\n\"$dir_of_tegonal_scripts/releasing/update-version-common-steps.sh\" --for-release true -v v0.1.0\n\n# 1. searches for additional occurrences where the version should be replaced via the specified pattern\n# 2. git commit all changes and create a tag for v0.1.0\n# 3. call scripts/prepare-next-dev-cycle.sh with nextVersion deduced from the specified version (in this case 0.2.0-SNAPSHOT)\n# 4. git commit all changes as prepare v0.2.0 dev cycle\n# 5. push tag and commits\n# 6. releases version v0.1.0 using the key 0x945FE615904E5C85 for signing and\n\"$dir_of_tegonal_scripts/releasing/update-version-common-steps.sh\" \\\n\t--for-release true \\\n\t-v v0.1.0 -k \"0x945FE615904E5C85\" \\\n\t-p \"(TEGONAL_SCRIPTS_VERSION=['\\\"])[^'\\\"]+(['\\\"])\"\n\n# in case you want to provide your own release.sh and only want to do some pre-configuration\n# then you might want to source it instead\nsourceOnce \"$dir_of_tegonal_scripts/releasing/update-version-common-steps.sh\"\n\n# and then call the function with your pre-configuration settings:\n# here we pre-define the additional pattern which shall be used in the search to replace the version\n# since \"$@\" follows afterwards, one could still override it via command line arguments.\n# put \"$@\" first, if you don't want that a user can override your pre-configuration\nupdateVersionCommonSteps -p \"(TEGONAL_SCRIPTS_VERSION=['\\\"])[^'\\\"]+(['\\\"])\" \"$@\"\n```\n\n\u003c/releasing-update-version-common-steps\u003e\n\n## Update Version in README\n\nUpdates the version used in download badges and in the sneak peek banner.\nRequires that you follow one of the following schemas for the download badges:\n\n```\n[![Download](https://img.shields.io/badge/Download-\u003cYOUR_VERSION\u003e-%23\u003cYOUR_COLOR\u003e)](\u003cANY_URL\u003e/v0.2.0)\n[![Download](https://img.shields.io/badge/Download-\u003cYOUR_VERSION\u003e-%23\u003cYOUR_COLOR\u003e)](\u003cANY_URL\u003e=v0.2.0)\n```\n\nAnd it searches for the following text for the sneak peek banner:\n\n```\nFor instance, the [README of v2.0.0](\u003cANY_URL\u003e/tree/v2.0.0/...) \n```\n\nHelp:\n\n\u003creleasing-update-version-README-help\u003e\n\n\u003c!-- auto-generated, do not modify here but in src/releasing/update-version-README.sh --\u003e\n```text\nParameters:\n-v             The version to release in the format vX.Y.Z(-RC...)\n-f|--file      (optional) the file where search \u0026 replace shall be done -- default: ./README.md\n-p|--pattern   (optional) pattern which is used in a perl command (separator /) to search \u0026 replace additional occurrences. It should define two match groups and the replace operation looks as follows: \\${1}$version\\${2}\n\n--help     prints this help\n--version  prints the version of this script\n\nExamples:\n# update version for ./README.md\nupdate-version-README.sh -v v0.1.0\n\n# update version for ./docs/index.md\nupdate-version-README.sh -v v0.1.0 -f ./docs/index.md\n\n# update version for ./README.md\n# also replace occurrences of the defined pattern\nupdate-version-README.sh -v v0.1.0 -p \"(VERSION=['\\\"])[^'\\\"]+(['\\\"])\"\n\nINFO: Version of update-version-README.sh is:\nv4.9.0-SNAPSHOT\n```\n\n\u003c/releasing-update-version-README-help\u003e\n\nFull usage example:\n\n\u003creleasing-update-version-README\u003e\n\n\u003c!-- auto-generated, do not modify here but in src/releasing/update-version-README.sh.doc --\u003e\n```bash\n#!/usr/bin/env bash\nset -euo pipefail\nshopt -s inherit_errexit || { echo \u003e\u00262 \"please update to bash 5, see errors above\" \u0026\u0026 exit 1; }\n# Assumes tegonal's scripts were fetched with gt - adjust location accordingly\ndir_of_tegonal_scripts=\"$(cd -- \"$(dirname -- \"${BASH_SOURCE[0]:-$0}\")\" \u003e/dev/null \u0026\u0026 pwd 2\u003e/dev/null)/../lib/tegonal-scripts/src\"\nsource \"$dir_of_tegonal_scripts/setup.sh\" \"$dir_of_tegonal_scripts\"\n\n\"$dir_of_tegonal_scripts/releasing/update-version-README.sh\" -v 0.1.0\n\n# if you use it in combination with other tegonal-scripts files, then you might want to source it instead\nsourceOnce \"$dir_of_tegonal_scripts/releasing/update-version-README.sh\"\n\n# and then call the function\nupdateVersionReadme -v 0.2.0\n```\n\n\u003c/releasing-update-version-README\u003e\n\n## Update Version in bash scripts\n\nSets the version placed before the `Description` section accordingly.\n\nHelp:\n\n\u003creleasing-update-version-scripts-help\u003e\n\n\u003c!-- auto-generated, do not modify here but in src/releasing/update-version-scripts.sh --\u003e\n```text\nParameters:\n-v               The version to release in the format vX.Y.Z(-RC...)\n-d|--directory   (optional) the working directory in which *.sh are searched (also in subdirectories) / you can also specify a file -- default: ./src\n-p|--pattern     (optional) pattern which is used in a perl command (separator /) to search \u0026 replace additional occurrences. It should define two match groups and the replace operation looks as follows: \\${1}$version\\${2}\n\n--help     prints this help\n--version  prints the version of this script\n\nExamples:\n# update version to v0.1.0 for all *.sh in ./src and subdirectories\nupdate-version-scripts.sh -v v0.1.0\n\n# update version to v0.1.0 for all *.sh in ./scripts and subdirectories\nupdate-version-scripts.sh -v v0.1.0 -d ./scripts\n\n# update version to v0.1.0 for all *.sh in ./src and subdirectories\n# also replace occurrences of the defined pattern\nupdate-version-scripts.sh -v v0.1.0 -p \"(VERSION=['\\\"])[^'\\\"]+(['\\\"])\"\n\nINFO: Version of update-version-scripts.sh is:\nv4.9.0-SNAPSHOT\n```\n\n\u003c/releasing-update-version-scripts-help\u003e\n\nFull usage example:\n\n\u003creleasing-update-version-scripts\u003e\n\n\u003c!-- auto-generated, do not modify here but in src/releasing/update-version-scripts.sh.doc --\u003e\n```bash\n#!/usr/bin/env bash\nset -euo pipefail\nshopt -s inherit_errexit || { echo \u003e\u00262 \"please update to bash 5, see errors above\" \u0026\u0026 exit 1; }\n# Assumes tegonal's scripts were fetched with gt - adjust location accordingly\ndir_of_tegonal_scripts=\"$(cd -- \"$(dirname -- \"${BASH_SOURCE[0]:-$0}\")\" \u003e/dev/null \u0026\u0026 pwd 2\u003e/dev/null)/../lib/tegonal-scripts/src\"\nsource \"$dir_of_tegonal_scripts/setup.sh\" \"$dir_of_tegonal_scripts\"\n\n\"$dir_of_tegonal_scripts/releasing/update-version-scripts.sh\" -v 0.1.0\n\n# if you use it in combination with other tegonal-scripts files, then you might want to source it instead\nsourceOnce \"$dir_of_tegonal_scripts/releasing/update-version-scripts.sh\"\n\n# and then call the function\nupdateVersionReadme -v 0.2.0\n```\n\n\u003c/releasing-update-version-scripts\u003e\n\n## Update Version in issue templates\n\nReplaces the `placeholder` of the `Affected Version` field in the given y(a)ml files\n\nHelp:\n\n\u003creleasing-update-version-issue-templates-help\u003e\n\n\u003c!-- auto-generated, do not modify here but in src/releasing/update-version-issue-templates.sh --\u003e\n```text\nParameters:\n-v               The version to release in the format vX.Y.Z(-RC...)\n-d|--directory   (optional) the working directory in which *.y(a)ml are searched (also in subdirectories) / you can also specify a file -- default: ./.github/ISSUE_TEMPLATE\n-p|--pattern     (optional) pattern which is used in a perl command (separator /) to search \u0026 replace additional occurrences. It should define two match groups and the replace operation looks as follows: \\${1}$version\\${2}\n\n--help     prints this help\n--version  prints the version of this script\n\nExamples:\n# update version to v0.1.0 for all *.y(a)ml in ./.github/ISSUE_TEMPLATE and subdirectories\nupdate-version-issue-templates.sh -v v0.1.0\n\n# update version to v0.1.0 for all *.y(a)ml in ./tpls and subdirectories\nupdate-version-issue-templates.sh -v v0.1.0 -d ./tpls\n\n# update version to v0.1.0 for all *.y(a)ml in ./.github/ISSUE_TEMPLATE and subdirectories\n# also replace occurrences of the defined pattern\nupdate-version-issue-templates.sh -v v0.1.0 -p \"(VERSION=['\\\"])[^'\\\"]+(['\\\"])\"\n\nINFO: Version of update-version-issue-templates.sh is:\nv4.9.0-SNAPSHOT\n```\n\n\u003c/releasing-update-version-issue-templates-help\u003e\n\nFull usage example:\n\n\u003creleasing-update-version-issue-templates\u003e\n\n\u003c!-- auto-generated, do not modify here but in src/releasing/update-version-issue-templates.sh.doc --\u003e\n```bash\n#!/usr/bin/env bash\nset -euo pipefail\nshopt -s inherit_errexit || { echo \u003e\u00262 \"please update to bash 5, see errors above\" \u0026\u0026 exit 1; }\n# Assumes tegonal's scripts were fetched with gt - adjust location accordingly\ndir_of_tegonal_scripts=\"$(cd -- \"$(dirname -- \"${BASH_SOURCE[0]:-$0}\")\" \u003e/dev/null \u0026\u0026 pwd 2\u003e/dev/null)/../lib/tegonal-scripts/src\"\nsource \"$dir_of_tegonal_scripts/setup.sh\" \"$dir_of_tegonal_scripts\"\n\n\"$dir_of_tegonal_scripts/releasing/update-issue-templates.sh\" -v 0.1.0\n\n# if you use it in combination with other tegonal-scripts files, then you might want to source it instead\nsourceOnce \"$dir_of_tegonal_scripts/releasing/update-issue-templates.sh\"\n\n# and then call the function\nupdateVersionIssueTemplate -v 0.2.0\n```\n\n\u003c/releasing-update-version-issue-templates\u003e\n\n## Toggle main/release sections\n\nUtility to comment/uncomment sections defined via\n\n```\n\u003c!-- for main --\u003e\n...\n\u003c!-- for main end --\u003e\n```\n\nand\n\n```\n\u003c!-- for release --\u003e\n...\n\u003c!-- for release end --\u003e\n```\n\ndepending on the passed command:\n\n- Passing `main` will uncomment main sections and comment release sections.\n- Passing `release` will uncomment release sections and comment main sections.\n\nHelp:\n\n\u003creleasing-toggle-sections-help\u003e\n\n\u003c!-- auto-generated, do not modify here but in src/releasing/toggle-sections.sh --\u003e\n```text\nParameters:\n-c|--command   either 'main' or 'release'\n-f|--file      (optional) the file where search \u0026 replace shall be done -- default: ./README.md\n\n--help     prints this help\n--version  prints the version of this script\n\nExamples:\n# comment the release sections in ./README.md and uncomment the main sections\ntoggle-sections.sh -c main\n\n# comment the main sections in ./docs/index.md and uncomment the release sections\ntoggle-sections.sh -c release -f ./docs/index.md\n\nINFO: Version of toggle-sections.sh is:\nv4.9.0-SNAPSHOT\n```\n\n\u003c/releasing-toggle-sections-help\u003e\n\nFull usage example:\n\n\u003creleasing-toggle-sections\u003e\n\n\u003c!-- auto-generated, do not modify here but in src/releasing/toggle-sections.sh.doc --\u003e\n```bash\n#!/usr/bin/env bash\nset -euo pipefail\nshopt -s inherit_errexit || { echo \u003e\u00262 \"please update to bash 5, see errors above\" \u0026\u0026 exit 1; }\n# Assumes tegonal's scripts were fetched with gt - adjust location accordingly\ndir_of_tegonal_scripts=\"$(cd -- \"$(dirname -- \"${BASH_SOURCE[0]:-$0}\")\" \u003e/dev/null \u0026\u0026 pwd 2\u003e/dev/null)/../lib/tegonal-scripts/src\"\nsource \"$dir_of_tegonal_scripts/setup.sh\" \"$dir_of_tegonal_scripts\"\n\n\"$dir_of_tegonal_scripts/releasing/toggle-sections.sh\" -c main\n\n# if you use it in combination with other files, then you might want to source it instead\nsourceOnce \"$dir_of_tegonal_scripts/releasing/toggle-sections.sh\"\n\n# and then call the function\ntoggleSections -c release\n```\n\n\u003c/releasing-toggle-sections\u003e\n\n## Hide/Show sneak peek banner\n\nIn case you use a sneak peek banner as we do in this repo, then this script can be used to hide it (before tagging)\nand show it again in the new dev cycle.\n\nHelp:\n\n\u003creleasing-sneak-peek-banner-help\u003e\n\n\u003c!-- auto-generated, do not modify here but in src/releasing/sneak-peek-banner.sh --\u003e\n```text\nParameters:\n-c|--command   either 'show' or 'hide'\n-f|--file      (optional) the file where search \u0026 replace shall be done -- default: ./README.md\n\n--help     prints this help\n--version  prints the version of this script\n\nExamples:\n# hide the sneak peek banner in ./README.md\nsneak-peek-banner.sh -c hide\n\n# show the sneak peek banner in ./docs/index.md\nsneak-peek-banner.sh -c show -f ./docs/index.md\n\nINFO: Version of sneak-peek-banner.sh is:\nv4.9.0-SNAPSHOT\n```\n\n\u003c/releasing-sneak-peek-banner-help\u003e\n\nFull usage example:\n\n\u003creleasing-sneak-peek-banner\u003e\n\n\u003c!-- auto-generated, do not modify here but in src/releasing/sneak-peek-banner.sh.doc --\u003e\n```bash\n#!/usr/bin/env bash\nset -euo pipefail\nshopt -s inherit_errexit || { echo \u003e\u00262 \"please update to bash 5, see errors above\" \u0026\u0026 exit 1; }\n# Assumes tegonal's scripts were fetched with gt - adjust location accordingly\ndir_of_tegonal_scripts=\"$(cd -- \"$(dirname -- \"${BASH_SOURCE[0]:-$0}\")\" \u003e/dev/null \u0026\u0026 pwd 2\u003e/dev/null)/../lib/tegonal-scripts/src\"\nsource \"$dir_of_tegonal_scripts/setup.sh\" \"$dir_of_tegonal_scripts\"\n\n\"$dir_of_tegonal_scripts/releasing/sneak-peek-banner.sh\" -c hide\n\n# if you use it in combination with other files, then you might want to source it instead\nsourceOnce \"$dir_of_tegonal_scripts/releasing/sneak-peek-banner.sh\"\n\n# and then call the function\nsneakPeekBanner -c show\n```\n\n\u003c/releasing-sneak-peek-banner\u003e\n\n# Script Utilities\n\nThe scripts under this topic (in directory `utility`) are useful for bash programming as such.\n\n## array utils\n\nUtility functions when dealing with arrays.\n\n\u003cutility-array-utils\u003e\n\n\u003c!-- auto-generated, do not modify here but in src/utility/array-utils.sh.doc --\u003e\n```bash\n#!/usr/bin/env bash\nset -euo pipefail\nshopt -s inherit_errexit || { echo \u003e\u00262 \"please update to bash 5, see errors above\" \u0026\u0026 exit 1; }\n# Assumes tegonal's scripts were fetched with gt - adjust location accordingly\ndir_of_tegonal_scripts=\"$(cd -- \"$(dirname -- \"${BASH_SOURCE[0]:-$0}\")\" \u003e/dev/null \u0026\u0026 pwd 2\u003e/dev/null)/../lib/tegonal-scripts/src\"\nsource \"$dir_of_tegonal_scripts/setup.sh\" \"$dir_of_tegonal_scripts\"\n\nsourceOnce \"$dir_of_tegonal_scripts/utility/array-utils.sh\"\n\ndeclare regex\nregex=$(joinByChar '|' my regex alternatives)\ndeclare -a commands=(add delete list config)\nregex=$(joinByChar '|' \"${commands[@]}\")\n\njoinByString ', ' a list of strings and the previously defined \"$regex\"\ndeclare -a names=(alwin darius fabian mike mikel robert oliver thomas)\ndeclare employees\nemployees=$(joinByString \", \" \"${names[@]}\")\necho \"\"\necho \"Tegonal employees are currently: $employees\"\n\nfunction startingWithA() {\n\t[[ $1 == a* ]]\n}\ndeclare -a namesStartingWithA=()\narrFilter names namesStartingWithA startingWithA\ndeclare -p namesStartingWithA\n\ndeclare -a everySecondName\narrTakeEveryX names everySecondName 2 0\ndeclare -p everySecondName\ndeclare -a everySecondNameStartingFrom1\narrTakeEveryX names everySecondNameStartingFrom1 2 1\ndeclare -p everySecondNameStartingFrom1\n\narrStringEntryMaxLength names # 6\n```\n\n\u003c/utility-array-utils\u003e\n\n## Ask functions\n\nUtility functions to interact with the user.\n\n\u003cutility-ask\u003e\n\n\u003c!-- auto-generated, do not modify here but in src/utility/ask.sh.doc --\u003e\n```bash\n#!/usr/bin/env bash\nset -euo pipefail\nshopt -s inherit_errexit || { echo \u003e\u00262 \"please update to bash 5, see errors above\" \u0026\u0026 exit 1; }\n# Assumes tegonal's scripts were fetched with gt - adjust location accordingly\ndir_of_tegonal_scripts=\"$(cd -- \"$(dirname -- \"${BASH_SOURCE[0]:-$0}\")\" \u003e/dev/null \u0026\u0026 pwd 2\u003e/dev/null)/../lib/tegonal-scripts/src\"\nsource \"$dir_of_tegonal_scripts/setup.sh\" \"$dir_of_tegonal_scripts\"\n\nsourceOnce \"$dir_of_tegonal_scripts/utility/ask.sh\"\n\nif askYesOrNo \"shall I say hello\"; then\n\techo \"hello\"\nfi\n\nfunction noAnswerCallback {\n\techo \"hm... no answer, I am sad :(\"\n}\ntimeoutInSeconds=30\nreadArgs='' # i.e. no additional args passed to read\nanswer='default value used if there is no answer'\naskWithTimeout \"some question\" \"$timeoutInSeconds\" noAnswerCallback answer \"$readArgs\"\necho \"$answer\"\n```\n\n\u003c/utility-ask\u003e\n\n## cleanups\n\nUtility functions which shall help to keep your repo clean and tidy.\n\n\u003cutility-cleanups\u003e\n\n\u003c!-- auto-generated, do not modify here but in src/utility/cleanups.sh.doc --\u003e\n```bash\n#!/usr/bin/env bash\nset -euo pipefail\nshopt -s inherit_errexit || { echo \u003e\u00262 \"please update to bash 5, see errors above\" \u0026\u0026 exit 1; }\n\nprojectDir=\"$(cd -- \"$(dirname -- \"${BASH_SOURCE[0]:-$0}\")\" \u003e/dev/null \u0026\u0026 pwd 2\u003e/dev/null)/..\"\n\n# Assumes tegonal's scripts were fetched with gt - adjust location accordingly\ndir_of_tegonal_scripts=\"$projectDir/lib/tegonal-scripts/src\"\nsource \"$dir_of_tegonal_scripts/setup.sh\" \"$dir_of_tegonal_scripts\"\n\nsourceOnce \"$dir_of_tegonal_scripts/utility/cleanups.sh\"\n\n# e.g. in scripts/cleanup-on-push-to-main.sh\nfunction cleanupOnPushToMain() {\n\tremoveUnusedSignatures \"$projectDir\"\n\tlogSuccess \"cleanup done\"\n}\n```\n\n\u003c/utility-cleanups\u003e\n\n## Checks\n\nUtility functions which check some conditions like is passed arg the correct type etc.\n\n\u003cutility-checks\u003e\n\n\u003c!-- auto-generated, do not modify here but in src/utility/checks.sh.doc --\u003e\n```bash\n#!/usr/bin/env bash\nset -euo pipefail\nshopt -s inherit_errexit || { echo \u003e\u00262 \"please update to bash 5, see errors above\" \u0026\u0026 exit 1; }\n# Assumes tegonal's scripts were fetched with gt - adjust location accordingly\ndir_of_tegonal_scripts=\"$(cd -- \"$(dirname -- \"${BASH_SOURCE[0]:-$0}\")\" \u003e/dev/null \u0026\u0026 pwd 2\u003e/dev/null)/../lib/tegonal-scripts/src\"\nsource \"$dir_of_tegonal_scripts/setup.sh\" \"$dir_of_tegonal_scripts\"\n\nsourceOnce \"$dir_of_tegonal_scripts/utility/checks.sh\"\n\nfunction foo() {\n\t# shellcheck disable=SC2034   # is passed by name to checkArgIsArray\n\tlocal -rn arr=$1\n\tlocal -r fn=$2\n\tlocal -r bool=$3\n\tlocal -r version=$4\n\n\t# resolves arr recursively via recursiveDeclareP and check that is a non-associative array\n\tcheckArgIsArray arr 1        \t\t# same as exitIfArgIsNotArray if set -e has an effect on this line\n\tcheckArgIsFunction \"$fn\" 2   \t\t# same as exitIfArgIsNotFunction if set -e has an effect on this line\n\tcheckArgIsBoolean \"$bool\" 3   \t# same as exitIfArgIsNotBoolean if set -e has an effect on this line\n\tcheckArgIsVersion \"$version\" 4  # same as exitIfArgIsNotVersion if set -e has an effect on this line\n\n\t# shellcheck disable=SC2317   # is passed by name to checkArgIsArrayWithTuples\n\tfunction describeTriple() {\n\t\techo \u003e\u00262 \"array contains 3-tuples with names where the first value is the first-, the second the middle- and the third the lastname\"\n\t}\n\t# check array with 3-tuples\n\tcheckArgIsArrayWithTuples arr 3 \"names\" 1 describeTriple\n\n\texitIfArgIsNotArray arr 1\n\texitIfArgIsNotArrayOrIsEmpty arr 1\n\texitIfArgIsNotArrayOrIsNonEmpty arr 1\n\texitIfArgIsNotFunction \"$fn\" 2\n\texitIfArgIsNotBoolean \"$bool\" 3\n\texitIfArgIsNotVersion \"$version\" 4\n\n\t# shellcheck disable=SC2317   # is passed by name to exitIfArgIsNotArrayWithTuples\n\tfunction describePair() {\n\t\techo \u003e\u00262 \"array contains 2-tuples with names where the first value is the first-, and the second the last name\"\n\t}\n\t# check array with 2-tuples\n\texitIfArgIsNotArrayWithTuples arr 2 \"names\" 1 describePair\n\n\t# returns 0 if the array was initialised (i.e. a value assigned) and non-0 otherwise\n\tcheckIsInitialisedArray arr\n}\n\nif checkCommandExists \"cat\"; then\n\techo \"do whatever you want to do...\"\nfi\n\n# give a hint how to install the command\ncheckCommandExists \"git\" \"please install it via https://git-scm.com/downloads\"\n\n# same as checkCommandExists but exits instead of returning non-zero in case command does not exist\nexitIfCommandDoesNotExist \"git\" \"please install it via https://git-scm.com/downloads\"\n\n# meant to be used in a file which is sourced where a contract exists between the file which `source`s and the sourced file\nexitIfVarsNotAlreadySetBySource myVar1 var2 var3\n\ndeclare myVar4\nexitIfVariablesNotDeclared myVar4 myVar5 # would exit because myVar5 is not set\necho \"myVar4 $myVar4\"\n\ndeclare currentDir\ncurrentDir=$(pwd)\ncheckPathNamedIsInsideOf \"$myVar4\" \"source directory\" \"$currentDir\" # same as exitIfPathNamedIsOutsideOf if set -e has an effect on this line\nexitIfPathNamedIsOutsideOf \"$myVar4/plugins.txt\" \"plugins\" \"$currentDir\"\n```\n\n\u003c/utility-checks\u003e\n\n## date utils\n\nDate utils around `date` and co\n\n\u003cutility-date-utils\u003e\n\n\u003c!-- auto-generated, do not modify here but in src/utility/date-utils.sh.doc --\u003e\n```bash\n#!/usr/bin/env bash\nset -euo pipefail\nshopt -s inherit_errexit || { echo \u003e\u00262 \"please update to bash 5, see errors above\" \u0026\u0026 exit 1; }\n\nprojectDir=\"$(cd -- \"$(dirname -- \"${BASH_SOURCE[0]:-$0}\")\" \u003e/dev/null \u0026\u0026 pwd 2\u003e/dev/null)/..\"\n\n# Assumes tegonal's scripts were fetched with gt - adjust location accordingly\ndir_of_tegonal_scripts=\"$projectDir/lib/tegonal-scripts/src\"\nsource \"$dir_of_tegonal_scripts/setup.sh\" \"$dir_of_tegonal_scripts\"\n\nsourceOnce \"$dir_of_tegonal_scripts/utility/date-utils.sh\"\n\n# converts the unix timestamp to a date with time in format Y-m-dTH:M:S\ntimestampToDateTime 1662981524 # outputs 2022-09-12T13:18:44\n\n# converts the unix timestamp to a date in format Y-m-d\ntimestampToDate 1662981524 # outputs 2022-09-12\n\n# converts the unix timestamp to a date in format as defined by LC_TIME\n# (usually as defined by the user in the system settings)\ntimestampToDateInUserFormat 1662981524 # outputs 12.09.2022 for ch_DE\n\ndateToTimestamp \"2024-03-01\" # outputs 1709247600\ndateToTimestamp \"2022-09-12T13:18:44\" # outputs 1662981524\n\n# outputs a timestamp in ms\nstartTimestampInMs=\"$(timestampInMs)\"\n\nformatMsToSeconds 12 \t\t# outputs 0.012\nformatMsToSeconds 1234  # outputs 1.234\nformatMsToSeconds -123  # outputs -0.123\n# note that formatMsToSeconds does not check if you pass a number\n\n# outputs the time passed since the given timestamp in ms formatted as seconds\nelapsedSecondsBasedOnTimestampInMs \"$startTimestampInMs\"\n```\n\n\u003c/utility-date-utils\u003e\n\n## git utils\n\nUtility functions around `git`.\n\n\u003cutility-git-utils\u003e\n\n\u003c!-- auto-generated, do not modify here but in src/utility/git-utils.sh.doc --\u003e\n```bash\n#!/usr/bin/env bash\nset -euo pipefail\nshopt -s inherit_errexit || { echo \u003e\u00262 \"please update to bash 5, see errors above\" \u0026\u0026 exit 1; }\n# Assumes tegonal's scripts were fetched with gt - adjust location accordingly\ndir_of_tegonal_scripts=\"$(cd -- \"$(dirname -- \"${BASH_SOURCE[0]:-$0}\")\" \u003e/dev/null \u0026\u0026 pwd 2\u003e/dev/null)/../lib/tegonal-scripts/src\"\nsource \"$dir_of_tegonal_scripts/setup.sh\" \"$dir_of_tegonal_scripts\"\n\nsourceOnce \"$dir_of_tegonal_scripts/utility/git-utils.sh\"\n\ndeclare currentBranch\ncurrentBranch=$(currentGitBranch)\necho \"current git branch is: $currentBranch\"\n\nif hasGitChanges; then\n\techo \"do whatever you want to do...\"\nfi\n\nif localGitIsAhead \"main\"; then\n\techo \"do whatever you want to do...\"\nelif localGitIsAhead \"main\" \"anotherRemote\"; then\n\techo \"do whatever you want to do...\"\nfi\n\nif localGitIsBehind \"main\"; then\n\techo \"do whatever you want to do...\"\nelif localGitIsBehind \"main\"; then\n\techo \"do whatever you want to do...\"\nfi\n\nif hasRemoteTag \"v0.1.0\"; then\n\techo \"do whatever you want to do...\"\nelif hasRemoteTag \"v0.1.0\" \"anotherRemote\"; then\n\techo \"do whatever you want to do...\"\nfi\n\necho \"all existing tags on remote origin, starting from smallest to biggest version number\"\nremoteTagsSorted\n\n# if you specify the name of the remote, then all additional arguments are passed to `sort` which is used internally\necho \"all existing tags on remote upstream, starting from smallest to biggest version number\"\nremoteTagsSorted upstream -r\n\ndeclare latestTag\nlatestTag=$(latestRemoteTag)\necho \"latest tag on origin: $latestTag\"\nlatestTag=$(latestRemoteTag upstream)\necho \"latest tag on upstream: $latestTag\"\nlatestTag=$(latestRemoteTag origin \"^v1\\.[0-9]+\\.[0-9]+$\")\necho \"latest tag in the major 1.x.x series on origin without release candidates: $latestTag\"\n```\n\n\u003c/utility-git-utils\u003e\n\n## GPG utils\n\nUtility functions which hopefully make it easier for you to deal with `gpg`\n\n\u003cutility-gpg-utils\u003e\n\n\u003c!-- auto-generated, do not modify here but in src/utility/gpg-utils.sh.doc --\u003e\n```bash\n#!/usr/bin/env bash\nset -euo pipefail\nshopt -s inherit_errexit || { echo \u003e\u00262 \"please update to bash 5, see errors above\" \u0026\u0026 exit 1; }\n# Assumes tegonal's scripts were fetched with gt - adjust location accordingly\ndir_of_tegonal_scripts=\"$(cd -- \"$(dirname -- \"${BASH_SOURCE[0]:-$0}\")\" \u003e/dev/null \u0026\u0026 pwd 2\u003e/dev/null)/../lib/tegonal-scripts/src\"\nsource \"$dir_of_tegonal_scripts/setup.sh\" \"$dir_of_tegonal_scripts\"\n\nsourceOnce \"$dir_of_tegonal_scripts/utility/gpg-utils.sh\"\n\n# import public-key.asc into gpg store located at ~/.gpg and trust automatically\nimportGpgKey ~/.gpg ./public-key.asc\n\n# import public-key.asc into gpg store located at ~/.gpg but ask given question first which needs to be answered with yes\nimportGpgKey ~/.gpg ./public-key.asc \"do you want to import the shown key(s)?\"\n\n# import public-key.asc into gpg store located at .gt/remotes/tegonal-scripts/public-keys/gpg\n# and trust automatically\nimportGpgKey .gt/remotes/tegonal-scripts/public-keys/gpg ./public-key.asc\n\n# trust key which is identified via info@tegonal.com in gpg store located at ~/.gpg\ntrustGpgKey ~/.gpg info@tegonal.com\n\n# get the gpg key data one can retrieve via --list-key --with-colons (pub or sub) for the key which signed the given file\ngetSigningGpgKeyData \"file.sig\"\n\n# get the gpg key data one can retrieve via --list-key --with-colons (pub or sub) for the key which signed the given file\n# but searches the key not in the default gpg store but in .gt/remotes/tegonal-scripts/public-keys/gpg\ngetSigningGpgKeyData \"file.sig\" .gt/remotes/tegonal-scripts/public-keys/gpg\n\n# returns the creation date of the signature\ngetSigCreationDate \"file.sig\"\n\nkeyData=\"sub:-:4096:1:4B78012139378220:...\"\n\n# extract the key id from the given key data\nextractGpgKeyIdFromKeyData \"$keyData\"\n# extract the expiration timestamp from the given key data\nextractExpirationTimestampFromKeyData \"$keyData\"\n\n# returns with 0 if the given key data (the key respectively) is expired, non-zero otherwise\nisGpgKeyInKeyDataExpired \"$keyData\"\n# returns with 0 if the given key data  (the key respectively) was revoked, non-zero otherwise\nisGpgKeyInKeyDataRevoked \"$keyData\"\n\n# returns the revocation data one can retrieve via --list-sigs --with-colons (rev) for the given key\ngetRevocationData 4B78012139378220\n\n# returns the revocation data one can retrieve via --list-sigs --with-colons (rev) for the given key\n# but searches the revocation not in the default gpg store but in .gt/remotes/tegonal-scripts/public-keys/gpg\ngetRevocationData 4B78012139378220 .gt/remotes/tegonal-scripts/public-keys/gpg\n\n# extract the creation timestamp from the given revocation data\nextractCreationTimestampFromRevocationData\n\n# list all signatures of the given key and highlights it in the output (which especially useful if the key is a subkey\n# and there are other subkeys)\nlistSignaturesAndHighlightKey 4B78012139378220\n\n# list all signatures of the given key and highlights it in the output (which especially useful if the key is a subkey\n# and there are other subkeys) but searches the revocation not in the default gpg store but in\n# .gt/remotes/tegonal-scripts/public-keys/gpg\nlistSignaturesAndHighlightKey 4B78012139378220 .gt/remotes/tegonal-scripts/public-keys/gpg\n```\n\n\u003c/utility-gpg-utils\u003e\n\n## http functions\n\n\u003cutility-http\u003e\n\n\u003c!-- auto-generated, do not modify here but in src/utility/http.sh.doc --\u003e\n```bash\n#!/usr/bin/env bash\nset -euo pipefail\nshopt -s inherit_errexit || { echo \u003e\u00262 \"please update to bash 5, see errors above\" \u0026\u0026 exit 1; }\n# Assumes tegonal's scripts were fetched with gt - adjust location accordingly\ndir_of_tegonal_scripts=\"$(cd -- \"$(dirname -- \"${BASH_SOURCE[0]:-$0}\")\" \u003e/dev/null \u0026\u0026 pwd 2\u003e/dev/null)/../lib/tegonal-scripts/src\"\nsource \"$dir_of_tegonal_scripts/setup.sh\" \"$dir_of_tegonal_scripts\"\n\nsourceOnce \"$dir_of_tegonal_scripts/utility/http.sh\"\n\n# downloads https://.../signing-key.public.asc and https://.../signing-key.public.asc.sig and verifies it with gpg\nwgetAndVerify \"https://github.com/tegonal/gt/.gt/signing-key.public.asc\"\n```\n\n\u003c/utility-http\u003e\n\n## IO functions\n\n\u003cutility-io\u003e\n\n\u003c!-- auto-generated, do not modify here but in src/utility/io.sh.doc --\u003e\n```bash\n#!/usr/bin/env bash\nset -euo pipefail\nshopt -s inherit_errexit || { echo \u003e\u00262 \"please update to bash 5, see errors above\" \u0026\u0026 exit 1; }\n# Assumes tegonal's scripts were fetched with gt - adjust location accordingly\ndir_of_tegonal_scripts=\"$(cd -- \"$(dirname -- \"${BASH_SOURCE[0]:-$0}\")\" \u003e/dev/null \u0026\u0026 pwd 2\u003e/dev/null)/../lib/tegonal-scripts/src\"\nsource \"$dir_of_tegonal_scripts/setup.sh\" \"$dir_of_tegonal_scripts\"\n\nsourceOnce \"$dir_of_tegonal_scripts/utility/io.sh\"\n\nfunction readFile() {\n\tcat \"$1\" \u003e\u00263\n\techo \"reading from 4 which was written to 3\"\n\tlocal line\n\twhile read -u 4 -r line; do\n\t\techo \"$line\"\n\tdone\n}\n\n# creates file descriptors 3 (output) and 4 (input) based on temporary files\n# executes readFile and closes the file descriptors again\nwithCustomOutputInput 3 4 readFile \"my-file.txt\"\n\n\n# First tries to set chmod 777 to the directory and all files within it and then deletes the directory\ndeleteDirChmod777 \".git\"\n```\n\n\u003c/utility-io\u003e\n\n## Log Functions\n\nUtility functions to log messages including a severity level where logError writes to stderr\n\n\u003cutility-log\u003e\n\n\u003c!-- auto-generated, do not modify here but in src/utility/log.sh.doc --\u003e\n```bash\n#!/usr/bin/env bash\nset -euo pipefail\nshopt -s inherit_errexit || { echo \u003e\u00262 \"please update to bash 5, see errors above\" \u0026\u0026 exit 1; }\n# Assumes tegonal's scripts were fetched with gt - adjust location accordingly\ndir_of_tegonal_scripts=\"$(cd -- \"$(dirname -- \"${BASH_SOURCE[0]:-$0}\")\" \u003e/dev/null \u0026\u0026 pwd 2\u003e/dev/null)/../lib/tegonal-scripts/src\"\nsource \"$dir_of_tegonal_scripts/setup.sh\" \"$dir_of_tegonal_scripts\"\n\nsourceOnce \"$dir_of_tegonal_scripts/utility/log.sh\"\n\nlogInfo \"hello %s\" \"world\"\n# INFO: hello world\n\nlogInfo \"line %s\" 1 2 3\n# INFO: line 1\n# INFO: line 2\n# INFO: line 3\n\nlogWarning \"oho...\"\n# WARNING: oho...\n\nlogError \"illegal state...\"\n# ERROR: illegal state...\n\nseconds=54\nlogSuccess \"import finished in %s seconds\" \"$seconds\"\n# SUCCESS: import finished in 54 seconds\n\ndie \"fatal error, shutting down\"\n# ERROR: fatal error, shutting down\n# exit 1\n\nreturnDying \"fatal error, shutting down\"\n# ERROR: fatal error, shutting down\n# return 1\n\n# in case you don't want a newline at the end of the message, then use one of\nlogInfoWithoutNewline \"hello\"\n# INFO: hello%\nlogWarningWithoutNewline \"be careful\"\nlogErrorWithoutNewline \"oho\"\nlogSuccessWithoutNewline \"yay\"\n\ntraceAndDie \"fatal error, shutting down\"\n# ERROR: fatal error, shutting down\n#\n# Stacktrace:\n#    foo @ /opt/foo.sh:32:1\n#    bar @ /opt/bar.sh:10:1\n#    ...\n# exit 1\n\ntraceAndReturnDying \"fatal error, shutting down\"\n# ERROR: fatal error, shutting down\n#\n# Stacktrace:\n#    foo @ /opt/foo.sh:32:1\n#    bar @ /opt/bar.sh:10:1\n#    ...\n# return 1\n\nprintStackTrace\n# Stacktrace:\n#    foo @ /opt/foo.sh:32:1\n#    bar @ /opt/bar.sh:10:1\n#   main @ /opt/main.sh:4:1\n```\n\n\u003c/utility-log\u003e\n\n## Parse arguments\n\nWe provide three scripts helping in parsing command line arguments:\n\n- parse-args.sh which expects named arguments\n- parse-fn-args which is intended to be used in functions and only supports positional arguments\n- parse-command.sh which simplifies the delegation to corresponding command functions\n\n### parse-args.sh\n\nFull usage example:\n\n\u003cutility-parse-args\u003e\n\n\u003c!-- auto-generated, do not modify here but in src/utility/parse-args.sh.doc --\u003e\n```bash\n#!/usr/bin/env bash\nset -euo pipefail\nshopt -s inherit_errexit || { echo \u003e\u00262 \"please update to bash 5, see errors above\" \u0026\u0026 exit 1; }\nMY_LIB_VERSION=\"v1.1.0\"\n\n# Assumes tegonal's scripts were fetched with gt - adjust location accordingly\ndir_of_tegonal_scripts=\"$(cd -- \"$(dirname -- \"${BASH_SOURCE[0]:-$0}\")\" \u003e/dev/null \u0026\u0026 pwd 2\u003e/dev/null)/../lib/tegonal-scripts/src\"\nsource \"$dir_of_tegonal_scripts/setup.sh\" \"$dir_of_tegonal_scripts\"\n\nsourceOnce \"$dir_of_tegonal_scripts/utility/parse-args.sh\"\n\n# declare all parameter names here (used as identifier afterwards)\ndeclare pattern version directory\n\n# parameter definitions where each parameter definition consists of three values (separated via space)\n# VARIABLE_NAME PATTERN HELP_TEXT\n# where the HELP_TEXT is optional in the sense of that you can use an empty string\n# shellcheck disable=SC2034   # is passed by name to parseArguments\ndeclare params=(\n\tpattern '-p|--pattern' ''\n\tversion '-v' 'the version'\n\tdirectory '-d|--directory' '(optional) the working directory -- default: .'\n)\n# optional: you can define examples which are included in the help text -- use an empty string for no example\ndeclare examples\n# `examples` is used implicitly in parse-args, here shellcheck cannot know it and you need to disable the rule\nexamples=$(\n\tcat \u003c\u003cEOM\n# analyse in the current directory using the specified pattern\nanalysis.sh -p \"%{21}\" -v v0.1.0\nEOM\n)\n\nparseArguments params \"$examples\" \"$MY_LIB_VERSION\" \"$@\" || return $?\n# in case there are optional parameters, then fill them in here before calling exitIfNotAllArgumentsSet\nif ! [[ -v directory ]]; then directory=\".\"; fi\nexitIfNotAllArgumentsSet params \"$examples\" \"$MY_LIB_VERSION\"\n\n# pass your variables storing the arguments to other scripts\necho \"p: $pattern, v: $version, d: $directory\"\n```\n\n\u003c/utility-parse-args\u003e\n\n### parse-fn-args.sh\n\nFull usage example:\n\n\u003cutility-parse-fn-args\u003e\n\n\u003c!-- auto-generated, do not modify here but in src/utility/parse-fn-args.sh.doc --\u003e\n```bash\n#!/usr/bin/env bash\nset -euo pipefail\nshopt -s inherit_errexit || { echo \u003e\u00262 \"please update to bash 5, see errors above\" \u0026\u0026 exit 1; }\n\nif ! [[ -v dir_of_tegonal_scripts ]]; then\n\t# Assumes tegonal's scripts were fetched with gt - adjust location accordingly\n\tdir_of_tegonal_scripts=\"$(cd -- \"$(dirname -- \"${BASH_SOURCE[0]:-$0}\")\" \u003e/dev/null \u0026\u0026 pwd 2\u003e/dev/null)/../lib/tegonal-scripts/src\"\n\tsource \"$dir_of_tegonal_scripts/setup.sh\" \"$dir_of_tegonal_scripts\"\nfi\nsourceOnce \"$dir_of_tegonal_scripts/utility/parse-fn-args.sh\"\n\nfunction myFunction() {\n\t# declare the variable you want to use and repeat in `declare params`\n\tlocal command dir\n\n\t# shellcheck disable=SC2034   # is passed by name to parseFnArgs\n\tlocal -ra params=(command dir)\n\tparseFnArgs params \"$@\" || return $?\n\n\t# pass your variables storing the arguments to other scripts\n\techo \"command: $command, dir: $dir\"\n}\n\nfunction myFunctionWithVarargs() {\n\n\t# in case you want to use a vararg parameter as last parameter then name your last parameter for `params` varargs:\n\tlocal command dir varargs\n\t# shellcheck disable=SC2034   # is passed by name to parseFnArgs\n\tlocal -ra params=(command dir varargs)\n\tparseFnArgs params \"$@\" || return $?\n\n\t# use varargs in another script\n\techo \"command: $command, dir: $dir, varargs: ${varargs*}\"\n}\n```\n\n\u003c/utility-parse-fn-args\u003e\n\n### parse-commands.sh\n\nFull usage example:\n\n\u003cutility-parse-commands\u003e\n\n\u003c!-- auto-generated, do not modify here but in src/utility/parse-commands.sh.doc --\u003e\n```bash\n#!/usr/bin/env bash\nset -euo pipefail\nshopt -s inherit_errexit || { echo \u003e\u00262 \"please update to bash 5, see errors above\" \u0026\u0026 exit 1; }\nMY_LIB_VERSION=\"v1.1.0\"\n\n# Assumes tegonal's scripts were fetched with gt - adjust location accordingly\ndir_of_tegonal_scripts=\"$(cd -- \"$(dirname -- \"${BASH_SOURCE[0]:-$0}\")\" \u003e/dev/null \u0026\u0026 pwd 2\u003e/dev/null)/../lib/tegonal-scripts/src\"\nsource \"$dir_of_tegonal_scripts/setup.sh\" \"$dir_of_tegonal_scripts\"\n\nsourceOnce \"$dir_of_tegonal_scripts/utility/parse-commands.sh\"\n\n# command definitions where each command definition consists of two values (separated via space)\n# COMMAND_NAME HELP_TEXT\n# where the HELP_TEXT is optional in the sense of that you can use an empty string\n# shellcheck disable=SC2034   # is passed by name to parseCommands\ndeclare commands=(\n\tadd 'command to add people to your list'\n\tconfig 'manage configuration'\n\tlogin ''\n)\n\n# the function which is responsible to load the corresponding file which contains the function of this particular command\nfunction sourceCommand() {\n\tlocal -r command=$1\n\tshift\n\tsourceOnce \"my-lib-$command.sh\"\n}\n\n# pass:\n# 1. supported commands\n# 2. version which shall be shown in --version and --help\n# 3. source command, responsible to load the files\n# 4. the prefix used for the commands. e.g. command show with prefix my_lib_ results in calling a\n#    function my_lib_show if the users wants to execute command show\n# 5. arguments passed to the corresponding function\nparseCommands commands \"$MY_LIB_VERSION\" sourceCommand \"my_lib_\" \"$@\"\n```\n\n\u003c/utility-parse-commands\u003e\n\n## Parse utils\n\nUtility functions when parsing (see also [Parse arguments](#parse-arguments)).\n\n\u003cutility-parse-utils\u003e\n\n\u003c!-- auto-generated, do not modify here but in src/utility/parse-utils.sh.doc --\u003e\n```bash\n#!/usr/bin/env bash\nset -euo pipefail\nshopt -s inherit_errexit || { echo \u003e\u00262 \"please update to bash 5, see errors above\" \u0026\u0026 exit 1; }\nMY_LIBRARY_VERSION=\"v1.0.3\"\n\nif ! [[ -v dir_of_tegonal_scripts ]]; then\n\t# Assumes tegonal's scripts were fetched with gt - adjust location accordingly\n\tdir_of_tegonal_scripts=\"$(cd -- \"$(dirname -- \"${BASH_SOURCE[0]:-$0}\")\" \u003e/dev/null \u0026\u0026 pwd 2\u003e/dev/null)/../lib/tegonal-scripts/src\"\n\tsource \"$dir_of_tegonal_scripts/setup.sh\" \"$dir_of_tegonal_scripts\"\nfi\nsourceOnce \"$dir_of_tegonal_scripts/utility/parse-utils.sh\"\n\nfunction myParseFunction() {\n\twhile (($# \u003e 0)); do\n\t\tif [[ $1 == \"--version\" ]]; then\n\t\t\tshift 1 || traceAndDie \"could not shift by 1\"\n\t\t\tprintVersion \"$MY_LIBRARY_VERSION\"\n\t\tfi\n\t\t#...\n\tdone\n}\n\nfunction myVersionPrinter() {\n\t# 3 defines that printVersion shall skip 3 stack frames to deduce the name of the script\n\t# makes only sense if we already know that this method is called indirectly\n\tprintVersion \"$MY_LIBRARY_VERSION\" 3\n}\n```\n\n\u003c/utility-parse-utils\u003e\n\n## Recursive `declare -p`\n\nUtility function to find out the initial `declare` statement after following `declare -n` statements\n\n\u003cutility-recursive-declare-p\u003e\n\n\u003c!-- auto-generated, do not modify here but in src/utility/recursive-declare-p.sh.doc --\u003e\n```bash\n#!/usr/bin/env bash\n# shellcheck disable=SC2034\nset -euo pipefail\nshopt -s inherit_errexit || { echo \u003e\u00262 \"please update to bash 5, see errors above\" \u0026\u0026 exit 1; }\n\n# Assumes tegonal's scripts were fetched with gt - adjust location accordingly\ndir_of_tegonal_scripts=\"$(cd -- \"$(dirname -- \"${BASH_SOURCE[0]:-$0}\")\" \u003e/dev/null \u0026\u0026 pwd 2\u003e/dev/null)/../lib/tegonal-scripts/src\"\nsource \"$dir_of_tegonal_scripts/setup.sh\" \"$dir_of_tegonal_scripts\"\n\nsource \"$dir_of_tegonal_scripts/utility/recursive-declare-p.sh\"\n\ndeclare -i tmp=1\ndeclare -n ref1=tmp\ndeclare -n ref2=ref1\ndeclare -n ref3=ref2\n\ndeclare r0 r1 r2 r3\nr0=$(recursiveDeclareP tmp)\nr1=$(recursiveDeclareP ref1)\nr2=$(recursiveDeclareP ref2)\nr3=$(recursiveDeclareP ref3)\n\nprintf \"%s\\n\" \"$r0\" \"$r1\" \"$r2\" \"$r3\"\n# declare -i tmp=\"1\"\n# declare -i tmp=\"1\"\n# declare -i tmp=\"1\"\n# declare -i tmp=\"1\"\n```\n\n\u003c/utility-recursive-declare-p\u003e\n\n## Replace Snippets\n\nIf you want to include some code in markdown files (or any other HTML-like file) then replace-snippet.sh could come in\nhandy.\n\nFull usage example:\n\n\u003cutility-replace-snippet\u003e\n\n\u003c!-- auto-generated, do not modify here but in src/utility/replace-snippet.sh.doc --\u003e\n```bash\n#!/usr/bin/env bash\nset -euo pipefail\nshopt -s inherit_errexit || { echo \u003e\u00262 \"please update to bash 5, see errors above\" \u0026\u0026 exit 1; }\n# Assumes tegonal's scripts were fetched with gt - adjust location accordingly\ndir_of_tegonal_scripts=\"$(cd -- \"$(dirname -- \"${BASH_SOURCE[0]:-$0}\")\" \u003e/dev/null \u0026\u0026 pwd 2\u003e/dev/null)/../lib/tegonal-scripts/src\"\nsource \"$dir_of_tegonal_scripts/setup.sh\" \"$dir_of_tegonal_scripts\"\n\nsource \"$dir_of_tegonal_scripts/utility/replace-snippet.sh\"\n\ndeclare file\nfile=$(mktemp)\necho \"\u003cmy-script\u003e\u003c/my-script\u003e\" \u003e \"$file\"\n\ndeclare dir fileName output\ndir=$(dirname \"$file\")\nfileName=$(basename \"$file\")\noutput=$(echo \"replace with your command\" | grep \"command\")\n\n# replaceSnippet file id dir pattern snippet\nreplaceSnippet my-script.sh my-script-help \"$dir\" \"$fileName\" \"$output\"\n\necho \"content\"\ncat \"$file\"\n\n# will search for \u003cmy-script-help\u003e...\u003c/my-script-help\u003e in the temp file and replace it with\n# \u003cmy-script-help\u003e\n#\n# \u003c!-- auto-generated, do not modify here but in my-snippet --\u003e\n# ```\n# output of executing $(myCommand)\n# ```\n# \u003c/my-script-help\u003e\n```\n\n\u003c/utility-replace-snippet\u003e\n\n## Secret utils\n\nUtility functions around secrets and `secret-tool`.\n\n\u003cutility-secret-utils\u003e\n\n\u003c!-- auto-generated, do not modify here but in src/utility/secret-utils.sh.doc --\u003e\n```bash\n#!/usr/bin/env bash\nset -euo pipefail\nshopt -s inherit_errexit || { echo \u003e\u00262 \"please update to bash 5, see errors above\" \u0026\u0026 exit 1; }\n# Assumes tegonal's scripts were fetched with gt - adjust location accordingly\ndir_of_tegonal_scripts=\"$(cd -- \"$(dirname -- \"${BASH_SOURCE[0]:-$0}\")\" \u003e/dev/null \u0026\u0026 pwd 2\u003e/dev/null)/../lib/tegonal-scripts/src\"\nsource \"$dir_of_tegonal_scripts/setup.sh\" \"$dir_of_tegonal_scripts\"\n\nsource \"$dir_of_tegonal_scripts/utility/secret-utils.sh\"\n\n# stores the entered password into the variable `secret`\npromptForSecret \"enter your password: \" secret\n\n# retrieves a secret identified by `group` and `key` via secret-tool from the login keyring\n# shellcheck disable=SC2034\t# we know secret is not used, only a sample\nsecret=\"$(getSecretViaSecretTool \"group\" \"key\")\"\n\n# stores the secret identified by `group` and `key` and value `mySecret` via secret-tool into the login keyring\nstoreSecretViaSecretTool \"group\" \"key\" \"label as shown in e.g. seahorse\" \"mySecret\"\n\n# stores the secret identified by `group` and `key` via secret-tool into the login keyring\n# uses stdin as input (prompts for a password if there is no input)\nstoreSecretViaSecretTool \"group\" \"key\" \"label as shown in e.g. seahorse\"\n\n# retrieves a secret identified by `group` and `key` via secret-tool from the login keyring and\n# stores it in the variable password. If the secret does not exist yet, then the given prompt is used and the secret is\n# stores accordingly\ngetSecretViaSecretToolOrPromptAndStore \"group\" \"key\" \"label as shown in e.g. seahorse\" \"enter your password: \" password\n```\n\n\u003c/utility-secret-utils\u003e\n\n## Source once\n\nEstablishes a guard by creating a variable based on the file which shall be sourced.\n\n\u003cutility-source-once\u003e\n\n\u003c!-- auto-generated, do not modify here but in src/utility/source-once.sh.doc --\u003e\n```bash\n#!/usr/bin/env bash\nset -euo pipefail\nshopt -s inherit_errexit || { echo \u003e\u00262 \"please update to bash 5, see errors above\" \u0026\u0026 exit 1; }\n# Assumes tegonal's scripts were fetched with gt - adjust location accordingly\ndir_of_tegonal_scripts=\"$(cd -- \"$(dirname -- \"${BASH_SOURCE[0]:-$0}\")\" \u003e/dev/null \u0026\u0026 pwd 2\u003e/dev/null)/../lib/tegonal-scripts/src\"\nsource \"$dir_of_tegonal_scripts/setup.sh\" \"$dir_of_tegonal_scripts\"\n\nsource \"$dir_of_tegonal_scripts/utility/source-once.sh\"\n\nsourceOnce \"foo.sh\"    # creates a variable named sourceOnceGuard_foo__sh which acts as guard and sources foo.sh\nsourceOnce \"foo.sh\"    # will source nothing as sourceOnceGuard_foo__sh is already defined\nunset sourceOnceGuard_foo__sh          # unsets the guard\nsourceOnce \"foo.sh\"    # is sourced again and the guard established\n# you can also use sourceAlways instead of unsetting and using sourceOnce.\nsourceAlways \"foo.sh\"\n\n# creates a variable named sourceOnceGuard_bar__foo__sh which acts as guard and sources bar/foo.sh\nsourceOnce \"bar/foo.sh\"\n\n# will source nothing, only the parent dir + file is used as identifier\n# i.e. the corresponding guard is sourceOnceGuard_bar__foo__sh and thus this file is not sourced\nsourceOnce \"asdf/bar/foo.sh\"\n\ndeclare guard\nguard=$(determineSourceOnceGuard \"src/bar.sh\")\n# In case you don't want that a certain file is sourced, then you can define the guard yourself\n# this will prevent that */src/bar.sh is sourced\nprintf -v \"$guard\" \"%s\" \"true\"\n```\n\n\u003c/utility-source-once\u003e\n\n## string utils\n\nString processing utils\n\n\u003cutility-string-utils\u003e\n\n\u003c!-- auto-generated, do not modify here but in src/utility/string-utils.sh.doc --\u003e\n```bash\n#!/usr/bin/env bash\nset -euo pipefail\nshopt -s inherit_errexit || { echo \u003e\u00262 \"please update to bash 5, see errors above\" \u0026\u0026 exit 1; }\n# Assumes tegonal's scripts were fetched with gt - adjust location accordingly\ndir_of_tegonal_scripts=\"$(cd -- \"$(dirname -- \"${BASH_SOURCE[0]:-$0}\")\" \u003e/dev/null \u0026\u0026 pwd 2\u003e/dev/null)/../lib/tegonal-scripts/src\"\nsource \"$dir_of_tegonal_scripts/setup.sh\" \"$dir_of_tegonal_scripts\"\n\nsource \"$dir_of_tegonal_scripts/utility/string-utils.sh\"\n\n# will output v4\\.2\\.0\nescapeRegex \"v4.2.0\"\n\n# useful in combination with grep which does not support literal searches:\n# escapes to tegonal\\+\npattern=$(escapeRegex \"tegonal+\")\ngrep -E \"$pattern\"\n```\n\n\u003c/utility-string-utils\u003e\n\n\n## Update Bash documentation\n\nUpdates the `Usage` section of a bash file based on a sibling doc which is named *.doc.sh (e.g foo.sh and foo.doc.sh).\nMoreover, it uses [Replace Snippets](#replace-snippets) to update a corresponding snippet in the specified files.\n\nFull usage example:\n\n\u003cutility-update-bash-docu\u003e\n\n\u003c!-- auto-generated, do not modify here but in src/utility/update-bash-docu.sh.doc --\u003e\n```bash\n#!/usr/bin/env bash\nset -euo pipefail\nshopt -s inherit_errexit || { echo \u003e\u00262 \"please update to bash 5, see errors above\" \u0026\u0026 exit 1; }\n# Assumes tegonal's scripts were fetched with gt - adjust location accordingly\ndir_of_tegonal_scripts=\"$(cd -- \"$(dirname -- \"${BASH_SOURCE[0]:-$0}\")\" \u003e/dev/null \u0026\u0026 pwd 2\u003e/dev/null)/../lib/tegonal-scripts/src\"\nsource \"$dir_of_tegonal_scripts/setup.sh\" \"$dir_of_tegonal_scripts\"\n\nsource \"$dir_of_tegonal_scripts/utility/update-bash-docu.sh\"\n\nfind . -name \"*.sh\" \\\n\t-not -name \"*.doc.sh\" \\\n\t-print0 |\n\twhile read -r -d $'\\0' script; do\n\t\tdeclare script=\"${script:2}\"\n\t\tupdateBashDocumentation \"$dir_of_tegonal_scripts/$script\" \"${script////-}\" . README.md\n\tdone\n```\n\n\u003c/utility-update-bash-docu\u003e\n\n# Contributors and contribute\n\nOur thanks go to [code contributors](https://github.com/tegonal/scripts/graphs/contributors)\nas well as all other contributors (e.g. bug reporters, feature request creators etc.)\n\nYou are more than welcome to contribute as well:\n\n- star this repository if you like/use it\n- [open a bug](https://github.com/tegonal/scripts/issues/new?template=bug_report.md) if you find one\n- Open a [new discussion](https://github.com/tegonal/scripts/discussions/new?category=ideas) if you are missing a\n  feature\n- [ask a question](https://github.com/tegonal/scripts/discussions/new?category=q-a)\n  so that we better understand where our scripts need to improve.\n- have a look at\n  the [help wanted issues](https://github.com/tegonal/scripts/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22)\n  if you would like to code.\n\nPlease have a look at\n[CONTRIBUTING.md](https://github.com/tegonal/scripts/tree/main/.github/CONTRIBUTING.md)\nfor further suggestions and guidelines.\n\n# License\n\nThe provided scripts are licensed under [Apache 2.0](http://opensource.org/licenses/Apache2.0).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftegonal%2Fscripts","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftegonal%2Fscripts","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftegonal%2Fscripts/lists"}