feat(scoped): refactor compiler, add nested includes, document flatten

Refactor compiler.go for better maintainability:
- Extract isScopedMode() helper function
- Split getVariables() into getScopedVariables() and getLegacyVariables()
- Fix directory resolution: parent chain env/vars now resolve from their
  own directory instead of the current task's directory

Add nested includes support and tests:
- Add testdata/scoped_taskfiles/inc_a/nested/Taskfile.yml (3 levels deep)
- Add test case for nested include inheritance (root → a → nested)
- Verify nested includes inherit vars from full parent chain

Fix flaky tests:
- Remove VAR from print tasks (defined in both inc_a and inc_b)
- Test only unique variables (UNIQUE_A, UNIQUE_B, ROOT_VAR)

Document flatten: true escape hatch:
- Add migration guide step for using flatten: true
- Add new section explaining flatten bypasses scoping
- Include example and usage recommendations
This commit is contained in:
Valentin Maerten
2026-01-14 19:34:53 +01:00
parent a57a16efca
commit 2810c267dd
11 changed files with 336 additions and 116 deletions

View File

@@ -225,3 +225,57 @@ To migrate your Taskfiles to use this experiment:
- If your included Taskfiles rely on variables from sibling includes, you'll
need to either move those variables to the root Taskfile or pass them
explicitly via the `vars:` attribute in the `includes:` section.
5. **Use `flatten: true` for gradual migration**:
- If an include needs the legacy behavior (access to sibling variables), you
can use `flatten: true` on that include as an escape hatch.
## Using `flatten: true`
The `flatten: true` option on includes bypasses scoping for that specific
include. When an include has `flatten: true`:
- Its variables are merged globally (legacy behavior)
- It can access variables from sibling includes
- Sibling includes can access its variables
This is useful for gradual migration or when you have includes that genuinely
need to share variables.
### Example
```yaml
version: '3'
vars:
ROOT_VAR: from_root
includes:
# Scoped include - isolated from siblings
api:
taskfile: ./api
# Flattened include - uses legacy merge behavior
shared:
taskfile: ./shared
flatten: true
# Another scoped include
web:
taskfile: ./web
```
In this example:
- `api` and `web` are isolated from each other (cannot see each other's vars)
- `shared` uses legacy behavior: its vars are merged globally
- Both `api` and `web` can access variables from `shared`
- `shared` can access variables from `api` and `web`
::: tip
Use `flatten: true` sparingly. The goal of scoped taskfiles is to improve
isolation and predictability. Flattening should be a temporary measure during
migration or for utility includes that genuinely need global scope.
:::