diff --git a/website/.vitepress/config.ts b/website/.vitepress/config.ts index 24c675f1..db44f510 100644 --- a/website/.vitepress/config.ts +++ b/website/.vitepress/config.ts @@ -302,6 +302,10 @@ export default defineConfig({ { text: 'Remote Taskfiles (#1317)', link: '/docs/experiments/remote-taskfiles' + }, + { + text: 'Scoped Taskfiles', + link: '/docs/experiments/scoped-taskfiles' } ] }, diff --git a/website/src/docs/experiments/scoped-taskfiles.md b/website/src/docs/experiments/scoped-taskfiles.md new file mode 100644 index 00000000..7cee72e8 --- /dev/null +++ b/website/src/docs/experiments/scoped-taskfiles.md @@ -0,0 +1,201 @@ +--- +title: 'Scoped Taskfiles' +description: + Experiment for variable isolation and env namespace in included Taskfiles +outline: deep +--- + +# Scoped Taskfiles + +::: warning + +All experimental features are subject to breaking changes and/or removal _at any +time_. We strongly recommend that you do not use these features in a production +environment. They are intended for testing and feedback only. + +::: + +::: danger + +This experiment breaks the following functionality: + +- **Environment variables are no longer available at root level in templates** + - Before: `{{.PATH}}`, `{{.MY_ENV}}` + - After: `{{.env.PATH}}`, + `{{.env.MY_ENV}}` +- **Variables from sibling includes are no longer visible** + - Include A cannot access variables defined in Include B + - Each include only sees: root vars + its own vars + parent vars + +::: + +::: info + +To enable this experiment, set the environment variable: +`TASK_X_SCOPED_TASKFILES=1`. Check out +[our guide to enabling experiments](./index.md#enabling-experiments) for more +information. + +::: + +This experiment introduces two major changes to how variables work in Task: + +1. **Environment namespace**: Environment variables (both OS and Taskfile `env:` + sections) are moved to a dedicated `{{.env.XXX}}` + namespace, separating them from regular variables +2. **Variable scoping**: Variables defined in included Taskfiles are isolated - + sibling includes cannot see each other's variables + +## Environment Namespace + +With this experiment enabled, environment variables are no longer mixed with +regular variables at the template root level. Instead, they are accessible +through the `{{.env.XXX}}` namespace. + +### Comparison Table + +| Template | Legacy | SCOPED_TASKFILES | +| ----------------------------------------------- | ------ | ------------------------- | +| `{{.MY_VAR}}` (from `vars:`) | Works | Works | +| `{{.MY_ENV}}` (from `env:`) | Works | `` | +| `{{.env.MY_ENV}}` | - | Works | +| `{{.PATH}}` (OS) | Works | `` | +| `{{.env.PATH}}` (OS) | - | Works | +| `{{.TASK}}` (special) | Works | Works (stays at root) | + +### Example + +```yaml +version: '3' + +env: + DB_HOST: localhost + +vars: + DB_NAME: mydb + +tasks: + show: + cmds: + # Access Taskfile env: section + - echo "Host: {{.env.DB_HOST}}" + + # Access regular vars (unchanged) + - echo "Name: {{.DB_NAME}}" + + # Access OS environment variables + - echo "Path: {{.env.PATH}}" + + # Special variables stay at root level + - echo "Task: {{.TASK}}" +``` + +## Variable Scoping + +Variables defined in included Taskfiles are now isolated from each other. +Sibling includes cannot access each other's variables, but child includes can +still inherit variables from their parent. + +### Example + +```yaml +# Taskfile.yml +version: '3' + +vars: + ROOT_VAR: from_root + +includes: + api: ./api + web: ./web +``` + +```yaml +# api/Taskfile.yml +version: '3' + +vars: + API_VAR: from_api + +tasks: + show: + cmds: + # Inherited from root - works + - echo "ROOT_VAR={{.ROOT_VAR}}" + + # Own variable - works + - echo "API_VAR={{.API_VAR}}" + + # From sibling include - NOT visible + - echo "WEB_VAR={{.WEB_VAR}}" +``` + +```yaml +# web/Taskfile.yml +version: '3' + +vars: + WEB_VAR: from_web + +tasks: + show: + cmds: + # Inherited from root - works + - echo "ROOT_VAR={{.ROOT_VAR}}" + + # Own variable - works + - echo "WEB_VAR={{.WEB_VAR}}" + + # From sibling include - NOT visible + - echo "API_VAR={{.API_VAR}}" +``` + +## CLI Variables Priority + +With this experiment, CLI variables (passed as `task foo VAR=value`) have the +highest priority and will override task-level variables. + +```yaml +version: '3' + +tasks: + greet: + vars: + NAME: from_task + cmds: + - echo "Hello {{.NAME}}" +``` + +```bash +# CLI vars now override task vars +TASK_X_SCOPED_TASKFILES=1 task greet NAME=cli +# Output: Hello cli +``` + +## Migration Guide + +To migrate your Taskfiles to use this experiment: + +1. **Update environment variable references** in your templates: + + - `{{.PATH}}` becomes + `{{.env.PATH}}` + - `{{.HOME}}` becomes + `{{.env.HOME}}` + - `{{.MY_TASKFILE_ENV}}` becomes + `{{.env.MY_TASKFILE_ENV}}` + +2. **Variables in `vars:` sections remain unchanged**: + + - `{{.MY_VAR}}` still works the same way + +3. **Special variables stay at root level**: + + - `{{.TASK}}`, `{{.ROOT_DIR}}`, + `{{.TASKFILE}}`, `{{.TASKFILE_DIR}}`, + etc. + +4. **Review cross-include variable dependencies**: + - 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.