Add development-scripts agent skill
Ports generic-scripts-module-v1 into a routed skill: module anatomy, shared loggers/base modules, Taskfile integration, workflows, and pattern decisions. Fixes a latent defect in the loggers example that silenced all logging in the module scaffold: loggers/lib/--index-api.sh now sources --env-vars-reader.sh, and the reader preserves already-exported values so caller overrides still win. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1 +1,55 @@
|
||||
# development-scripts
|
||||
|
||||
Agent Skill for shell script modules under a repository's `.scripts/` directory — the
|
||||
`api/` + `lib/` split, the `--index.sh` bootstrap chain, Taskfile integration, and the shared
|
||||
`loggers` and `base` foundation modules.
|
||||
|
||||
## Layout
|
||||
|
||||
```text
|
||||
development-scripts/
|
||||
├── SKILL.md # Entry point — routing, anatomy, naming, runtime flow
|
||||
├── references/
|
||||
│ ├── module-anatomy.md # Reader, validator, index files, implementations, wrappers
|
||||
│ ├── shared-modules.md # loggers and base, and the logging bootstrap rule
|
||||
│ ├── taskfile.md # Module and root Taskfile integration
|
||||
│ ├── workflows.md # Create, change, validate
|
||||
│ └── module-patterns.md # Module type and dependency decision guide
|
||||
└── assets/
|
||||
├── module-example-v1/ # Scaffold to copy for a new module
|
||||
├── loggers/ # Working reference implementation
|
||||
└── base/ # Working reference implementation
|
||||
```
|
||||
|
||||
## The model
|
||||
|
||||
```text
|
||||
<target-repository>/
|
||||
Taskfile.yml
|
||||
.scripts/
|
||||
<module>/
|
||||
api/ # public command wrappers — what users run
|
||||
lib/ # implementation functions — what the code calls
|
||||
Taskfile.yml # only when exposed through task
|
||||
```
|
||||
|
||||
Commands run from the repository root:
|
||||
|
||||
```bash
|
||||
./.scripts/<module>/api/<command>.sh --dry-run
|
||||
task <module-alias>:<task-name> -- --dry-run
|
||||
```
|
||||
|
||||
Every source path is repository-root-relative, and the bootstrap chain — reader, then
|
||||
validator, then API index — guarantees an implementation function sees a fully-prepared
|
||||
environment.
|
||||
|
||||
## Deploy
|
||||
|
||||
```bash
|
||||
cd ../skill-manager/scripts
|
||||
task deploy -- --skill-dir="$(cd ../../development-scripts && pwd)"
|
||||
```
|
||||
|
||||
Built with the `skill-manager` skill, following the
|
||||
[agentskills.io specification](https://agentskills.io/specification).
|
||||
|
||||
@@ -0,0 +1,198 @@
|
||||
---
|
||||
name: development-scripts
|
||||
description: >
|
||||
Create, refactor, review, document, and maintain shell script modules under a repository's
|
||||
.scripts/ directory — the api/ + lib/ split, the --index.sh / --index-api.sh /
|
||||
--env-vars-reader.sh / --env-vars-validator.sh bootstrap chain, module and root Taskfile.yml
|
||||
integration, logging through the shared loggers module, and shared helpers from the base
|
||||
module. Use when adding a new script module or a new command to an existing one; writing an
|
||||
api/ wrapper or a lib/ implementation function; adding a CLI flag or a required environment
|
||||
variable; wiring a module into task; debugging a script that produces no output, cannot find
|
||||
a function, or unexpectedly loads .env; or reviewing shell module work for naming, sourcing
|
||||
order, and secret-safety — even when the user only says ".scripts", "Taskfile", "task
|
||||
runner", "shell module", or names a specific module like loggers or base.
|
||||
license: Proprietary
|
||||
metadata:
|
||||
author: workspace-skills-code-agent
|
||||
version: "1.0"
|
||||
spec: agentskills.io/specification
|
||||
compatibility: Requires bash. Taskfile (task) needed only for task-runner integration. Designed for Cline, Claude Code, GitHub Copilot, OpenAI Codex, and other compatible agent environments
|
||||
---
|
||||
|
||||
# Repository Script Modules
|
||||
|
||||
Work rules for shell automation organised as modules under a repository's `.scripts/`
|
||||
directory, with a strict public/private split and a fixed sourcing order.
|
||||
|
||||
The whole model rests on one idea: **`api/` is what people run, `lib/` is what the code
|
||||
calls, and a single bootstrap chain guarantees that by the time an implementation function
|
||||
runs, its environment has been read, validated, and its dependencies sourced.**
|
||||
|
||||
## Scope routing
|
||||
|
||||
Pick the reference that matches the change; do not load all of them.
|
||||
|
||||
| The change touches | Read |
|
||||
|---|---|
|
||||
| A reader, validator, implementation function, or `api/` wrapper | `references/module-anatomy.md` |
|
||||
| The `loggers` or `base` module, or logging that produces no output | `references/shared-modules.md` |
|
||||
| A module `Taskfile.yml` or the root `Taskfile.yml` | `references/taskfile.md` |
|
||||
| Creating a module, changing one, or checking work before delivery | `references/workflows.md` |
|
||||
| Deciding what kind of module something should be | `references/module-patterns.md` |
|
||||
|
||||
Copy-ready modules live in `assets/`: `module-example-v1/` is the scaffold for a new module;
|
||||
`loggers/` and `base/` are working reference implementations.
|
||||
|
||||
## 1. Repository model
|
||||
|
||||
```text
|
||||
<target-repository>/
|
||||
Taskfile.yml # root task runner, includes module Taskfiles
|
||||
.scripts/
|
||||
<module>/
|
||||
api/ # public command wrappers — what users run
|
||||
lib/ # implementation functions — what the code calls
|
||||
Taskfile.yml # only when the module is exposed through task
|
||||
```
|
||||
|
||||
Commands always run **from the repository root**, never from inside the module:
|
||||
|
||||
```bash
|
||||
./.scripts/<module>/api/<command>.sh [args]
|
||||
task <module-alias>:<task-name> -- [args]
|
||||
```
|
||||
|
||||
Every `.` source path in every file is written relative to the repository root
|
||||
(`. ./.scripts/loggers/lib/--index-api.sh`). This is why running a script from inside its own
|
||||
directory fails to find its dependencies — that is the convention working as designed, not a
|
||||
bug to patch with `dirname "$0"`.
|
||||
|
||||
## 2. Module anatomy
|
||||
|
||||
```text
|
||||
.scripts/<module>/
|
||||
api/
|
||||
<command-name>.sh
|
||||
lib/
|
||||
--env-vars-reader.sh # defaults + CLI flag parsing
|
||||
--env-vars-validator.sh # required-input checks
|
||||
--index-api.sh # sources dependencies + this module's implementations
|
||||
--index.sh # full runtime bootstrap
|
||||
-<command-name>.sh # one implementation function per command
|
||||
Taskfile.yml # optional
|
||||
```
|
||||
|
||||
| File | Responsibility |
|
||||
|---|---|
|
||||
| `api/<command>.sh` | Thin public entrypoint. Sources `lib/--index.sh`, calls one function. |
|
||||
| `lib/-<command>.sh` | The command implementation function. |
|
||||
| `lib/--index-api.sh` | Sources upstream module APIs, then this module's implementation files. |
|
||||
| `lib/--index.sh` | Runtime bootstrap: reader, then validator, then API index. |
|
||||
| `lib/--env-vars-reader.sh` | Exports defaults and parses CLI arguments into environment variables. |
|
||||
| `lib/--env-vars-validator.sh` | Validates required variables, failing with an actionable log. |
|
||||
| `Taskfile.yml` | Maps task names to `api/` scripts, forwarding `{{.CLI_ARGS}}`. |
|
||||
|
||||
Not every module has every file — a support-only library like `loggers` has no `api/` and no
|
||||
`Taskfile.yml`. See `references/module-patterns.md`.
|
||||
|
||||
## 3. Standard runtime flow
|
||||
|
||||
```text
|
||||
api/<command>.sh
|
||||
└── source lib/--index.sh
|
||||
├── source lib/--env-vars-reader.sh # defaults + CLI flags → env vars
|
||||
├── source lib/--env-vars-validator.sh # required vars present?
|
||||
└── source lib/--index-api.sh
|
||||
├── source dependencies (loggers, base, …)
|
||||
└── source lib/-<command>.sh # defines the function
|
||||
└── call _<moduleNamespace>_<commandFunction>
|
||||
```
|
||||
|
||||
**The order is load-bearing.** The reader runs before the validator so the validator has
|
||||
something to check; both run before the API index so implementation functions see a
|
||||
fully-prepared environment. Reordering produces failures that look like missing variables.
|
||||
|
||||
Arguments reach the reader because sourcing happens with the wrapper's own arguments still in
|
||||
scope — this is why `api/` wrappers need no argument forwarding of their own.
|
||||
|
||||
## 4. Naming conventions
|
||||
|
||||
| Kind | Convention | Example |
|
||||
|---|---|---|
|
||||
| Module directory | lowercase kebab-case | `module-example-v1`, `repositories-nodejs` |
|
||||
| Public command | lowercase kebab-case, action-oriented | `initialize-one.sh`, `find-many-by-query.sh` |
|
||||
| Implementation file | single leading dash | `lib/-initialize-one.sh` |
|
||||
| Index / lifecycle file | double leading dash | `lib/--index.sh`, `lib/--env-vars-reader.sh` |
|
||||
| Function | `_<moduleNamespace>_<actionName>` | `_moduleExampleV1_initializeOne` |
|
||||
| Environment variable | uppercase module prefix | `MODULE_EXAMPLE_V1_OUTPUT_DIR` |
|
||||
|
||||
Kebab-case module names convert to camelCase function namespaces:
|
||||
|
||||
| Module | Function prefix | Env prefix |
|
||||
|---|---|---|
|
||||
| `module-example-v1` | `_moduleExampleV1_` | `MODULE_EXAMPLE_V1_` |
|
||||
| `repositories-nodejs` | `_repositoriesNodejs_` | `REPOSITORIES_NODEJS_` |
|
||||
| `operation-utilities` | `_operationUtilities_` | `OPERATION_UTILITIES_` |
|
||||
|
||||
The dash count is not decoration — it is how you tell at a glance whether a file defines a
|
||||
command (`-name.sh`) or wires the module together (`--name.sh`).
|
||||
|
||||
## 5. Non-negotiable rules
|
||||
|
||||
- **`api/` wrappers stay thin.** Source `lib/--index.sh`, call one function, nothing else. No
|
||||
implementation, no argument parsing, no validation.
|
||||
- **CLI flags are parsed only in `--env-vars-reader.sh`.** Never in an implementation file.
|
||||
- **Every new `lib/-*.sh` gets added to `lib/--index-api.sh`.** Forgetting this is the most
|
||||
common cause of "command not found" for a function that plainly exists.
|
||||
- **Readers preserve already-exported values** — `export X="${X:-default}"` — so a caller can
|
||||
override any setting before invoking the module.
|
||||
- **Log through `_loggers_*` helpers, never raw `echo`.** Loggers write to `stderr`, keeping
|
||||
`stdout` clean for real output.
|
||||
- **Never log secrets.** Redact tokens, API keys, passwords, and kube config.
|
||||
- **Quote variable expansions** unless word splitting is intended.
|
||||
- **`return` non-zero from implementation functions; reserve `exit 1` for validators and
|
||||
bootstrap.** An `exit` inside a sourced library kills the caller's shell.
|
||||
|
||||
## 6. Creating a module
|
||||
|
||||
Full walkthrough in `references/workflows.md`. The short path:
|
||||
|
||||
1. Copy `assets/module-example-v1/` to `.scripts/<new-module>/`.
|
||||
2. Replace every `module-example-v1` path, the `MODULE_EXAMPLE_V1_` env prefix, and the
|
||||
`_moduleExampleV1_` function prefix.
|
||||
3. Add implementation files as `lib/-<command>.sh` and source them from `lib/--index-api.sh`.
|
||||
4. Add `api/<command>.sh` wrappers for user-facing commands only.
|
||||
5. Add a module `Taskfile.yml`, and a root include only if the namespace is stable.
|
||||
6. Validate (section 7).
|
||||
|
||||
## 7. Validation
|
||||
|
||||
```bash
|
||||
# Syntax-check every script in the module
|
||||
find .scripts/<module> -name '*.sh' -print0 | xargs -0 -n1 bash -n
|
||||
|
||||
# Confirm task exposure resolves
|
||||
task --list
|
||||
|
||||
# Run the command itself, from the repository root
|
||||
./.scripts/<module>/api/<command>.sh --dry-run
|
||||
```
|
||||
|
||||
`bash -n` catches syntax errors but **not** a missing entry in `--index-api.sh` — that only
|
||||
surfaces at call time. Always run the command once, from the repository root, before
|
||||
delivering. A dry-run flag is worth adding precisely so this check is cheap.
|
||||
|
||||
## 8. Mistakes to avoid
|
||||
|
||||
- Putting implementation logic into `api/*.sh`.
|
||||
- Adding a `lib/-*.sh` file and forgetting to source it from `lib/--index-api.sh`.
|
||||
- Parsing CLI flags in an implementation function instead of the reader.
|
||||
- Sourcing `base/lib/--index.sh` from a library function — it reads `.env` and
|
||||
environment-specific files as a side effect. Use `base/lib/--index-api.sh` when you only
|
||||
need shared functions.
|
||||
- Writing source paths relative to the script instead of the repository root.
|
||||
- Using `exit` inside a sourced implementation function.
|
||||
- Printing secrets, or documenting their values.
|
||||
- Adding a root `Taskfile.yml` include for an experimental module.
|
||||
- Assuming logging works because the code compiles — a logger whose level flags were never
|
||||
exported is silent and returns 0. See `references/shared-modules.md` §3.
|
||||
@@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
# -------------------------------------------------------------------------------------
|
||||
# IBM Confidential
|
||||
# 6949-70F, 6949-80D
|
||||
# © Copyright IBM Corp. 2018, 2024
|
||||
# US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
|
||||
# -------------------------------------------------------------------------------------
|
||||
|
||||
. ./.scripts/base/lib/--index.sh
|
||||
|
||||
_base_localStorage_ensureExistance_fileDotEnv
|
||||
@@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
# -------------------------------------------------------------------------------------
|
||||
# IBM Confidential
|
||||
# 6949-70F, 6949-80D
|
||||
# © Copyright IBM Corp. 2018, 2024
|
||||
# US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
|
||||
# -------------------------------------------------------------------------------------
|
||||
|
||||
. ./.scripts/base/lib/--index.sh
|
||||
|
||||
_base_localStorage_readLinesFrom_fileDotEnv
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
# -------------------------------------------------------------------------------------
|
||||
# IBM Confidential
|
||||
# 6949-70F, 6949-80D
|
||||
# © Copyright IBM Corp. 2018, 2024
|
||||
# US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
|
||||
# -------------------------------------------------------------------------------------
|
||||
|
||||
. ./.scripts/base/lib/--index.sh
|
||||
|
||||
_base_localStorage_reset_fileDotEnv
|
||||
@@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
# -------------------------------------------------------------------------------------
|
||||
# IBM Confidential
|
||||
# 6949-70F, 6949-80D
|
||||
# © Copyright IBM Corp. 2018, 2024
|
||||
# US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
|
||||
# -------------------------------------------------------------------------------------
|
||||
|
||||
. ./.scripts/base/lib/--index.sh
|
||||
|
||||
_base_localStorage_saveEnvVariable2_fileDotEnv
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
# -------------------------------------------------------------------------------------
|
||||
# IBM Confidential
|
||||
# 6949-70F, 6949-80D
|
||||
# © Copyright IBM Corp. 2018, 2024
|
||||
# US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
|
||||
# -------------------------------------------------------------------------------------
|
||||
|
||||
. ./.scripts/base/lib/--index.sh
|
||||
|
||||
_base_localStorage_view_fileDotEnv
|
||||
Executable
+75
@@ -0,0 +1,75 @@
|
||||
#!/bin/bash
|
||||
# -------------------------------------------------------------------------------------
|
||||
# IBM Confidential
|
||||
# 6949-70F, 6949-80D
|
||||
# © Copyright IBM Corp. 2018, 2024
|
||||
# US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
|
||||
# -------------------------------------------------------------------------------------
|
||||
|
||||
. ./.scripts/loggers/lib/--env-vars-reader.sh
|
||||
|
||||
TMP_BASE_LIB_ENV_VARS_READER=".scripts/base/lib/--env-vars-reader.sh"
|
||||
|
||||
export LOCAL_OS_TYPE="darwin"
|
||||
export LOCAL_CPU_TYPE="amd64"
|
||||
export LOCAL_HOME_DIR=$(pwd)
|
||||
export LOCAL_HOME_DIR_NAME=${PWD##*/}
|
||||
export LOCAL_GIT_ROOT_DIR=$(dirname "${LOCAL_HOME_DIR}")
|
||||
export LOCAL_CACHE_DIR_KUBE=".kube"
|
||||
|
||||
export LOCAL_FILE_DOT_ENV=".env"
|
||||
|
||||
# Pre-load CA_ENVIRONMENT from .env if not already set
|
||||
if [ -z "${CA_ENVIRONMENT}" ] && [ -f "${LOCAL_FILE_DOT_ENV}" ]; then
|
||||
export CA_ENVIRONMENT=$(grep '^CA_ENVIRONMENT=' "${LOCAL_FILE_DOT_ENV}" | cut -d'=' -f2- | tr -d '"' | tr -d "'")
|
||||
fi
|
||||
|
||||
export LOCAL_FILE_DOT_ENV_CA_ENVIRONMENT=".env-${CA_ENVIRONMENT}"
|
||||
|
||||
. ./.scripts/base/lib/-export-env-variables-from-file-dot-env.sh
|
||||
|
||||
_loggers_info "${CA_ENVIRONMENT}" "CA_ENVIRONMENT: ${CA_ENVIRONMENT}"
|
||||
_loggers_info "${CA_ENVIRONMENT}" "LOCAL_FILE_DOT_ENV: ${LOCAL_FILE_DOT_ENV}"
|
||||
_loggers_info "${CA_ENVIRONMENT}" "LOCAL_FILE_DOT_ENV_CA_ENVIRONMENT: ${LOCAL_FILE_DOT_ENV_CA_ENVIRONMENT}"
|
||||
|
||||
if
|
||||
[ ! -e "${LOCAL_FILE_DOT_ENV}" ]
|
||||
then
|
||||
_loggers_error "${LOCAL_FILE_DOT_ENV}" "Missing ${LOCAL_FILE_DOT_ENV} file."
|
||||
exit 1
|
||||
else
|
||||
set -o allexport
|
||||
. "./${LOCAL_FILE_DOT_ENV}"
|
||||
set +o allexport
|
||||
fi
|
||||
|
||||
if
|
||||
[ ! -e "${LOCAL_FILE_DOT_ENV_CA_ENVIRONMENT}" ]
|
||||
then
|
||||
_loggers_error "${TMP_BASE_LIB_ENV_VARS_READER}" "Missing ${LOCAL_FILE_DOT_ENV_CA_ENVIRONMENT} file."
|
||||
exit 1
|
||||
else
|
||||
set -o allexport
|
||||
. "./${LOCAL_FILE_DOT_ENV_CA_ENVIRONMENT}"
|
||||
set +o allexport
|
||||
fi
|
||||
|
||||
mkdir -p "${LOCAL_CACHE_DIR_KUBE}"
|
||||
|
||||
ALL_ARGS=("$@")
|
||||
while [[ "$#" -gt 0 ]]; do
|
||||
case $1 in
|
||||
--local-os-type)
|
||||
export LOCAL_OS_TYPE="$2"
|
||||
;;
|
||||
--local-cpu-type)
|
||||
export LOCAL_CPU_TYPE="$2"
|
||||
;;
|
||||
--local-file-dot-env)
|
||||
export LOCAL_FILE_DOT_ENV="$2"
|
||||
;;
|
||||
*) ;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
set -- "${ALL_ARGS[@]}"
|
||||
Executable
+15
@@ -0,0 +1,15 @@
|
||||
#!/bin/bash
|
||||
# -------------------------------------------------------------------------------------
|
||||
# IBM Confidential
|
||||
# 6949-70F, 6949-80D
|
||||
# © Copyright IBM Corp. 2018, 2024
|
||||
# US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
|
||||
# -------------------------------------------------------------------------------------
|
||||
|
||||
. ./.scripts/loggers/lib/--index-api.sh
|
||||
|
||||
. ./.scripts/base/lib/-ensure-env-var-ibm-user-email.sh
|
||||
. ./.scripts/base/lib/-ensure-env-var-ibm-user-api-key.sh
|
||||
|
||||
_base_ensureEnvVarIbmUserEmail
|
||||
_base_ensureEnvVarIbmUserApiKey
|
||||
Executable
+19
@@ -0,0 +1,19 @@
|
||||
#!/bin/bash
|
||||
# -------------------------------------------------------------------------------------
|
||||
# IBM Confidential
|
||||
# 6949-70F, 6949-80D
|
||||
# © Copyright IBM Corp. 2018, 2024
|
||||
# US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
|
||||
# -------------------------------------------------------------------------------------
|
||||
|
||||
. ./.scripts/base/lib/-export-env-variable.sh
|
||||
. ./.scripts/base/lib/-export-env-variables-from-file-dot-env.sh
|
||||
. ./.scripts/base/lib/-export-env-variables-from-file.sh
|
||||
|
||||
. ./.scripts/base/lib/-get-env-variable-key-from-line.sh
|
||||
. ./.scripts/base/lib/-get-env-variable-value-from-line.sh
|
||||
|
||||
. ./.scripts/base/lib/local-storage/--index-api.sh
|
||||
|
||||
. ./.scripts/base/lib/-log-env-vars.sh
|
||||
. ./.scripts/base/lib/-prompt-for-env-var.sh
|
||||
Executable
+24
@@ -0,0 +1,24 @@
|
||||
#!/bin/bash
|
||||
# -------------------------------------------------------------------------------------
|
||||
# IBM Confidential
|
||||
# 6949-70F, 6949-80D
|
||||
# © Copyright IBM Corp. 2018, 2024
|
||||
# US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
|
||||
# -------------------------------------------------------------------------------------
|
||||
#
|
||||
# --> passed parameters are read & exported environment variables
|
||||
#
|
||||
. ./.scripts/base/lib/--env-vars-reader.sh
|
||||
#
|
||||
# --> required environment variables are validated for existance
|
||||
#
|
||||
. ./.scripts/base/lib/--env-vars-validator.sh
|
||||
#
|
||||
# --> Importing local shell packages
|
||||
#
|
||||
. ./.scripts/loggers/lib/--index-api.sh
|
||||
#
|
||||
# --> available functions are imported/exported
|
||||
#
|
||||
. ./.scripts/base/lib/--index-api.sh
|
||||
# -------------------------------------------------------------------------------------
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
#!/bin/bash
|
||||
# -------------------------------------------------------------------------------------
|
||||
# IBM Confidential
|
||||
# 6949-70F, 6949-80D
|
||||
# © Copyright IBM Corp. 2018, 2024
|
||||
# US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
|
||||
# -------------------------------------------------------------------------------------
|
||||
set -e
|
||||
|
||||
. ./.scripts/loggers/lib/--index-api.sh
|
||||
|
||||
. ./.scripts/base/lib/local-storage/--index-api.sh
|
||||
|
||||
_base_ensureEnvVarIbmUserApiKey() {
|
||||
local FUNCTION_NAME="_base_ensureEnvVarIbmUserApiKey"
|
||||
|
||||
local TMP_IBM_USER_API_KEY=""
|
||||
if
|
||||
[ -z "${IBM_USER_API_KEY}" ]
|
||||
then
|
||||
while
|
||||
true
|
||||
do
|
||||
_loggers_emptyLine
|
||||
read -rep $'Provide for IBM_USER_API_KEY environment variable! \n\n> ' TMP_IBM_USER_API_KEY
|
||||
if
|
||||
[ ! -z "${TMP_IBM_USER_API_KEY}" ]
|
||||
then
|
||||
export IBM_USER_API_KEY="${TMP_IBM_USER_API_KEY}"
|
||||
export ENV_VAR_KEY="IBM_USER_API_KEY"
|
||||
export ENV_VAR_VALUE="${IBM_USER_API_KEY}"
|
||||
_base_localStorage_saveEnvVariable2_fileDotEnv
|
||||
break
|
||||
else
|
||||
_loggers_emptyLine
|
||||
_loggers_warn "${FUNCTION_NAME}" "Provided value can not be empty!"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
_loggers_debug "${FUNCTION_NAME}" "IBM_USER_API_KEY: *REDACTED*"
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
#!/bin/bash
|
||||
# -------------------------------------------------------------------------------------
|
||||
# IBM Confidential
|
||||
# 6949-70F, 6949-80D
|
||||
# © Copyright IBM Corp. 2018, 2024
|
||||
# US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
|
||||
# -------------------------------------------------------------------------------------
|
||||
set -e
|
||||
|
||||
. ./.scripts/loggers/lib/--index-api.sh
|
||||
|
||||
. ./.scripts/base/lib/local-storage/--index-api.sh
|
||||
|
||||
_base_ensureEnvVarIbmUserEmail() {
|
||||
local FUNCTION_NAME="_base_ensureEnvVarIbmUserEmail"
|
||||
|
||||
local TMP_IBM_USER_EMAIL=""
|
||||
if
|
||||
[ -z "${IBM_USER_EMAIL}" ]
|
||||
then
|
||||
while
|
||||
true
|
||||
do
|
||||
_loggers_emptyLine
|
||||
read -rep $'Provide for IBM_USER_EMAIL environment variable! \n\n> ' TMP_IBM_USER_EMAIL
|
||||
if
|
||||
[ ! -z "${TMP_IBM_USER_EMAIL}" ]
|
||||
then
|
||||
export IBM_USER_EMAIL="${TMP_IBM_USER_EMAIL}"
|
||||
export ENV_VAR_KEY="IBM_USER_EMAIL"
|
||||
export ENV_VAR_VALUE="${IBM_USER_EMAIL}"
|
||||
_base_localStorage_saveEnvVariable2_fileDotEnv
|
||||
break
|
||||
else
|
||||
_loggers_emptyLine
|
||||
_loggers_warn "${FUNCTION_NAME}" "Provided value can not be empty!"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
_loggers_debug "${FUNCTION_NAME}" "IBM_USER_EMAIL: ${IBM_USER_EMAIL}"
|
||||
}
|
||||
Executable
+34
@@ -0,0 +1,34 @@
|
||||
#!/bin/bash
|
||||
# -------------------------------------------------------------------------------------
|
||||
# IBM Confidential
|
||||
# 6949-70F, 6949-80D
|
||||
# © Copyright IBM Corp. 2018, 2024
|
||||
# US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
|
||||
# -------------------------------------------------------------------------------------
|
||||
|
||||
. ./.scripts/loggers/lib/--index-api.sh
|
||||
|
||||
_base_ensure_evnVarKey() {
|
||||
local FUNCTION_NAME="_base_ensure_evnVarKey"
|
||||
_loggers_debug "${FUNCTION_NAME}"
|
||||
|
||||
while
|
||||
true
|
||||
do
|
||||
if
|
||||
[ ! -z "${ENV_VAR_KEY}" ]
|
||||
then
|
||||
break
|
||||
fi
|
||||
_loggers_emptyLine
|
||||
read -rep $'Provide environment variable key! \n> ' TMP_ENV_VAR_KEY
|
||||
if
|
||||
[ -z "$TMP_ENV_VAR_KEY" ]
|
||||
then
|
||||
_loggers_errorX "${FUNCTION_NAME}" "Provided environment variable key can not be empty!"
|
||||
else
|
||||
export ENV_VAR_KEY="$TMP_ENV_VAR_KEY"
|
||||
fi
|
||||
_loggers_emptyLine
|
||||
done
|
||||
}
|
||||
Executable
+34
@@ -0,0 +1,34 @@
|
||||
#!/bin/bash
|
||||
# -------------------------------------------------------------------------------------
|
||||
# IBM Confidential
|
||||
# 6949-70F, 6949-80D
|
||||
# © Copyright IBM Corp. 2018, 2024
|
||||
# US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
|
||||
# -------------------------------------------------------------------------------------
|
||||
|
||||
. ./.scripts/loggers/lib/--index-api.sh
|
||||
|
||||
_base_ensure_evnVarValue() {
|
||||
local FUNCTION_NAME="_base_ensure_evnVarValue"
|
||||
_loggers_debug "${FUNCTION_NAME}"
|
||||
|
||||
while
|
||||
true
|
||||
do
|
||||
if
|
||||
[ ! -z "${ENV_VAR_VALUE}" ]
|
||||
then
|
||||
break
|
||||
fi
|
||||
_loggers_emptyLine
|
||||
read -rep $'Provide environment variable value! \n> ' TMP_ENV_VAR_VALUE
|
||||
if
|
||||
[ -z "${TMP_ENV_VAR_VALUE}" ]
|
||||
then
|
||||
_loggers_errorX "${FUNCTION_NAME}" "Provided environment variable value can not be empty!"
|
||||
else
|
||||
export ENV_VAR_VALUE="${TMP_ENV_VAR_VALUE}"
|
||||
fi
|
||||
_loggers_emptyLine
|
||||
done
|
||||
}
|
||||
Executable
+35
@@ -0,0 +1,35 @@
|
||||
#!/bin/bash
|
||||
# -------------------------------------------------------------------------------------
|
||||
# IBM Confidential
|
||||
# 6949-70F, 6949-80D
|
||||
# © Copyright IBM Corp. 2018, 2024
|
||||
# US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
|
||||
# -------------------------------------------------------------------------------------
|
||||
|
||||
. ./.scripts/loggers/lib/--index-api.sh
|
||||
|
||||
_base_exportEnvVariable() {
|
||||
local FUNCTION_NAME="_base_exportEnvVariable"
|
||||
|
||||
local PARAM_ENV_VAR_KEY="${1}"
|
||||
local PARAM_ENV_VAR_VALUE="${2}"
|
||||
|
||||
if
|
||||
[ true ] &&
|
||||
[ ! -z "${PARAM_ENV_VAR_KEY}" ] &&
|
||||
[ ! -z "${PARAM_ENV_VAR_VALUE}" ]
|
||||
then
|
||||
_loggers_trace "${FUNCTION_NAME}" "PARAM_ENV_VAR_KEY: ${PARAM_ENV_VAR_KEY}"
|
||||
_loggers_trace "${FUNCTION_NAME}" "PARAM_ENV_VAR_VALUE: ${PARAM_ENV_VAR_VALUE}"
|
||||
|
||||
printf -v "${PARAM_ENV_VAR_KEY}" "${PARAM_ENV_VAR_VALUE}"
|
||||
export $PARAM_ENV_VAR_KEY
|
||||
else
|
||||
_loggers_warn "${FUNCTION_NAME}"
|
||||
_loggers_warn "${FUNCTION_NAME}" "Missing one of passed parameters!"
|
||||
_loggers_warn "${FUNCTION_NAME}" ""
|
||||
_loggers_warn "${FUNCTION_NAME}" "PARAM_ENV_VAR_KEY: ${PARAM_ENV_VAR_KEY}"
|
||||
_loggers_warn "${FUNCTION_NAME}" "PARAM_ENV_VAR_VALUE: ${PARAM_ENV_VAR_VALUE}"
|
||||
fi
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#!/bin/bash
|
||||
# -------------------------------------------------------------------------------------
|
||||
# IBM Confidential
|
||||
# 6949-70F, 6949-80D
|
||||
# © Copyright IBM Corp. 2018, 2024
|
||||
# US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
|
||||
# -------------------------------------------------------------------------------------
|
||||
|
||||
. ./.scripts/loggers/lib/--index-api.sh
|
||||
|
||||
. ./.scripts/base/lib/-export-env-variables-from-file.sh
|
||||
|
||||
_base_exportEnvVarsFrom_fileDotEnv() {
|
||||
local FUNCTION_NAME="_base_exportEnvVarsFrom_fileDotEnv"
|
||||
|
||||
_loggers_debug "${FUNCTION_NAME}" "LOCAL_FILE_DOT_ENV: ${LOCAL_FILE_DOT_ENV}"
|
||||
|
||||
_base_exportEnvVariablesFrom_file "${LOCAL_FILE_DOT_ENV}"
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
#!/bin/bash
|
||||
# -------------------------------------------------------------------------------------
|
||||
# IBM Confidential
|
||||
# 6949-70F, 6949-80D
|
||||
# © Copyright IBM Corp. 2018, 2024
|
||||
# US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
|
||||
# -------------------------------------------------------------------------------------
|
||||
|
||||
. ./.scripts/loggers/lib/--index-api.sh
|
||||
|
||||
. ./.scripts/base/lib/local-storage/-ensure-existance-file.sh
|
||||
|
||||
. ./.scripts/base/lib/-export-env-variable.sh
|
||||
|
||||
. ./.scripts/base/lib/-get-env-variable-key-from-line.sh
|
||||
. ./.scripts/base/lib/-get-env-variable-value-from-line.sh
|
||||
|
||||
_base_exportEnvVariablesFrom_file() {
|
||||
local FUNCTION_NAME="_base_exportEnvVariablesFrom_file"
|
||||
local FILE_RELATIVE_PATH=${1}
|
||||
|
||||
_loggers_trace "${FUNCTION_NAME}" "FILE_RELATIVE_PATH: ${FILE_RELATIVE_PATH}"
|
||||
_base_localStorage_ensureExistance_file "${FILE_RELATIVE_PATH}"
|
||||
|
||||
while read TMP_FILE_ENV_LINE; do
|
||||
if
|
||||
[ ! -z "${TMP_FILE_ENV_LINE}" ]
|
||||
then
|
||||
|
||||
local TMP_KEY=$(
|
||||
_base_getEnvVariableKey_fromLine "${TMP_FILE_ENV_LINE}"
|
||||
)
|
||||
local TMP_VALUE=$(
|
||||
_base_getEnvVariableValue_fromLine "${TMP_FILE_ENV_LINE}"
|
||||
)
|
||||
_base_exportEnvVariable "${TMP_KEY}" "${TMP_VALUE}"
|
||||
|
||||
fi
|
||||
done <"${FILE_RELATIVE_PATH}"
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
#!/bin/bash
|
||||
# -------------------------------------------------------------------------------------
|
||||
# IBM Confidential
|
||||
# 6949-70F, 6949-80D
|
||||
# © Copyright IBM Corp. 2018, 2024
|
||||
# US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
|
||||
# -------------------------------------------------------------------------------------
|
||||
|
||||
. ./.scripts/loggers/lib/--index-api.sh
|
||||
|
||||
_base_getEnvVariableKey_fromLine() {
|
||||
local FUNCTION_NAME="_base_getEnvVariableKey_fromLine"
|
||||
|
||||
local PARAM_LINE="${1}"
|
||||
_loggers_trace "${FUNCTION_NAME}" "PARAM_LINE: ${PARAM_LINE}"
|
||||
|
||||
local RET_VAL=$(
|
||||
echo "${PARAM_LINE}" | awk -F "=" '{print $1}'
|
||||
)
|
||||
_loggers_trace "${FUNCTION_NAME}" "RET_VAL: ${RET_VAL}"
|
||||
|
||||
echo "${RET_VAL}"
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
#!/bin/bash
|
||||
# -------------------------------------------------------------------------------------
|
||||
# IBM Confidential
|
||||
# 6949-70F, 6949-80D
|
||||
# © Copyright IBM Corp. 2018, 2024
|
||||
# US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
|
||||
# -------------------------------------------------------------------------------------
|
||||
|
||||
. ./.scripts/loggers/lib/--index-api.sh
|
||||
|
||||
_base_getEnvVariableValue_fromLine() {
|
||||
local FUNCTION_NAME="_base_getEnvVariableValue_fromLine"
|
||||
local TMP_LINE="${1}"
|
||||
local RET_VAL=$(
|
||||
echo $TMP_LINE | awk -F "=" '{print $2}'
|
||||
)
|
||||
RET_VAL=$(
|
||||
echo "${RET_VAL}" | sed 's/^"\(.*\)"$/\1/'
|
||||
)
|
||||
_loggers_trace "${FUNCTION_NAME}" "RET_VAL: ${RET_VAL}"
|
||||
echo "${RET_VAL}"
|
||||
}
|
||||
Executable
+19
@@ -0,0 +1,19 @@
|
||||
#!/bin/bash
|
||||
# -------------------------------------------------------------------------------------
|
||||
# IBM Confidential
|
||||
# 6949-70F, 6949-80D
|
||||
# © Copyright IBM Corp. 2018, 2024
|
||||
# US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
|
||||
# -------------------------------------------------------------------------------------
|
||||
|
||||
. ./.scripts/loggers/lib/--index-api.sh
|
||||
|
||||
_base_logEnvVars() {
|
||||
local FUNCTION_NAME="_base_logEnvVars"
|
||||
_loggers_debug "${FUNCTION_NAME}"
|
||||
|
||||
_loggers_info "${FUNCTION_NAME}" "LOCAL_OS_TYPE: ${LOCAL_OS_TYPE}"
|
||||
_loggers_info "${FUNCTION_NAME}" "LOCAL_CPU_TYPE: ${LOCAL_CPU_TYPE}"
|
||||
_loggers_info "${FUNCTION_NAME}" "LOCAL_HOME_DIR: ${LOCAL_HOME_DIR}"
|
||||
_loggers_info "${FUNCTION_NAME}" "LOCAL_FILE_DOT_ENV: ${LOCAL_FILE_DOT_ENV}"
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
# -------------------------------------------------------------------------------------
|
||||
# IBM Confidential
|
||||
# 6949-70F, 6949-80D
|
||||
# © Copyright IBM Corp. 2018, 2024
|
||||
# US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
|
||||
# -------------------------------------------------------------------------------------
|
||||
|
||||
prompt_for_env_var() {
|
||||
local var_name="$1"
|
||||
local function_name="${FUNCNAME[1]:-unknown_function}"
|
||||
|
||||
if [ -z "${!var_name}" ]; then
|
||||
while true; do
|
||||
_loggers_emptyLine
|
||||
echo -e "Provide a value for ${var_name} environment variable!\n"
|
||||
read -rep "> " tmp_value
|
||||
|
||||
if [ -n "${tmp_value}" ]; then
|
||||
export "${var_name}=${tmp_value}"
|
||||
export ENV_VAR_KEY="${var_name}"
|
||||
export ENV_VAR_VALUE="${tmp_value}"
|
||||
_base_localStorage_saveEnvVariable2_fileDotEnv
|
||||
break
|
||||
else
|
||||
_loggers_emptyLine
|
||||
_loggers_warn "${function_name}" "Provided value cannot be empty!"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
_loggers_debug "${function_name}" "${var_name}: *REDACTED*"
|
||||
}
|
||||
|
||||
Executable
+22
@@ -0,0 +1,22 @@
|
||||
#!/bin/bash
|
||||
# -------------------------------------------------------------------------------------
|
||||
# IBM Confidential
|
||||
# 6949-70F, 6949-80D
|
||||
# © Copyright IBM Corp. 2018, 2024
|
||||
# US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
|
||||
# -------------------------------------------------------------------------------------
|
||||
|
||||
. ./.scripts/base/lib/local-storage/-ensure-existance-file-dot-env.sh
|
||||
. ./.scripts/base/lib/local-storage/-ensure-existance-file.sh
|
||||
|
||||
. ./.scripts/base/lib/local-storage/-read-lines-from-file-dot-env.sh
|
||||
. ./.scripts/base/lib/local-storage/-read-lines-from-file.sh
|
||||
|
||||
. ./.scripts/base/lib/local-storage/-reset-file-dot-env.sh
|
||||
. ./.scripts/base/lib/local-storage/-reset-file.sh
|
||||
|
||||
. ./.scripts/base/lib/local-storage/-save-env-variable-2-file-dot-env.sh
|
||||
. ./.scripts/base/lib/local-storage/-save-env-variable-2-file.sh
|
||||
|
||||
. ./.scripts/base/lib/local-storage/-view-file-dot-env.sh
|
||||
. ./.scripts/base/lib/local-storage/-view-file.sh
|
||||
@@ -0,0 +1,22 @@
|
||||
#!/bin/bash
|
||||
# -------------------------------------------------------------------------------------
|
||||
# IBM Confidential
|
||||
# 6949-70F, 6949-80D
|
||||
# © Copyright IBM Corp. 2018, 2024
|
||||
# US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
|
||||
# -------------------------------------------------------------------------------------
|
||||
|
||||
. ./.scripts/loggers/lib/--index-api.sh
|
||||
|
||||
. ./.scripts/base/lib/local-storage/-ensure-existance-file.sh
|
||||
|
||||
_base_localStorage_ensureExistance_fileDotEnv() {
|
||||
local FUNCTION_NAME="_base_localStorage_ensureExistance_fileDotEnv"
|
||||
_loggers_debug "${FUNCTION_NAME}"
|
||||
|
||||
_loggers_info "${FUNCTION_NAME}" "LOCAL_FILE_DOT_ENV: ${LOCAL_FILE_DOT_ENV}"
|
||||
_loggers_info "${FUNCTION_NAME}" "LOCAL_FILE_DOT_ENV (absolute): ${LOCAL_HOME_DIR}/${LOCAL_FILE_DOT_ENV}"
|
||||
|
||||
_base_localStorage_ensureExistance_file "${LOCAL_FILE_DOT_ENV}"
|
||||
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
#!/bin/bash
|
||||
# -------------------------------------------------------------------------------------
|
||||
# IBM Confidential
|
||||
# 6949-70F, 6949-80D
|
||||
# © Copyright IBM Corp. 2018, 2024
|
||||
# US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
|
||||
# -------------------------------------------------------------------------------------
|
||||
|
||||
. ./.scripts/loggers/lib/--index-api.sh
|
||||
|
||||
_base_localStorage_ensureExistance_file() {
|
||||
local FUNCTION_NAME="_base_localStorage_ensureExistance_file"
|
||||
# _loggers_info "${FUNCTION_NAME}"
|
||||
|
||||
local FILE_RELATIVE_PATH="${1}"
|
||||
|
||||
if
|
||||
[ -z "${FILE_RELATIVE_PATH}" ]
|
||||
then
|
||||
_loggers_error "${FUNCTION_NAME}"
|
||||
_loggers_error "${FUNCTION_NAME}" "Missing mandatory 1st paramter (FILE_RELATIVE_PATH)!"
|
||||
_loggers_error "${FUNCTION_NAME}"
|
||||
exit 1
|
||||
fi
|
||||
if
|
||||
[ ! -e "${FILE_RELATIVE_PATH}" ]
|
||||
then
|
||||
touch "${FILE_RELATIVE_PATH}"
|
||||
_loggers_warn "${FUNCTION_NAME}"
|
||||
_loggers_warn "${FUNCTION_NAME}" "Was absent -> had to create!"
|
||||
_loggers_warn "${FUNCTION_NAME}"
|
||||
fi
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#!/bin/bash
|
||||
# -------------------------------------------------------------------------------------
|
||||
# IBM Confidential
|
||||
# 6949-70F, 6949-80D
|
||||
# © Copyright IBM Corp. 2018, 2024
|
||||
# US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
|
||||
# -------------------------------------------------------------------------------------
|
||||
|
||||
. ./.scripts/loggers/lib/--index-api.sh
|
||||
|
||||
. ./.scripts/base/lib/local-storage/-ensure-existance-file.sh
|
||||
|
||||
_base_localStorage_readLinesFrom_fileDotEnv() {
|
||||
local FUNCTION_NAME="_base_localStorage_readLinesFrom_fileDotEnv"
|
||||
_loggers_debug "${FUNCTION_NAME}"
|
||||
|
||||
_loggers_info "${FUNCTION_NAME}" "LOCAL_FILE_DOT_ENV: ${LOCAL_FILE_DOT_ENV}"
|
||||
_loggers_info "${FUNCTION_NAME}" "LOCAL_FILE_DOT_ENV (absolute): ${LOCAL_HOME_DIR}/${LOCAL_FILE_DOT_ENV}"
|
||||
|
||||
local RET_VAL=$(
|
||||
_base_localStorage_readLinesFrom_file "${LOCAL_FILE_DOT_ENV}"
|
||||
)
|
||||
_loggers_emptyLine
|
||||
|
||||
echo "${RET_VAL[@]}"
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
#!/bin/bash
|
||||
# -------------------------------------------------------------------------------------
|
||||
# IBM Confidential
|
||||
# 6949-70F, 6949-80D
|
||||
# © Copyright IBM Corp. 2018, 2024
|
||||
# US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
|
||||
# -------------------------------------------------------------------------------------
|
||||
|
||||
. ./.scripts/loggers/lib/--index-api.sh
|
||||
|
||||
. ./.scripts/base/lib/local-storage/-ensure-existance-file.sh
|
||||
|
||||
_base_localStorage_readLinesFrom_file() {
|
||||
local FUNCTION_NAME="_base_localStorage_readLinesFrom_file"
|
||||
_loggers_debug "${FUNCTION_NAME}"
|
||||
|
||||
local FILE_RELATIVE_PATH="${1}"
|
||||
|
||||
_base_localStorage_ensureExistance_file "${FILE_RELATIVE_PATH}"
|
||||
|
||||
local RET_VAL=()
|
||||
|
||||
while
|
||||
read -r TMP_FILE_LINE
|
||||
do
|
||||
if
|
||||
[ ! -z "${TMP_FILE_LINE}" ]
|
||||
then
|
||||
RET_VAL+=($TMP_FILE_LINE)
|
||||
fi
|
||||
|
||||
done <"${FILE_RELATIVE_PATH}"
|
||||
|
||||
echo "${RET_VAL[*]}"
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
# -------------------------------------------------------------------------------------
|
||||
# IBM Confidential
|
||||
# 6949-70F, 6949-80D
|
||||
# © Copyright IBM Corp. 2018, 2024
|
||||
# US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
|
||||
# -------------------------------------------------------------------------------------
|
||||
|
||||
. ./.scripts/loggers/lib/--index-api.sh
|
||||
|
||||
. ./.scripts/base/lib/local-storage/-reset-file.sh
|
||||
|
||||
_base_localStorage_reset_fileDotEnv() {
|
||||
local FUNCTION_NAME="_base_localStorage_reset_fileDotEnv"
|
||||
_loggers_debug "${FUNCTION_NAME}"
|
||||
|
||||
_loggers_info "${FUNCTION_NAME}" "LOCAL_FILE_DOT_ENV: ${LOCAL_FILE_DOT_ENV}"
|
||||
_loggers_info "${FUNCTION_NAME}" "LOCAL_FILE_DOT_ENV (absolute): ${LOCAL_HOME_DIR}/${LOCAL_FILE_DOT_ENV}"
|
||||
|
||||
_base_localStorage_reset_file "${LOCAL_FILE_DOT_ENV}"
|
||||
}
|
||||
Executable
+29
@@ -0,0 +1,29 @@
|
||||
#!/bin/bash
|
||||
# -------------------------------------------------------------------------------------
|
||||
# IBM Confidential
|
||||
# 6949-70F, 6949-80D
|
||||
# © Copyright IBM Corp. 2018, 2024
|
||||
# US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
|
||||
# -------------------------------------------------------------------------------------
|
||||
|
||||
. ./.scripts/loggers/lib/--index-api.sh
|
||||
|
||||
_base_localStorage_reset_file() {
|
||||
local FUNCTION_NAME="_base_localStorage_reset_file"
|
||||
_loggers_debug "${FUNCTION_NAME}"
|
||||
|
||||
local FILE_RELATIVE_PATH="${1}"
|
||||
|
||||
if
|
||||
[ -z "${FILE_RELATIVE_PATH}" ]
|
||||
then
|
||||
_loggers_error "${FUNCTION_NAME}"
|
||||
_loggers_error "${FUNCTION_NAME}" "Missing mandatory 1st paramter (FILE_RELATIVE_PATH)!"
|
||||
_loggers_error "${FUNCTION_NAME}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
rm "${FILE_RELATIVE_PATH}"
|
||||
|
||||
touch "${FILE_RELATIVE_PATH}"
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
#!/bin/bash
|
||||
# -------------------------------------------------------------------------------------
|
||||
# IBM Confidential
|
||||
# 6949-70F, 6949-80D
|
||||
# © Copyright IBM Corp. 2018, 2024
|
||||
# US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
|
||||
# -------------------------------------------------------------------------------------
|
||||
|
||||
. ./.scripts/loggers/lib/--index-api.sh
|
||||
|
||||
. ./.scripts/base/lib/local-storage/-save-env-variable-2-file.sh
|
||||
|
||||
_base_localStorage_saveEnvVariable2_fileDotEnv() {
|
||||
local FUNCTION_NAME="_base_localStorage_saveEnvVariable2_fileDotEnv"
|
||||
_loggers_debug "${FUNCTION_NAME}"
|
||||
|
||||
_loggers_info "${FUNCTION_NAME}" "LOCAL_FILE_DOT_ENV: ${LOCAL_FILE_DOT_ENV}"
|
||||
_loggers_info "${FUNCTION_NAME}" "LOCAL_FILE_DOT_ENV (absolute): ${LOCAL_HOME_DIR}/${LOCAL_FILE_DOT_ENV}"
|
||||
|
||||
_base_localStorage_saveEnvVariable2_file "${LOCAL_FILE_DOT_ENV}"
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
#!/bin/bash
|
||||
# -------------------------------------------------------------------------------------
|
||||
# IBM Confidential
|
||||
# 6949-70F, 6949-80D
|
||||
# © Copyright IBM Corp. 2018, 2024
|
||||
# US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
|
||||
# -------------------------------------------------------------------------------------
|
||||
|
||||
. ./.scripts/loggers/lib/--index-api.sh
|
||||
|
||||
. ./.scripts/base/lib/-ensure-env-var-key.sh
|
||||
. ./.scripts/base/lib/-ensure-env-var-value.sh
|
||||
|
||||
. ./.scripts/base/lib/-get-env-variable-key-from-line.sh
|
||||
|
||||
. ./.scripts/base/lib/local-storage/-ensure-existance-file.sh
|
||||
. ./.scripts/base/lib/local-storage/-read-lines-from-file.sh
|
||||
. ./.scripts/base/lib/local-storage/-reset-file.sh
|
||||
|
||||
_base_localStorage_saveEnvVariable2_file() {
|
||||
local FUNCTION_NAME="_base_localStorage_saveEnvVariable2_file"
|
||||
_loggers_debug "${FUNCTION_NAME}"
|
||||
|
||||
_base_ensure_evnVarKey
|
||||
_base_ensure_evnVarValue
|
||||
|
||||
local FILE_RELATIVE_PATH="${1}"
|
||||
_base_localStorage_ensureExistance_file "${FILE_RELATIVE_PATH}"
|
||||
|
||||
local PARAM_ENV_VAR_KEY="${ENV_VAR_KEY}"
|
||||
local PARAM_ENV_VAR_VALUE="${ENV_VAR_VALUE}"
|
||||
|
||||
_loggers_debug "${FUNCTION_NAME}" "ENV_VAR_KEY: ${ENV_VAR_KEY}"
|
||||
_loggers_debug "${FUNCTION_NAME}" "ENV_VAR_VALUE: ${ENV_VAR_VALUE}"
|
||||
|
||||
local FILE_LINES=$(cat "$FILE_RELATIVE_PATH")
|
||||
|
||||
_base_localStorage_reset_file "${FILE_RELATIVE_PATH}"
|
||||
|
||||
local TMP_KEY_STATUS=""
|
||||
|
||||
echo "$FILE_LINES" | while IFS= read -r FILE_LINE; do
|
||||
local TMP_ENV_VAR_KEY=$(
|
||||
_base_getEnvVariableKey_fromLine "${FILE_LINE}"
|
||||
)
|
||||
if
|
||||
[ "${PARAM_ENV_VAR_KEY}" = "${TMP_ENV_VAR_KEY}" ]
|
||||
then
|
||||
echo "${PARAM_ENV_VAR_KEY}=\"${PARAM_ENV_VAR_VALUE}\"" >>"${FILE_RELATIVE_PATH}"
|
||||
TMP_KEY_STATUS="REPLACED"
|
||||
else
|
||||
echo "${FILE_LINE}" >>"${FILE_RELATIVE_PATH}"
|
||||
fi
|
||||
done
|
||||
|
||||
if
|
||||
[ ! "${TMP_KEY_STATUS}" = "REPLACED" ]
|
||||
then
|
||||
echo "${PARAM_ENV_VAR_KEY}=\"${PARAM_ENV_VAR_VALUE}\"" >>"${FILE_RELATIVE_PATH}"
|
||||
fi
|
||||
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
#!/bin/bash
|
||||
# -------------------------------------------------------------------------------------
|
||||
# IBM Confidential
|
||||
# 6949-70F, 6949-80D
|
||||
# © Copyright IBM Corp. 2018, 2024
|
||||
# US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
|
||||
# -------------------------------------------------------------------------------------
|
||||
|
||||
. ./.scripts/loggers/lib/--index-api.sh
|
||||
|
||||
. ./.scripts/base/lib/local-storage/-ensure-existance-file-dot-env.sh
|
||||
. ./.scripts/base/lib/local-storage/-view-file.sh
|
||||
|
||||
_base_localStorage_view_fileDotEnv() {
|
||||
local FUNCTION_NAME="_base_localStorage_view_fileDotEnv"
|
||||
_loggers_debug "${FUNCTION_NAME}"
|
||||
|
||||
_loggers_info "${FUNCTION_NAME}" "LOCAL_FILE_DOT_ENV: ${LOCAL_FILE_DOT_ENV}"
|
||||
_loggers_info "${FUNCTION_NAME}" "LOCAL_FILE_DOT_ENV (absolute): ${LOCAL_HOME_DIR}/${LOCAL_FILE_DOT_ENV}"
|
||||
|
||||
_base_localStorage_ensureExistance_file "${LOCAL_FILE_DOT_ENV}"
|
||||
|
||||
_base_localStorage_view_file "${LOCAL_FILE_DOT_ENV}"
|
||||
|
||||
}
|
||||
Executable
+30
@@ -0,0 +1,30 @@
|
||||
#!/bin/bash
|
||||
# -------------------------------------------------------------------------------------
|
||||
# IBM Confidential
|
||||
# 6949-70F, 6949-80D
|
||||
# © Copyright IBM Corp. 2018, 2024
|
||||
# US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
|
||||
# -------------------------------------------------------------------------------------
|
||||
|
||||
. ./.scripts/loggers/lib/--index-api.sh
|
||||
|
||||
_base_localStorage_view_file() {
|
||||
local FUNCTION_NAME="_base_localStorage_view_file"
|
||||
_loggers_debug "${FUNCTION_NAME}"
|
||||
|
||||
local FILE_RELATIVE_PATH="${1}"
|
||||
|
||||
if
|
||||
[ -z "${FILE_RELATIVE_PATH}" ]
|
||||
then
|
||||
_loggers_error "${FUNCTION_NAME}"
|
||||
_loggers_error "${FUNCTION_NAME}" "Missing mandatory 1st paramter (FILE_RELATIVE_PATH)!"
|
||||
_loggers_error "${FUNCTION_NAME}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
_loggers_emptyLine
|
||||
cat "${FILE_RELATIVE_PATH}"
|
||||
_loggers_emptyLine
|
||||
|
||||
}
|
||||
Executable
+23
@@ -0,0 +1,23 @@
|
||||
#!/bin/bash
|
||||
# -------------------------------------------------------------------------------------
|
||||
# IBM Confidential
|
||||
# 6949-70F, 6949-80D
|
||||
# © Copyright IBM Corp. 2018, 2024
|
||||
# US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
|
||||
# -------------------------------------------------------------------------------------
|
||||
#
|
||||
# --> defaults preserve already-exported values so a caller can override
|
||||
# any level before sourcing the loggers module
|
||||
#
|
||||
export LOGGER_TRAILING_NEW_LINE_ENABLED="${LOGGER_TRAILING_NEW_LINE_ENABLED:-TRUE}"
|
||||
|
||||
export LOGGER_IS_ENABLED_ERROR="${LOGGER_IS_ENABLED_ERROR:-true}"
|
||||
export LOGGER_IS_ENABLED_INFO="${LOGGER_IS_ENABLED_INFO:-true}"
|
||||
export LOGGER_IS_ENABLED_WARN="${LOGGER_IS_ENABLED_WARN:-true}"
|
||||
export LOGGER_IS_ENABLED_DEBUG="${LOGGER_IS_ENABLED_DEBUG:-true}"
|
||||
export LOGGER_IS_ENABLED_TRACE="${LOGGER_IS_ENABLED_TRACE:-false}"
|
||||
|
||||
export LOCAL_STRING_005_SPACES=" "
|
||||
export LOCAL_STRING_010_SPACES="${LOCAL_STRING_005_SPACES}${LOCAL_STRING_005_SPACES}"
|
||||
export LOCAL_STRING_050_SPACES="${LOCAL_STRING_010_SPACES}${LOCAL_STRING_010_SPACES}${LOCAL_STRING_010_SPACES}${LOCAL_STRING_010_SPACES}${LOCAL_STRING_010_SPACES}"
|
||||
export LOCAL_STRING_070_SPACES="${LOCAL_STRING_050_SPACES}${LOCAL_STRING_010_SPACES}${LOCAL_STRING_010_SPACES}"
|
||||
Executable
+25
@@ -0,0 +1,25 @@
|
||||
#!/bin/bash
|
||||
# -------------------------------------------------------------------------------------
|
||||
# IBM Confidential
|
||||
# 6949-70F, 6949-80D
|
||||
# © Copyright IBM Corp. 2018, 2024
|
||||
# US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
|
||||
# -------------------------------------------------------------------------------------
|
||||
|
||||
#
|
||||
# --> logger level flags and padding strings must exist before any logger
|
||||
# function runs; the reader preserves already-exported values, so this
|
||||
# is safe to source repeatedly and from any dependent module
|
||||
#
|
||||
. ./.scripts/loggers/lib/--env-vars-reader.sh
|
||||
|
||||
. ./.scripts/loggers/lib/-enable-trailing-new-line.sh
|
||||
|
||||
. ./.scripts/loggers/lib/-info.sh
|
||||
. ./.scripts/loggers/lib/-trace.sh
|
||||
. ./.scripts/loggers/lib/-debug.sh
|
||||
. ./.scripts/loggers/lib/-error.sh
|
||||
. ./.scripts/loggers/lib/-warn.sh
|
||||
|
||||
. ./.scripts/loggers/lib/-empty-line.sh
|
||||
. ./.scripts/loggers/lib/-waiting-dot.sh
|
||||
Executable
+12
@@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
# -------------------------------------------------------------------------------------
|
||||
# IBM Confidential
|
||||
# 6949-70F, 6949-80D
|
||||
# © Copyright IBM Corp. 2018, 2024
|
||||
# US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
|
||||
# -------------------------------------------------------------------------------------
|
||||
#
|
||||
# --> available functions are imported/exported
|
||||
#
|
||||
. ./.scripts/loggers/lib/--index-api.sh
|
||||
# -------------------------------------------------------------------------------------
|
||||
Executable
+21
@@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
# -------------------------------------------------------------------------------------
|
||||
# IBM Confidential
|
||||
# 6949-70F, 6949-80D
|
||||
# © Copyright IBM Corp. 2018, 2024
|
||||
# US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
|
||||
# -------------------------------------------------------------------------------------
|
||||
|
||||
. ./.scripts/loggers/lib/-enable-trailing-new-line.sh
|
||||
|
||||
_loggers_debug() {
|
||||
_loggers_enableLoggerTrailingNewLine
|
||||
if
|
||||
[ "${LOGGER_IS_ENABLED_DEBUG}" = true ]
|
||||
then
|
||||
local TMP_1ST_PARAM="${1}${LOCAL_STRING_070_SPACES}"
|
||||
TMP_1ST_PARAM="${TMP_1ST_PARAM:0:70}"
|
||||
local TMP_LINE="# DEBUG # ${TMP_1ST_PARAM} # ${2}"
|
||||
echo -e "\033[1;36m${TMP_LINE}\033[0m" >&2
|
||||
fi
|
||||
}
|
||||
Executable
+14
@@ -0,0 +1,14 @@
|
||||
#!/bin/bash
|
||||
# -------------------------------------------------------------------------------------
|
||||
# IBM Confidential
|
||||
# 6949-70F, 6949-80D
|
||||
# © Copyright IBM Corp. 2018, 2024
|
||||
# US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
|
||||
# -------------------------------------------------------------------------------------
|
||||
|
||||
. ./.scripts/loggers/lib/-enable-trailing-new-line.sh
|
||||
|
||||
_loggers_emptyLine() {
|
||||
_loggers_enableLoggerTrailingNewLine
|
||||
echo -e "" >&2
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
#!/bin/bash
|
||||
# -------------------------------------------------------------------------------------
|
||||
# IBM Confidential
|
||||
# 6949-70F, 6949-80D
|
||||
# © Copyright IBM Corp. 2018, 2024
|
||||
# US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
|
||||
# -------------------------------------------------------------------------------------
|
||||
|
||||
_loggers_enableLoggerTrailingNewLine() {
|
||||
if
|
||||
[ -z "$LOGGER_TRAILING_NEW_LINE_DISABLED" ]
|
||||
then
|
||||
echo "" >&2
|
||||
export LOGGER_TRAILING_NEW_LINE_DISABLED="TRUE"
|
||||
fi
|
||||
}
|
||||
Executable
+22
@@ -0,0 +1,22 @@
|
||||
#!/bin/bash
|
||||
# -------------------------------------------------------------------------------------
|
||||
# IBM Confidential
|
||||
# 6949-70F, 6949-80D
|
||||
# © Copyright IBM Corp. 2018, 2024
|
||||
# US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
|
||||
# -------------------------------------------------------------------------------------
|
||||
|
||||
. ./.scripts/loggers/lib/-enable-trailing-new-line.sh
|
||||
|
||||
_loggers_error() {
|
||||
_loggers_enableLoggerTrailingNewLine
|
||||
if
|
||||
[ "${LOGGER_IS_ENABLED_ERROR}" = true ]
|
||||
then
|
||||
local TMP_1ST_PARAM="${1}${LOCAL_STRING_070_SPACES}"
|
||||
TMP_1ST_PARAM="${TMP_1ST_PARAM:0:70}"
|
||||
local TMP_LINE="# ERROR # ${TMP_1ST_PARAM} # $2"
|
||||
echo -e "\033[1;31m${TMP_LINE}\033[0m" >&2
|
||||
fi
|
||||
|
||||
}
|
||||
Executable
+21
@@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
# -------------------------------------------------------------------------------------
|
||||
# IBM Confidential
|
||||
# 6949-70F, 6949-80D
|
||||
# © Copyright IBM Corp. 2018, 2024
|
||||
# US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
|
||||
# -------------------------------------------------------------------------------------
|
||||
|
||||
. ./.scripts/loggers/lib/-enable-trailing-new-line.sh
|
||||
|
||||
_loggers_info() {
|
||||
_loggers_enableLoggerTrailingNewLine
|
||||
if
|
||||
[ "${LOGGER_IS_ENABLED_INFO}" = true ]
|
||||
then
|
||||
local TMP_1ST_PARAM="${1}${LOCAL_STRING_070_SPACES}"
|
||||
TMP_1ST_PARAM="${TMP_1ST_PARAM:0:70}"
|
||||
local TMP_LINE="# INFO # ${TMP_1ST_PARAM} # ${2}"
|
||||
echo -e "${TMP_LINE}" >&2
|
||||
fi
|
||||
}
|
||||
Executable
+22
@@ -0,0 +1,22 @@
|
||||
#!/bin/bash
|
||||
# -------------------------------------------------------------------------------------
|
||||
# IBM Confidential
|
||||
# 6949-70F, 6949-80D
|
||||
# © Copyright IBM Corp. 2018, 2024
|
||||
# US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
|
||||
# -------------------------------------------------------------------------------------
|
||||
|
||||
. ./.scripts/loggers/lib/-enable-trailing-new-line.sh
|
||||
|
||||
_loggers_trace() {
|
||||
_loggers_enableLoggerTrailingNewLine
|
||||
if
|
||||
[ "${LOGGER_IS_ENABLED_TRACE}" = true ]
|
||||
then
|
||||
local TMP_1ST_PARAM="${1}${LOCAL_STRING_070_SPACES}"
|
||||
TMP_1ST_PARAM="${TMP_1ST_PARAM:0:70}"
|
||||
local TMP_LINE="# TRACE # ${TMP_1ST_PARAM} # $2"
|
||||
echo -e "\033[0;94m${TMP_LINE}\033[0m" >&2
|
||||
fi
|
||||
|
||||
}
|
||||
Executable
+14
@@ -0,0 +1,14 @@
|
||||
#!/bin/bash
|
||||
# -------------------------------------------------------------------------------------
|
||||
# IBM Confidential
|
||||
# 6949-70F, 6949-80D
|
||||
# © Copyright IBM Corp. 2018, 2024
|
||||
# US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
|
||||
# -------------------------------------------------------------------------------------
|
||||
|
||||
. ./.scripts/loggers/lib/-enable-trailing-new-line.sh
|
||||
|
||||
_loggers_waitingDot() {
|
||||
echo -n "." >&2
|
||||
export LOGGER_TRAILING_NEW_LINE_DISABLED=""
|
||||
}
|
||||
Executable
+21
@@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
# -------------------------------------------------------------------------------------
|
||||
# IBM Confidential
|
||||
# 6949-70F, 6949-80D
|
||||
# © Copyright IBM Corp. 2018, 2024
|
||||
# US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
|
||||
# -------------------------------------------------------------------------------------
|
||||
|
||||
. ./.scripts/loggers/lib/-enable-trailing-new-line.sh
|
||||
|
||||
_loggers_warn() {
|
||||
_loggers_enableLoggerTrailingNewLine
|
||||
if
|
||||
[ "${LOGGER_IS_ENABLED_WARN}" = true ]
|
||||
then
|
||||
local TMP_1ST_PARAM="${1}${LOCAL_STRING_070_SPACES}"
|
||||
TMP_1ST_PARAM="${TMP_1ST_PARAM:0:70}"
|
||||
local TMP_LINE="# WARN # ${TMP_1ST_PARAM} # $2"
|
||||
echo -e "\033[1;33m${TMP_LINE}\033[0m" >&2
|
||||
fi
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
# `module-example-v1` Generic Scaffold
|
||||
|
||||
This is a generic reference scaffold for a new Cognitive Architect script module.
|
||||
|
||||
To adapt it:
|
||||
|
||||
1. Copy `module-example-v1/` into `.scripts/<new-module>/`.
|
||||
2. Replace paths containing `module-example-v1`.
|
||||
3. Replace environment prefix `MODULE_EXAMPLE_V1_`.
|
||||
4. Replace function prefix `_moduleExampleV1_`.
|
||||
5. Add public API wrappers and implementation files as needed.
|
||||
6. Add a root `Taskfile.yml` include only if the module should be task-runner public.
|
||||
7. Run `bash -n` against all generated `.sh` files.
|
||||
@@ -0,0 +1,10 @@
|
||||
# https://taskfile.dev
|
||||
|
||||
version: "3"
|
||||
|
||||
tasks:
|
||||
initialize-one:
|
||||
cmds:
|
||||
- |
|
||||
./.scripts/module-example-v1/api/initialize-one.sh {{.CLI_ARGS}}
|
||||
silent: true
|
||||
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
. ./.scripts/module-example-v1/lib/--index.sh
|
||||
|
||||
_moduleExampleV1_initializeOne
|
||||
@@ -0,0 +1,25 @@
|
||||
#!/bin/bash
|
||||
|
||||
export MODULE_EXAMPLE_V1_NAME="${MODULE_EXAMPLE_V1_NAME:-default-name}"
|
||||
export MODULE_EXAMPLE_V1_OUTPUT_DIR="${MODULE_EXAMPLE_V1_OUTPUT_DIR:-.tmp/module-example-v1}"
|
||||
export MODULE_EXAMPLE_V1_DRY_RUN="${MODULE_EXAMPLE_V1_DRY_RUN:-false}"
|
||||
|
||||
ALL_ARGS=("$@")
|
||||
while [[ "$#" -gt 0 ]]; do
|
||||
case $1 in
|
||||
--name)
|
||||
export MODULE_EXAMPLE_V1_NAME="$2"
|
||||
shift
|
||||
;;
|
||||
--output-dir)
|
||||
export MODULE_EXAMPLE_V1_OUTPUT_DIR="$2"
|
||||
shift
|
||||
;;
|
||||
--dry-run)
|
||||
export MODULE_EXAMPLE_V1_DRY_RUN="true"
|
||||
;;
|
||||
*) ;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
set -- "${ALL_ARGS[@]}"
|
||||
@@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
. ./.scripts/loggers/lib/--index-api.sh
|
||||
|
||||
if [ -z "${MODULE_EXAMPLE_V1_NAME}" ]; then
|
||||
_loggers_error "module-example-v1" "Missing required --name / MODULE_EXAMPLE_V1_NAME"
|
||||
exit 1
|
||||
fi
|
||||
@@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
. ./.scripts/loggers/lib/--index-api.sh
|
||||
. ./.scripts/base/lib/--index-api.sh
|
||||
|
||||
. ./.scripts/module-example-v1/lib/-initialize-one.sh
|
||||
@@ -0,0 +1,15 @@
|
||||
#!/bin/bash
|
||||
|
||||
#
|
||||
# --> passed parameters are read & exported environment variables
|
||||
#
|
||||
. ./.scripts/module-example-v1/lib/--env-vars-reader.sh
|
||||
#
|
||||
# --> required environment variables are validated for existence
|
||||
#
|
||||
. ./.scripts/module-example-v1/lib/--env-vars-validator.sh
|
||||
#
|
||||
# --> available functions are imported/exported
|
||||
#
|
||||
. ./.scripts/module-example-v1/lib/--index-api.sh
|
||||
# -------------------------------------------------------------------------------------
|
||||
@@ -0,0 +1,19 @@
|
||||
#!/bin/bash
|
||||
|
||||
. ./.scripts/loggers/lib/--index-api.sh
|
||||
|
||||
_moduleExampleV1_initializeOne() {
|
||||
local FUNCTION_NAME="_moduleExampleV1_initializeOne"
|
||||
|
||||
_loggers_info "${FUNCTION_NAME}" "Initializing module-example-v1"
|
||||
_loggers_debug "${FUNCTION_NAME}" "Name: ${MODULE_EXAMPLE_V1_NAME}"
|
||||
_loggers_debug "${FUNCTION_NAME}" "Output directory: ${MODULE_EXAMPLE_V1_OUTPUT_DIR}"
|
||||
|
||||
if [ "${MODULE_EXAMPLE_V1_DRY_RUN}" = "true" ]; then
|
||||
_loggers_info "${FUNCTION_NAME}" "Dry run enabled; no files will be changed."
|
||||
return 0
|
||||
fi
|
||||
|
||||
mkdir -p "${MODULE_EXAMPLE_V1_OUTPUT_DIR}"
|
||||
_loggers_info "${FUNCTION_NAME}" "Initialization complete."
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
# Module Anatomy
|
||||
|
||||
The four file types inside `lib/`, the `api/` wrapper, and the patterns each follows.
|
||||
|
||||
Read this when writing or changing a reader, a validator, an implementation function, or a
|
||||
public wrapper.
|
||||
|
||||
---
|
||||
|
||||
## 1. `--env-vars-reader.sh` — defaults and CLI parsing
|
||||
|
||||
Responsibilities, in order:
|
||||
|
||||
1. export defaults, preserving any value already exported by the caller;
|
||||
2. parse CLI flags into environment variables;
|
||||
3. restore the positional arguments so later consumers still see them.
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
export MODULE_EXAMPLE_V1_NAME="${MODULE_EXAMPLE_V1_NAME:-default-name}"
|
||||
export MODULE_EXAMPLE_V1_OUTPUT_DIR="${MODULE_EXAMPLE_V1_OUTPUT_DIR:-.tmp/module-example-v1}"
|
||||
export MODULE_EXAMPLE_V1_DRY_RUN="${MODULE_EXAMPLE_V1_DRY_RUN:-false}"
|
||||
|
||||
ALL_ARGS=("$@")
|
||||
while [[ "$#" -gt 0 ]]; do
|
||||
case $1 in
|
||||
--name)
|
||||
export MODULE_EXAMPLE_V1_NAME="$2"
|
||||
shift
|
||||
;;
|
||||
--output-dir)
|
||||
export MODULE_EXAMPLE_V1_OUTPUT_DIR="$2"
|
||||
shift
|
||||
;;
|
||||
--dry-run)
|
||||
export MODULE_EXAMPLE_V1_DRY_RUN="true"
|
||||
;;
|
||||
*) ;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
set -- "${ALL_ARGS[@]}"
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
- Use a stable uppercase environment prefix per module.
|
||||
- **Always use `${VAR:-default}`**, never a bare `export VAR=value`. A bare assignment
|
||||
silently discards a caller's override, and the caller has no way to detect it. This is what
|
||||
makes a reader safe to source more than once.
|
||||
- Prefer explicit CLI flags over positional arguments.
|
||||
- Defaults must be safe to run locally — a default that writes outside `.tmp/` or touches a
|
||||
shared system is not a safe default.
|
||||
- Never print secrets here.
|
||||
|
||||
The `ALL_ARGS` save/restore matters because `shift` consumes the arguments. Without the
|
||||
`set --` at the end, anything sourced after the reader sees an empty argument list.
|
||||
|
||||
---
|
||||
|
||||
## 2. `--env-vars-validator.sh` — required inputs
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
. ./.scripts/loggers/lib/--index-api.sh
|
||||
|
||||
if [ -z "${MODULE_EXAMPLE_V1_NAME}" ]; then
|
||||
_loggers_error "module-example-v1" "Missing required --name / MODULE_EXAMPLE_V1_NAME"
|
||||
exit 1
|
||||
fi
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
- Runs from `--index.sh`, after the reader and before the API index, so failures happen before
|
||||
any implementation function is even defined.
|
||||
- Use `_loggers_error` for the failure and `_loggers_info` for a usage hint.
|
||||
- `exit 1` is correct **here** — the validator runs during bootstrap of a top-level command,
|
||||
and stopping is the intent.
|
||||
- Validate only what every command in the module needs. A variable that only one command
|
||||
requires is validated inside that command's function, not globally — otherwise unrelated
|
||||
commands fail on input they never use.
|
||||
|
||||
---
|
||||
|
||||
## 3. `--index-api.sh` — dependency and implementation wiring
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
. ./.scripts/loggers/lib/--index-api.sh
|
||||
. ./.scripts/base/lib/--index-api.sh
|
||||
|
||||
. ./.scripts/module-example-v1/lib/-initialize-one.sh
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
- Upstream dependencies first, then this module's own implementation files.
|
||||
- Source other modules' `--index-api.sh`, **not** their `--index.sh` — see
|
||||
`references/shared-modules.md` §2.
|
||||
- **Every implementation file must appear here.** A `lib/-*.sh` that is never sourced defines
|
||||
nothing, and the failure surfaces as `command not found` for a function you can see on disk.
|
||||
- Safe to source repeatedly. Sourcing defines functions; it should have no other side effect.
|
||||
|
||||
---
|
||||
|
||||
## 4. `--index.sh` — runtime bootstrap
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
# --> passed parameters are read & exported environment variables
|
||||
. ./.scripts/module-example-v1/lib/--env-vars-reader.sh
|
||||
|
||||
# --> required environment variables are validated for existence
|
||||
. ./.scripts/module-example-v1/lib/--env-vars-validator.sh
|
||||
|
||||
# --> available functions are imported/exported
|
||||
. ./.scripts/module-example-v1/lib/--index-api.sh
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
- Exactly these three sources, in exactly this order.
|
||||
- This is the module's **own** entrypoint, sourced by its `api/` wrappers. Other modules never
|
||||
source it — they take `--index-api.sh`.
|
||||
- A module with no required inputs may omit the validator, but keeping an empty one makes the
|
||||
next required variable a one-line change.
|
||||
|
||||
---
|
||||
|
||||
## 5. Implementation functions — `lib/-<command>.sh`
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
. ./.scripts/loggers/lib/--index-api.sh
|
||||
|
||||
_moduleExampleV1_initializeOne() {
|
||||
local FUNCTION_NAME="_moduleExampleV1_initializeOne"
|
||||
|
||||
_loggers_info "${FUNCTION_NAME}" "Initializing module-example-v1"
|
||||
_loggers_debug "${FUNCTION_NAME}" "Output directory: ${MODULE_EXAMPLE_V1_OUTPUT_DIR}"
|
||||
|
||||
if [ "${MODULE_EXAMPLE_V1_DRY_RUN}" = "true" ]; then
|
||||
_loggers_info "${FUNCTION_NAME}" "Dry run enabled; no files will be changed."
|
||||
return 0
|
||||
fi
|
||||
|
||||
mkdir -p "${MODULE_EXAMPLE_V1_OUTPUT_DIR}"
|
||||
_loggers_info "${FUNCTION_NAME}" "Initialization complete."
|
||||
}
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
- Open with `local FUNCTION_NAME="_<module>_<function>"` — every logger call takes it as the
|
||||
first argument, which is what makes log output traceable to a specific function.
|
||||
- One file, one primary function. Small private helpers may live alongside it.
|
||||
- Use `_loggers_*` helpers, never raw `echo`, for status and errors.
|
||||
- **`return` non-zero on failure; never `exit`.** The file is sourced, so `exit` terminates
|
||||
the caller's shell — including an interactive one.
|
||||
- Read configuration from the module's environment variables. Never re-parse `$@` here.
|
||||
- Quote every expansion unless word splitting is deliberate.
|
||||
- Never expose secret values in a log line.
|
||||
|
||||
---
|
||||
|
||||
## 6. `api/` wrappers
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
. ./.scripts/module-example-v1/lib/--index.sh
|
||||
|
||||
_moduleExampleV1_initializeOne
|
||||
```
|
||||
|
||||
That is the whole file. Rules:
|
||||
|
||||
- Source exactly `lib/--index.sh`, then call exactly one function.
|
||||
- No implementation, no flag parsing, no validation, no argument forwarding.
|
||||
- Arguments reach the reader automatically: sourcing happens while the wrapper's own `$@` is
|
||||
still in scope, so `--env-vars-reader.sh` sees them without being passed anything.
|
||||
- Create a wrapper only for a genuinely user-facing command. An internal helper stays in
|
||||
`lib/` — every file in `api/` is a public interface someone may come to depend on.
|
||||
|
||||
---
|
||||
|
||||
## 7. Diagnosing a broken module
|
||||
|
||||
| Symptom | Cause |
|
||||
|---|---|
|
||||
| `command not found` for a function that exists on disk | Its file is missing from `lib/--index-api.sh` |
|
||||
| No log output at all, exit code 0 | Logger level flags never exported — see `references/shared-modules.md` §3 |
|
||||
| A flag is ignored | Not handled in `--env-vars-reader.sh`, or handled after the `set --` restore |
|
||||
| Later sources see no arguments | Reader is missing the `ALL_ARGS` save/`set --` restore |
|
||||
| `No such file or directory` for a `lib/` path | Run from inside the module instead of the repository root |
|
||||
| `.env` loaded unexpectedly | Something sourced `base/lib/--index.sh` instead of `base/lib/--index-api.sh` |
|
||||
| The shell exits on a handled error | `exit` used inside a sourced implementation function |
|
||||
@@ -0,0 +1,66 @@
|
||||
# Module Patterns
|
||||
|
||||
A decision guide for what kind of module you are building and how it should connect to the
|
||||
others.
|
||||
|
||||
---
|
||||
|
||||
## 1. Module type
|
||||
|
||||
| Module type | Has `api/` | Has `Taskfile.yml` | Example |
|
||||
|---|:---:|:---:|---|
|
||||
| Support-only library | No | No | `loggers` |
|
||||
| Shared foundation with public commands | Yes | Optional / no | `base` |
|
||||
| Feature module | Yes | Usually yes | `kube`, `github`, `data-migration` |
|
||||
| Wrapper around an external CLI | Yes | Usually yes | `helm`, `openshift`, `github` |
|
||||
|
||||
Pick the type before creating any file — it decides whether `api/` and `Taskfile.yml` exist at
|
||||
all, and adding them later means reworking every consumer that has already started sourcing
|
||||
the module.
|
||||
|
||||
A module with no user-facing command is a support library. Do not give it an `api/` directory
|
||||
speculatively; every file in `api/` is a public interface someone may come to depend on.
|
||||
|
||||
---
|
||||
|
||||
## 2. Dependency sourcing
|
||||
|
||||
| You need | Source |
|
||||
|---|---|
|
||||
| Logging | `./.scripts/loggers/lib/--index-api.sh` |
|
||||
| Shared base functions | `./.scripts/base/lib/--index-api.sh` |
|
||||
| Another module's exported functions | that module's `lib/--index-api.sh` |
|
||||
| Your own module's full runtime, from its `api/` wrapper | your `lib/--index.sh` |
|
||||
|
||||
The rule underneath: **`--index-api.sh` is the public edge between modules; `--index.sh` is a
|
||||
module's own private entrypoint.** Sourcing another module's `--index.sh` runs its reader and
|
||||
validator inside your command — importing its defaults, its required-input checks, and in
|
||||
`base`'s case its `.env` loading. Symptoms show up as variables nobody set, or a validation
|
||||
failure naming a module the user never invoked.
|
||||
|
||||
---
|
||||
|
||||
## 3. Command exposure
|
||||
|
||||
Three independent decisions, in increasing order of commitment:
|
||||
|
||||
1. **`lib/` only** — internal. Reachable from other modules that source your `--index-api.sh`.
|
||||
2. **`api/<command>.sh`** — user-facing. Someone can run it directly from the repository root.
|
||||
3. **Module `Taskfile.yml`** — discoverable through `task --list-all`.
|
||||
4. **Root `Taskfile.yml` include** — a stable public namespace, effectively permanent.
|
||||
|
||||
Escalate only as far as the command genuinely needs. Each step is easy to add later and
|
||||
disruptive to withdraw, because each one is a promise someone may already be relying on.
|
||||
|
||||
---
|
||||
|
||||
## 4. Common mistakes
|
||||
|
||||
- Putting full implementation logic into `api/*.sh`.
|
||||
- Adding a `lib/-*.sh` file and forgetting to source it from `lib/--index-api.sh`.
|
||||
- Parsing CLI flags in implementation files instead of `--env-vars-reader.sh`.
|
||||
- Printing secrets in logs.
|
||||
- Sourcing `base/lib/--index.sh` from a library function and unexpectedly loading `.env`.
|
||||
- Adding root Taskfile includes for experimental modules.
|
||||
- Giving a support-only library an `api/` directory it does not need.
|
||||
- Mixing function prefixes inside one module after a rename.
|
||||
@@ -0,0 +1,165 @@
|
||||
# Shared Modules — `loggers` and `base`
|
||||
|
||||
The two foundation modules every other module depends on, and the bootstrap rule that decides
|
||||
whether logging works at all.
|
||||
|
||||
Working implementations are in `assets/loggers/` and `assets/base/`.
|
||||
|
||||
---
|
||||
|
||||
## 1. `loggers` — support-only library
|
||||
|
||||
No `api/` commands, no `Taskfile.yml`. It exists to be sourced.
|
||||
|
||||
```text
|
||||
.scripts/loggers/
|
||||
lib/
|
||||
--env-vars-reader.sh # level flags + padding strings
|
||||
--index-api.sh # sources the reader, then every logger function
|
||||
--index.sh
|
||||
-debug.sh -error.sh -info.sh -trace.sh -warn.sh
|
||||
-empty-line.sh -enable-trailing-new-line.sh -waiting-dot.sh
|
||||
```
|
||||
|
||||
Consume it from any module:
|
||||
|
||||
```bash
|
||||
. ./.scripts/loggers/lib/--index-api.sh
|
||||
```
|
||||
|
||||
Available functions:
|
||||
|
||||
```bash
|
||||
_loggers_info "${FUNCTION_NAME}" "message"
|
||||
_loggers_debug "${FUNCTION_NAME}" "message"
|
||||
_loggers_warn "${FUNCTION_NAME}" "message"
|
||||
_loggers_error "${FUNCTION_NAME}" "message"
|
||||
_loggers_trace "${FUNCTION_NAME}" "message"
|
||||
_loggers_emptyLine
|
||||
```
|
||||
|
||||
Levels are controlled by environment flags, defaulting to everything except trace:
|
||||
|
||||
```bash
|
||||
LOGGER_IS_ENABLED_ERROR=true
|
||||
LOGGER_IS_ENABLED_INFO=true
|
||||
LOGGER_IS_ENABLED_WARN=true
|
||||
LOGGER_IS_ENABLED_DEBUG=true
|
||||
LOGGER_IS_ENABLED_TRACE=false
|
||||
```
|
||||
|
||||
Export any of them before invoking a command to change verbosity for that run:
|
||||
|
||||
```bash
|
||||
LOGGER_IS_ENABLED_DEBUG=false ./.scripts/<module>/api/<command>.sh
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
1. Do not add `api/` wrappers to `loggers` without a real user-facing requirement.
|
||||
2. Keep logger helpers small and side-effect-light.
|
||||
3. Log to `stderr` — `stdout` stays clean so command output remains pipeable.
|
||||
4. Dependent modules source the logger API directly.
|
||||
|
||||
---
|
||||
|
||||
## 2. `base` — shared foundation
|
||||
|
||||
Has public `api/` wrappers but no `Taskfile.yml`. Provides local environment handling and
|
||||
local-storage helpers over `.env` files.
|
||||
|
||||
```text
|
||||
.scripts/base/
|
||||
api/
|
||||
local-storage-ensure-existance-file-dot-env.sh
|
||||
local-storage-read-lines-from-file-dot-env.sh
|
||||
local-storage-reset-file-dot-env.sh
|
||||
local-storage-save-env-variable-2-file-dot-env.sh
|
||||
local-storage-view-file-dot-env.sh
|
||||
lib/
|
||||
--env-vars-reader.sh --env-vars-validator.sh
|
||||
--index-api.sh --index.sh
|
||||
-export-env-variable.sh
|
||||
-export-env-variables-from-file-dot-env.sh
|
||||
-export-env-variables-from-file.sh
|
||||
-get-env-variable-key-from-line.sh
|
||||
-get-env-variable-value-from-line.sh
|
||||
-log-env-vars.sh
|
||||
-prompt-for-env-var.sh
|
||||
local-storage/
|
||||
--index-api.sh
|
||||
-ensure-existance-file.sh -ensure-existance-file-dot-env.sh
|
||||
-read-lines-from-file.sh -read-lines-from-file-dot-env.sh
|
||||
-reset-file.sh -reset-file-dot-env.sh
|
||||
-save-env-variable-2-file.sh -save-env-variable-2-file-dot-env.sh
|
||||
-view-file.sh -view-file-dot-env.sh
|
||||
```
|
||||
|
||||
### Which entrypoint to source — this matters
|
||||
|
||||
```bash
|
||||
# From another module, when you only need base's shared functions:
|
||||
. ./.scripts/base/lib/--index-api.sh
|
||||
|
||||
# Only from base's own api/ wrappers:
|
||||
. ./.scripts/base/lib/--index.sh
|
||||
```
|
||||
|
||||
`base/lib/--index.sh` runs base's reader and validator, and **reads `.env` and
|
||||
environment-specific files as a side effect**. Sourcing it from a library function pulls that
|
||||
whole environment into an unrelated command — values appear that nobody set, and the failure
|
||||
is hard to trace because nothing in the calling module mentions `.env`.
|
||||
|
||||
`--index-api.sh` defines functions and nothing else, which is why it is the correct dependency
|
||||
edge between modules.
|
||||
|
||||
Rules:
|
||||
|
||||
1. Prefer `base/lib/--index-api.sh` from other modules.
|
||||
2. Nested lib packages such as `lib/local-storage/` carry their own `--index-api.sh` and are
|
||||
sourced from the parent's.
|
||||
3. Never log secret values — redact tokens, API keys, passwords, kube config, credentials.
|
||||
|
||||
---
|
||||
|
||||
## 3. The logging bootstrap rule
|
||||
|
||||
**A logger function whose level flag is unset prints nothing and returns 0.**
|
||||
|
||||
Every `_loggers_*` function is guarded by its level flag:
|
||||
|
||||
```bash
|
||||
if [ "${LOGGER_IS_ENABLED_INFO}" = true ]; then ... fi
|
||||
```
|
||||
|
||||
An unset flag is not `true`, so the call is a silent no-op with a success exit code. Nothing
|
||||
fails, nothing warns — the command simply produces no output, which reads like a bug in the
|
||||
command rather than in its bootstrap.
|
||||
|
||||
Those flags are exported by `loggers/lib/--env-vars-reader.sh`. For logging to work, that
|
||||
reader must have run before any logger call.
|
||||
|
||||
In the shipped `assets/loggers/`, `--index-api.sh` sources the reader itself, so any module
|
||||
that sources the logger API gets working logging with no extra step. The reader uses
|
||||
`${VAR:-default}` throughout, so it is safe to source repeatedly and a caller's override
|
||||
still wins.
|
||||
|
||||
**If you are adapting an existing `loggers` module rather than using the shipped one, check
|
||||
this first.** A `--index-api.sh` that sources only the logger function files, without the
|
||||
reader, silences every module that depends on it — while `bash -n` passes and every command
|
||||
exits 0.
|
||||
|
||||
Quick check in any repository:
|
||||
|
||||
```bash
|
||||
grep -n 'env-vars-reader' .scripts/loggers/lib/--index-api.sh \
|
||||
|| echo "WARNING: loggers API does not bootstrap its level flags — logging may be silent"
|
||||
```
|
||||
|
||||
Direct test:
|
||||
|
||||
```bash
|
||||
bash -c '. ./.scripts/loggers/lib/--index-api.sh; _loggers_info "check" "visible?"'
|
||||
```
|
||||
|
||||
No output means the flags were never exported.
|
||||
@@ -0,0 +1,76 @@
|
||||
# Taskfile Integration
|
||||
|
||||
Exposing module commands through the `task` runner.
|
||||
|
||||
Add a module `Taskfile.yml` only when its commands should be discoverable through `task`. A
|
||||
module that is only consumed by other modules does not need one.
|
||||
|
||||
---
|
||||
|
||||
## 1. Module `Taskfile.yml`
|
||||
|
||||
```yaml
|
||||
# https://taskfile.dev
|
||||
|
||||
version: "3"
|
||||
|
||||
tasks:
|
||||
initialize-one:
|
||||
cmds:
|
||||
- |
|
||||
./.scripts/module-example-v1/api/initialize-one.sh {{.CLI_ARGS}}
|
||||
silent: true
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
1. Task names mirror the public `api/` command names, unless an alias is deliberate. A task
|
||||
named differently from the script it runs makes `task --list` output impossible to map back
|
||||
to files.
|
||||
2. Forward `{{.CLI_ARGS}}` whenever the command accepts flags.
|
||||
3. `silent: true` suppresses task's own command echo, so only the script's logger output
|
||||
appears.
|
||||
4. Invoke the `api/` wrapper — never a `lib/` file directly.
|
||||
5. The path is repository-root-relative, matching how the scripts source their dependencies.
|
||||
|
||||
Arguments pass through after `--`:
|
||||
|
||||
```bash
|
||||
task module-example-v1:initialize-one -- --name demo --dry-run
|
||||
```
|
||||
|
||||
Without the `--`, task treats the flags as its own and the script never sees them.
|
||||
|
||||
---
|
||||
|
||||
## 2. Root `Taskfile.yml` include
|
||||
|
||||
```yaml
|
||||
includes:
|
||||
module-example-v1: ./.scripts/module-example-v1/Taskfile.yml
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
1. Add a root include only for a module intended as a **stable public task namespace**. The
|
||||
include name becomes a permanent user-facing prefix; renaming it later breaks every
|
||||
documented command and every CI invocation.
|
||||
2. Choose a short, clear namespace. Existing examples include `ca`, `kube`, `npmrc`,
|
||||
`repos-local`, and `repos-local-nodejs`.
|
||||
3. Do not add includes for experimental or in-progress modules — run them through their `api/`
|
||||
path until the interface settles.
|
||||
|
||||
---
|
||||
|
||||
## 3. Verifying
|
||||
|
||||
```bash
|
||||
# Every included namespace and task, with descriptions
|
||||
task --list-all
|
||||
|
||||
# Confirm a specific task resolves and forwards arguments
|
||||
task <module-alias>:<task-name> -- --dry-run
|
||||
```
|
||||
|
||||
`task --list` shows only tasks carrying a `desc:`; `task --list-all` shows everything. A task
|
||||
missing from `--list-all` means the root include is absent or its path is wrong.
|
||||
@@ -0,0 +1,118 @@
|
||||
# Workflows
|
||||
|
||||
Creating a module, changing an existing one, and the checks to run before delivering either.
|
||||
|
||||
---
|
||||
|
||||
## 1. Creating a new module
|
||||
|
||||
1. **Confirm the module name and namespace** — the kebab-case directory name, the
|
||||
`_camelCase_` function prefix, and the `UPPER_SNAKE_` environment prefix all derive from it
|
||||
and must agree.
|
||||
2. **Inspect nearby modules** for a comparable pattern before designing a new one. Matching an
|
||||
existing module beats inventing a variant.
|
||||
3. **Copy the scaffold:**
|
||||
|
||||
```bash
|
||||
cp -R assets/module-example-v1 .scripts/<new-module>
|
||||
```
|
||||
|
||||
4. **Rename throughout** — every `module-example-v1` path, `MODULE_EXAMPLE_V1_`, and
|
||||
`_moduleExampleV1_`:
|
||||
|
||||
```bash
|
||||
cd .scripts/<new-module>
|
||||
grep -rl 'module-example-v1\|MODULE_EXAMPLE_V1_\|_moduleExampleV1_' . | while read -r f; do
|
||||
sed -i '' \
|
||||
-e 's|module-example-v1|<new-module>|g' \
|
||||
-e 's|MODULE_EXAMPLE_V1_|<NEW_MODULE>_|g' \
|
||||
-e 's|_moduleExampleV1_|_<newModule>_|g' "$f"
|
||||
done
|
||||
grep -rn 'module-example-v1\|MODULE_EXAMPLE_V1_\|_moduleExampleV1_' . || echo "rename complete"
|
||||
```
|
||||
|
||||
(`sed -i ''` is BSD/macOS; use `sed -i` on GNU.)
|
||||
|
||||
5. **Set the defaults and flags** in `lib/--env-vars-reader.sh`, using `${VAR:-default}`.
|
||||
6. **Set the required-input checks** in `lib/--env-vars-validator.sh`.
|
||||
7. **Write implementation files** as `lib/-<command>.sh`, one function each.
|
||||
8. **Source every implementation file** from `lib/--index-api.sh`.
|
||||
9. **Add `api/<command>.sh` wrappers** for user-facing commands only.
|
||||
10. **Add a module `Taskfile.yml`**, and a root include only if the namespace is stable —
|
||||
`references/taskfile.md`.
|
||||
11. **Make scripts executable** where they will be invoked directly:
|
||||
`chmod +x .scripts/<new-module>/api/*.sh`.
|
||||
12. **Validate** — section 3.
|
||||
13. **Update the repository's script documentation** if it has a memory bank or equivalent.
|
||||
|
||||
---
|
||||
|
||||
## 2. Changing an existing module
|
||||
|
||||
1. **Read `lib/--index.sh` and `lib/--index-api.sh` first.** They show what the module loads
|
||||
and in what order, which determines where a change can safely go.
|
||||
2. **Decide which layer the change belongs to:**
|
||||
|
||||
| The change is | It belongs in |
|
||||
|---|---|
|
||||
| A new user-facing command | `api/` + `lib/-<command>.sh` + `--index-api.sh` |
|
||||
| New behaviour in an existing command | that command's `lib/-<command>.sh` |
|
||||
| A new CLI flag or default | `--env-vars-reader.sh` |
|
||||
| A new required input | `--env-vars-validator.sh` |
|
||||
| Task-runner exposure | module `Taskfile.yml`, and the root include if public |
|
||||
|
||||
3. **Preserve the existing naming and function prefixes.** Consistency inside a module beats
|
||||
matching a newer convention used elsewhere — mixed prefixes in one module are worse than an
|
||||
old prefix used uniformly.
|
||||
4. **Add every new `lib/-*.sh` to `--index-api.sh`** as you create it, not afterwards.
|
||||
5. **Add `api/` wrappers only for user-facing commands**; internal helpers stay in `lib/`.
|
||||
6. **Validate** — section 3.
|
||||
7. **Update the script documentation** when public behaviour changes.
|
||||
|
||||
---
|
||||
|
||||
## 3. Validation checklist
|
||||
|
||||
- [ ] Public commands are under `api/`; reusable implementation is under `lib/`.
|
||||
- [ ] `api/` wrappers are thin — source `lib/--index.sh`, call one function.
|
||||
- [ ] `lib/--index.sh` sources reader, validator, API index, in that order.
|
||||
- [ ] `lib/--index-api.sh` sources every implementation file the wrappers need.
|
||||
- [ ] New CLI flags are parsed in `--env-vars-reader.sh`, using `${VAR:-default}`.
|
||||
- [ ] Required variables are validated before use.
|
||||
- [ ] Logs use `_loggers_*` helpers, and logging actually produces output.
|
||||
- [ ] No secret values are printed or documented.
|
||||
- [ ] Implementation functions `return` rather than `exit`.
|
||||
- [ ] Taskfile entries invoke `./.scripts/<module>/api/<command>.sh {{.CLI_ARGS}}`.
|
||||
- [ ] A root `Taskfile.yml` include was added only if intended.
|
||||
- [ ] `bash -n` passes for every changed script.
|
||||
- [ ] The command was actually run once from the repository root.
|
||||
- [ ] Script documentation is updated when public behaviour changed.
|
||||
|
||||
---
|
||||
|
||||
## 4. Validation commands
|
||||
|
||||
```bash
|
||||
# Syntax check every script in the module
|
||||
find .scripts/<module> -name '*.sh' -print0 | xargs -0 -n1 bash -n
|
||||
|
||||
# Every implementation file is wired into the API index.
|
||||
# Note the `--` before the pattern: implementation basenames start with a dash,
|
||||
# which grep would otherwise parse as an option flag and report every file.
|
||||
cd .scripts/<module>
|
||||
for f in lib/-*.sh; do
|
||||
case "$f" in lib/--*) continue;; esac
|
||||
grep -qF -- "$(basename "$f")" lib/--index-api.sh || echo "NOT INDEXED: $f"
|
||||
done
|
||||
|
||||
# Task exposure resolves
|
||||
task --list-all
|
||||
|
||||
# Run it — the only check that proves the wiring works
|
||||
./.scripts/<module>/api/<command>.sh --dry-run
|
||||
```
|
||||
|
||||
`bash -n` proves a file parses. It does **not** prove a function is reachable, that a flag is
|
||||
handled, or that logging is bootstrapped — all three fail silently at runtime while every
|
||||
static check passes. The final run is the one that matters; a `--dry-run` flag exists to make
|
||||
it cheap and safe.
|
||||
Reference in New Issue
Block a user