feat: workspace root microsyntax (#10094)
### Description
Microsyntax for file globbing from the workspace root. Our file globs
are anchored to packages, but there are use cases where anchoring at the
root is more preferable.
Adds `$TURBO_ROOT$` which can be used in task `inputs` and `outputs`. It
can only be used at the start of an inclusion/exclusion so
`../$TURBO_ROOT$/config.txt` isn't valid usage.
We achieve this by swapping out `$TURBO_ROOT$` as we convert a raw task
definition to a usable one. This allows us to not handle this at any
later steps since all inputs/outpus are expected to be relative to the
package directory.
### Testing Instructions
Added unit tests for:
- Replacing of `$TURBO_ROOT$` with the relative path to the repo root
- Calculation of the relative path to repo root for packages
```
[0 olszewski@macbookpro] /tmp/watch-time $ bat turbo.json
───────┬──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
│ File: turbo.json
───────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
1 │ {
2 │ "$schema": "https://turbo.build/schema.json",
3 │ "ui": "tui",
4 │ "tasks": {
5 │ "build": {
6 │ "dependsOn": ["^build"],
7 ~ │ "inputs": ["$TURBO_DEFAULT$", ".env*", "$TURBO_ROOT$/my-configs/*"],
8 │ "outputs": [".next/**", "!.next/cache/**"]
9 │ },
10 │ "lint": {
11 │ "dependsOn": ["^lint"]
12 │ },
13 │ "check-types": {
14 │ "dependsOn": ["^check-types"]
15 │ },
16 │ "dev": {
17 │ "cache": false,
18 │ "persistent": true
19 │ }
20 │ }
21 │ }
[0 olszewski@macbookpro] /tmp/watch-time $ turbo_dev --skip-infer build --output-logs=hash-only
turbo 2.4.5-canary.2
• Packages in scope: @repo/eslint-config, @repo/typescript-config, @repo/ui, docs, web
• Running build in 5 packages
• Remote caching disabled
web#build > cache hit, suppressing logs cf5b7818b9c2c383
docs#build > cache hit, suppressing logs 9306af3d3750177a
Tasks: 2 successful, 2 total
Cached: 2 cached, 2 total
Time: 110ms >>> FULL TURBO
[0 olszewski@macbookpro] /tmp/watch-time $ echo 'a change' > my-configs/config.txt
[0 olszewski@macbookpro] /tmp/watch-time $ turbo_dev --skip-infer build --output-logs=hash-only
turbo 2.4.5-canary.2
• Packages in scope: @repo/eslint-config, @repo/typescript-config, @repo/ui, docs, web
• Running build in 5 packages
• Remote caching disabled
web#build > cache miss, executing 0acfce06b3b2069d
docs#build > cache miss, executing cfb4227df7dfd1fc
Tasks: 2 successful, 2 total
Cached: 0 cached, 2 total
Time: 7.97s
[0 olszewski@macbookpro] /tmp/watch-time $ vim turbo.json
[0 olszewski@macbookpro] /tmp/watch-time $ turbo_dev --skip-infer build --output-logs=hash-only
turbo 2.4.5-canary.2
× Cannot use '$TURBO_ROOT$' anywhere besides start of string.
╭─[turbo.json:7:46]
6 │ "dependsOn": ["^build"],
7 │ "inputs": ["$TURBO_DEFAULT$", ".env*", "../$TURBO_ROOT$/my-configs/*"],
· ───────────────┬──────────────
· ╰── must be at start
8 │ "outputs": [".next/**", "!.next/cache/**"]
╰────
```
---------
Co-authored-by: Chris Olszewski <chris.olszewski@vercel.com>