@@ -27,6 +27,7 @@ A fast and simple command-line template rendering tool using [MiniJinja](https:/
2727 - [ Path Manipulation Functions] ( #path-manipulation-functions )
2828 - [ Data Parsing Functions] ( #data-parsing-functions )
2929 - [ Validation Functions] ( #validation-functions )
30+ - [ Debugging & Development Functions] ( #debugging--development-functions )
3031- [ Advanced Examples] ( #advanced-examples )
3132- [ Error Handling] ( #error-handling )
3233- [ Development] ( #development )
@@ -75,6 +76,7 @@ tmpltool greeting.tmpl
7576- ** Data Parsing** : Parse and read JSON, YAML, TOML files
7677- ** Validation** : Validate emails, URLs, IPs, UUIDs, regex matching
7778- ** System & Network** : Get hostname, username, directories, IP addresses, DNS resolution, port availability
79+ - ** Debugging & Development** : Debug output, type checking, assertions, warnings, error handling
7880- ** String Filters** : 12+ filters for case conversion, indentation, padding, quoting, and more
7981- ** Security** : Built-in protections with optional ` --trust ` mode
8082- ** Flexible I/O** : File or stdin input, file or stdout output
@@ -2117,6 +2119,270 @@ Correlation ID: {{ correlation_id }}
21172119{% endif %}
21182120```
21192121
2122+ ### Debugging & Development Functions
2123+
2124+ Functions for debugging templates, validating data, and controlling template execution flow during development and production.
2125+
2126+ #### `debug(value)`
2127+
2128+ Print a value to stderr and return it unchanged. Useful for inspecting values during template development.
2129+
2130+ **Arguments:**
2131+ - `value` (required) - Value to debug
2132+
2133+ **Returns:** The same value (allows chaining)
2134+
2135+ **Examples:**
2136+ ```jinja
2137+ {# Debug a variable #}
2138+ {% set config = debug(value=parse_json(string=' {" port" : 8080}' )) %}
2139+ Port: {{ config.port }}
2140+
2141+ {# Debug in a pipeline #}
2142+ Result: {{ get_env(name="PATH") | debug }}
2143+
2144+ {# Debug intermediate values #}
2145+ {% set users = debug(value=filter_env(pattern="USER_*")) %}
2146+ Found {{ users | length }} user variables
2147+ ```
2148+
2149+ **Output to stderr:**
2150+ ```
2151+ [DEBUG] {"port": 8080}
2152+ [DEBUG] /usr/local/bin:/usr/bin:/bin
2153+ [DEBUG] [{"key": "USER_NAME", "value": "admin"}]
2154+ ```
2155+
2156+ #### `type_of(value)`
2157+
2158+ Get the type of a value. Returns a string describing the value type.
2159+
2160+ **Arguments:**
2161+ - `value` (required) - Value to check
2162+
2163+ **Returns:** String type name: `"string"`, `"number"`, `"bool"`, `"array"`, `"object"`, `"undefined"`
2164+
2165+ **Examples:**
2166+ ```jinja
2167+ {{ type_of(value="hello") }} {# Output: string #}
2168+ {{ type_of(value=123) }} {# Output: number #}
2169+ {{ type_of(value=true) }} {# Output: bool #}
2170+ {{ type_of(value=[1,2,3]) }} {# Output: array #}
2171+
2172+ {# Conditional logic based on type #}
2173+ {% set data = get_env(name="DATA", default="[]") %}
2174+ {% if type_of(value=data) == "string" %}
2175+ {% set data = parse_json(string=data) %}
2176+ {% endif %}
2177+
2178+ {# Type-safe processing #}
2179+ {% if type_of(value=config.workers) == "number" %}
2180+ Workers: {{ config.workers }}
2181+ {% else %}
2182+ Workers: {{ config.workers | int }}
2183+ {% endif %}
2184+ ```
2185+
2186+ #### `inspect(value)`
2187+
2188+ Pretty-print a value' s structure to stderr and return it unchanged. Shows detailed structure of complex objects and arrays.
2189+
2190+ ** Arguments:**
2191+ - ` value` (required) - Value to inspect
2192+
2193+ ** Returns:** The same value (allows chaining)
2194+
2195+ ** Examples:**
2196+ ` ` ` jinja
2197+ {# Inspect complex data structures #}
2198+ {% set config = inspect(value=read_json_file(path=" config.json" )) %}
2199+
2200+ {# Inspect and continue #}
2201+ {% set env_vars = inspect(value=filter_env(pattern=" DB_*" )) %}
2202+ Database variables: {{ env_vars | length }}
2203+ ` ` `
2204+
2205+ ** Output to stderr:**
2206+ ` ` `
2207+ [INSPECT] {
2208+ " database" : {
2209+ " host" : " localhost" ,
2210+ " port" : 5432,
2211+ " name" : " myapp"
2212+ },
2213+ " redis" : {
2214+ " host" : " localhost" ,
2215+ " port" : 6379
2216+ }
2217+ }
2218+ ` ` `
2219+
2220+ # ### `assert(condition, message)`
2221+
2222+ Assert that a condition is true, otherwise abort rendering with an error message.
2223+
2224+ ** Arguments:**
2225+ - ` condition` (required) - Boolean condition to check
2226+ - ` message` (optional) - Error message if assertion fails (default: " Assertion failed" )
2227+
2228+ ** Returns:** ` true` if condition passes
2229+
2230+ ** Examples:**
2231+ ` ` ` jinja
2232+ {# Assert required environment variable #}
2233+ {% set port = get_env(name="PORT", default="") %}
2234+ {{ assert(condition=port != "", message="PORT environment variable is required") }}
2235+
2236+ {# Assert file exists before reading #}
2237+ {{ assert(condition=file_exists(path="config.json"), message="config.json not found") }}
2238+ {% set config = read_file(path="config.json") %}
2239+
2240+ {# Assert valid range #}
2241+ {% set workers = get_env(name="WORKERS", default="4") | int %}
2242+ {{ assert(condition=workers >= 1 and workers <= 100, message="WORKERS must be between 1 and 100") }}
2243+
2244+ {# Assert valid email format #}
2245+ {% set admin_email = get_env(name="ADMIN_EMAIL") %}
2246+ {{ assert(condition=is_email(string=admin_email), message="ADMIN_EMAIL must be valid email") }}
2247+ ` ` `
2248+
2249+ ** Error output (if assertion fails):**
2250+ ` ` `
2251+ Error: PORT environment variable is required
2252+ ` ` `
2253+
2254+ # ### `warn(message)`
2255+
2256+ Print a warning message to stderr and continue rendering. Non-fatal warnings for deprecated features or missing optional configuration.
2257+
2258+ ** Arguments:**
2259+ - ` message` (required) - Warning message
2260+
2261+ ** Returns:** Empty string (no template output)
2262+
2263+ ** Examples:**
2264+ ` ` ` jinja
2265+ {# Warn about missing optional config #}
2266+ {% if not file_exists(path="custom.conf") %}
2267+ {{ warn(message="custom.conf not found, using defaults") }}
2268+ {% endif %}
2269+
2270+ {# Warn about deprecated environment variable #}
2271+ {% set old_var = get_env(name="DEPRECATED_VAR", default="") %}
2272+ {% if old_var %}
2273+ {{ warn(message="DEPRECATED_VAR is deprecated, use NEW_VAR instead") }}
2274+ {% set new_var = old_var %}
2275+ {% else %}
2276+ {% set new_var = get_env(name="NEW_VAR", default="default") %}
2277+ {% endif %}
2278+
2279+ {# Warn about potentially unsafe configuration #}
2280+ {% set debug = get_env(name="DEBUG", default="false") %}
2281+ {% set env = get_env(name="APP_ENV", default="development") %}
2282+ {% if debug == "true" and env == "production" %}
2283+ {{ warn(message="WARNING: DEBUG mode enabled in production environment") }}
2284+ {% endif %}
2285+ ` ` `
2286+
2287+ ** Output to stderr:**
2288+ ` ` `
2289+ [WARNING] custom.conf not found, using defaults
2290+ [WARNING] DEPRECATED_VAR is deprecated, use NEW_VAR instead
2291+ [WARNING] WARNING: DEBUG mode enabled in production environment
2292+ ` ` `
2293+
2294+ # ### `abort(message)`
2295+
2296+ Immediately abort template rendering with an error message. Use for critical failures where rendering should not continue.
2297+
2298+ ** Arguments:**
2299+ - ` message` (required) - Error message
2300+
2301+ ** Returns:** Never returns (always throws error)
2302+
2303+ ** Examples:**
2304+ ` ` ` jinja
2305+ {# Abort if critical file missing #}
2306+ {% if not file_exists(path="critical.conf") %}
2307+ {{ abort(message="Critical configuration file 'critical.conf' is missing") }}
2308+ {% endif %}
2309+
2310+ {# Abort if environment is invalid #}
2311+ {% set env = get_env(name="APP_ENV", default="") %}
2312+ {% if env not in ["development", "staging", "production"] %}
2313+ {{ abort(message="Invalid APP_ENV: must be development, staging, or production, got: " ~ env) }}
2314+ {% endif %}
2315+
2316+ {# Abort on validation failure #}
2317+ {% set port = get_env(name="PORT", default="8080") | int %}
2318+ {% if port < 1024 or port > 65535 %}
2319+ {{ abort(message="Invalid PORT: must be between 1024 and 65535, got: " ~ port) }}
2320+ {% endif %}
2321+
2322+ {# Abort if required secrets are missing #}
2323+ {% set api_key = get_env(name="API_KEY", default="") %}
2324+ {% set db_password = get_env(name="DB_PASSWORD", default="") %}
2325+ {% if api_key == "" or db_password == "" %}
2326+ {{ abort(message="Missing required secrets: API_KEY and DB_PASSWORD must be set") }}
2327+ {% endif %}
2328+ ` ` `
2329+
2330+ ** Error output:**
2331+ ` ` `
2332+ Error: Critical configuration file ' critical.conf' is missing
2333+ ` ` `
2334+
2335+ ** Practical Example - Configuration Validation:**
2336+ ` ` ` yaml
2337+ # Production Configuration Template
2338+
2339+ # Validate critical environment
2340+ {% set env = get_env(name=" APP_ENV" , default=" " ) %}
2341+ {{ assert(condition=env in [" staging" , " production" ], message=" APP_ENV must be staging or production" ) }}
2342+
2343+ # Validate required secrets
2344+ {% set db_url = get_env(name=" DATABASE_URL" , default=" " ) %}
2345+ {{ assert(condition=db_url ! = " " , message=" DATABASE_URL is required" ) }}
2346+
2347+ {% set api_key = get_env(name=" API_KEY" , default=" " ) %}
2348+ {{ assert(condition=api_key ! = " " , message=" API_KEY is required" ) }}
2349+
2350+ # Warn about debug mode
2351+ {% set debug = get_env(name=" DEBUG" , default=" false" ) %}
2352+ {% if debug == " true" %}
2353+ {{ warn(message=" DEBUG mode is enabled in " ~ env) }}
2354+ {% endif %}
2355+
2356+ # Debug configuration for troubleshooting
2357+ {% set config = {
2358+ " environment" : env,
2359+ " database" : db_url,
2360+ " debug" : debug
2361+ } %}
2362+ {{ inspect(value=config) }}
2363+
2364+ # Type-safe port configuration
2365+ {% set port = get_env(name=" PORT" , default=" 8080" ) %}
2366+ {% if type_of(value=port) == " string" %}
2367+ {% set port = port | int %}
2368+ {% endif %}
2369+ {{ assert(condition=port > 0 and port < 65536, message=" PORT must be valid" ) }}
2370+
2371+ application:
2372+ environment: {{ env }}
2373+ port: {{ port }}
2374+ debug: {{ debug }}
2375+ database_url: {{ db_url }}
2376+ api_key: {{ api_key }}
2377+ ` ` `
2378+
2379+ ** Use Cases:**
2380+ - ✅ ** Development** : Debug complex data structures with ` debug()` and ` inspect()`
2381+ - ✅ ** Validation** : Ensure configuration correctness with ` assert()`
2382+ - ✅ ** Type Safety** : Check value types with ` type_of()` before operations
2383+ - ✅ ** Graceful Degradation** : Use ` warn()` for non-critical issues
2384+ - ✅ ** Fail Fast** : Use ` abort()` for critical failures requiring immediate attention
2385+
21202386# # Advanced Examples
21212387
21222388# ## Docker Compose Generator
0 commit comments