bottlerocket-os / bottlerocket-os/bottlerocket-core-kit
`schnauzer`: Disable Strict Mode Checking for Boolean Operators
- Dominant language
- Rust
- Stars
- 34
- Forks
- 77
- Avg merge
- 2d 23h
- Merged PRs (30d)
- 23
Description
**What I'd like:**
We should disable "strict" check for, at minimum, the following builtin "handlebars helpers":
* `eq`
* `ne`
* `and`
* `or`
* `not`
* others?
**Background:**
When `schnauzer` renders a template, it enables "strict mode" in our handlebars templating library. This causes templates to fail to render if they refer to context variables that are unset.
BUT that's only true under specific conditions (and in our case, some pretty inconvenient ones.)
Consider these scenarios:
```handlebars
{{#if settings.variable-that-doesnt-exist }}
hello!
{{else}}
goodbye!
{{/if}}
```
This will happily render as `goodbye!`; however, now consider this template:
```handlebars
{{#if (eq settings.variable-that-doesnt-exist "eleven") }}
hello!
{{else}}
goodbye!
{{/if}}
```
This does not render as `goodbye!` as you might expect, but instead fails to render entirely!
In handlebars parlance, `if` and `eq` are both "helpers". The "strict mode" setting in our handlebars library defers the strictness check to each setting implementation, rather than implementing it in a centralized location in the library.
This means that it depends entirely on how a helper is defined as to whether or not a strictness check occurs. In particular in the case of `if` and `eq`, they are implemented using different strategies in `handlebars-rs`.
In `handlebars-rs`, a helper is something that implements [the `HelperDef` trait](https://docs.rs/handlebars/6.3.2/handlebars/trait.HelperDef.html).
You can either manually define it using `impl HelperDef for Type { ... }`, or you can use a macro that the library provides [called `handlebars_helper!`](https://docs.rs/handlebars/6.3.2/handlebars/macro.handlebars_helper.html) to generate an implementation on your behalf.
The `eq` helper is defined using the `handlebars_helper!` macro [here](https://github.com/sunng87/handlebars-rust/blob/0e5467fdd38109d44a8f65d1df7dbacb0597ee10/src/helpers/helper_extras.rs#L6). That macro's generated `HelperDef` [checks if the handlebars registry has strict_mode enabled](https://github.com/sunng87/handlebars-rust/blob/4bf34dab4c4fd796b837d55a0fdd1162c98cb2f6/src/macros.rs#L59), and causes an error if the value is undefined.
The `if` helper uses a literal implementation of the `HelperDef` trait which [does not interact with strict_mode](https://github.com/sunng87/handlebars-rust/blob/4bf34dab4c4fd796b837d55a0fdd1162c98cb2f6/src/helpers/helper_if.rs#L15). (and I have tests that prove it!)
I have half of an implementation of the idea for a fix here, but don't have time to carry it across the finish line, so leaving it in this issue for now: https://github.com/bottlerocket-os/bottlerocket-core-kit/compare/develop...cbgbt:bottlerocket-core-kit:schnauzer-custom-bools
Contributor guide
Research direction
Start with the schnauzer-custom-bools comparison referenced in the issue, then review the handlebars-rs helper_extras.rs, macros.rs, and helper_if.rs references. Compare strict-mode behavior for eq, ne, and, or, and not, and verify that templates using unset variables render as intended without strict-mode failures.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100