Commit 02d570b
fix(ttsc): make TS config loaders and the virtual layout Windows-safe (#308)
* fix(lint,banner,strip): make TS config loaders volume-aware on Windows
The lint fix from #300 left two byte-identical siblings hardcoding the
loader tsconfig's rootDir to "/", which is never an ancestor of
drive-letter paths (TS6059, #304). Extract the volume-root resolution
into a named loaderRootDir helper (also restoring gofmt-stable
formatting in linthost) and apply it to the banner and strip drivers.
Rooting at the volume is still not enough when the system temp dir and
the config file live on different drives: no single rootDir spans two
volumes and relative import specifiers cannot cross them (#305). Create
the ephemeral loader tree under the config's nearest
node_modules/.cache in that case — on all three Go drivers and the
lint JS factory — keeping the system temp dir whenever the volumes
already match.
Also normalize separators in the runtime hooks' isWithin so the
slash-form manifest rootDir the loader tsconfig now emits (C:/) matches
native real paths, and align the ttsx e2e fixture that mirrored the
loader's rootDir synthesis.
Resolves #304, resolves #305.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix(ttsc): copy file-symlink virtual entries when symlinks need privilege
linkVirtualEntry handled directories, plain files, and directory-target
symlinks in a Windows-safe way, but its final branch re-symlinked file
symlinks with a bare fs.symlinkSync — which needs
SeCreateSymbolicLinkPrivilege on Windows and crashed the run with EPERM
without admin rights or Developer Mode (#306, same class as #218).
Mirror the plain-file branch's hard-link/copy fallback, and skip a link
whose target no longer exists: it can serve no module and none of the
fallbacks can materialize it.
Resolves #306.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix(lint,banner,strip,ttsc): close the loader-volume and symlink edges
Driving the whole loader chain end-to-end on a two-volume Windows
machine surfaced three gaps in the previous commit:
- A linked node_modules (junction/symlink) broke the loader: the ESM
runtime realpaths the loader module at import time, so a relative
config specifier computed from the link-form .cache path resolved
against the wrong directory. The temp base is realpathed now; NTFS
junctions defeat filepath.EvalSymlinks, so the Go drivers chase the
link component with os.Readlink first.
- Cross-volume configs with no usable node_modules/.cache fell back to
the system temp dir — guaranteed to fail. They now fall back to the
config's own directory, which is always on the right volume and keeps
the relative import a plain "./".
- isWithin now compares case-insensitively on Windows (a lowercase TEMP
yields a c:-rooted manifest rootDir for the volume real paths spell
C:), and is exported alongside linkVirtualEntry so the e2e suite can
pin the Windows normalization and EPERM-fallback branches that a
spawned run cannot reach on CI.
New coverage: the temp-base tests pin the blocked-.cache, missing
node_modules, and junction realpath branches; api e2e tests drive
linkVirtualEntry's copy fallback and dangling-entry skip (the dangling
fixture is a junction, so it exercises the real privilege-less EPERM
path on Windows) and isWithin's root/slash/case matching. Verified on
Windows 11 with the project on D: and TEMP on C:, including live
cross-drive config evaluation through real ttsx + tsgo on both the JS
factory and the Go driver paths.
Refs #304, #305, #306.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* ci(test): add a Windows Go-suite lane and make it green
Add a windows-latest matrix entry running `pnpm run test:go` as the
minimal Windows safety net — the Go unit suites cover the
platform-sensitive layers (config loaders, path handling) without the
POSIX-only e2e runner, and only need the ttsx launcher build.
Everything that kept that lane red gets fixed with it:
- scripts/test-go-utility-plugins.cjs wrote forward-slash `use` paths
into its go.work; Go's workspace-module matching on Windows rejects
them ("directory ... is not one of the workspace modules"), so every
suite failed at setup. Write native separators.
- packages/ttsc's build script copied README with unix `cp`, which cmd
has no notion of; use a node one-liner.
- The banner suites faked launchers as extensionless `#!/bin/sh`
scripts, which Windows cannot spawn. A new writeDirectLauncher helper
emits the sh script on POSIX and an equivalent `.cmd` on Windows,
keeping both off the node-routed extension list.
- The tempdir-failure case pointed TMPDIR at a file; os.TempDir reads
TMP/TEMP on Windows, so override those there.
- Two assertions were unhermetic on machines with a stray drive-root
node_modules; they now tolerate discoveries outside the fixture.
The relative-config-path case surfaced a real regression in the new
loaderTempBase helpers: a volume-less location compared unequal to the
system temp's volume and was misrouted to the cross-volume branch,
breaking the Rel-failure contract (and creating loader dirs relative to
the cwd). All four helpers now keep the historical default for
volume-less locations, with test scenarios pinning it.
Refs #304, #305.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* chore: drop a leaked paths test fixture from the tree
A locally-run paths Go test materializes its external-file fixture
inside the package directory and leaves it behind; the previous commit
swept it up unintentionally.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix(paths,ci): unblock the Windows Go lane on split-volume runners
Two problems surfaced running the paths suite on a machine whose repo
and temp dir live on different drives (the windows-latest layout):
- TestCommandRewritesAllModuleSpecifierForms materialized its external
files-list fixture inside the package directory. With the project in
the system temp dir that makes the tsconfig `files` list span two
volumes, and project loading hangs until the go test timeout (#310
tracks the sidecar behavior; tsc errors fast on the same input). The
fixture moves to a sibling temp dir — still outside the tsconfig
directory, same volume, and it can no longer leak into the tree when
a test dies mid-run.
- The utility-plugin runner now prewarms the plugin/driver build before
`go test`: the command tests `go run ./plugin` during test execution,
so on a cold CI cache the full typescript-go compile counted against
the 10-minute test timeout.
With these, all three utility suites pass on Windows for the first
time (banner 16s, paths 20s, strip 27s locally).
Refs #308, #310.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* chore: drop leaked paths fixtures again
Residue from the two timed-out suite runs predating the fixture
relocation; the previous commit swept them up. The relocation itself
prevents any further leaks.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* test: normalize the cross-volume temp-base expectation like the helper
CI Windows runners hand out an 8.3 short-name TEMP (RUNNER~1), so the
helper's EvalSymlinks-normalized result never compared equal to a raw
Join of the fixture root even though both name the same directory.
Normalize the expectation the same way.
Refs #308.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* test: narrow the Dirent fixture lookup before use
assert.ok on `entry?.isSymbolicLink()` narrows that expression, not
`entry`, so the `Dirent | undefined` from Array.find reached
linkVirtualEntry and failed typecheck. Assert existence first.
Refs #308.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* test: front the stderr redirect in the Windows fake launcher
A trailing `>&2` glued to a payload ending in a digit would turn that
digit into a file-descriptor redirect; putting the redirect first
sidesteps both that and the trailing-space form. Also document the
cmd-metacharacter constraint on payloads.
Refs #308.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>1 parent 1ab7956 commit 02d570b
28 files changed
Lines changed: 1131 additions & 55 deletions
File tree
- .github/workflows
- packages
- banner
- driver
- test
- lint
- linthost
- src
- test/config
- paths/test
- strip
- driver
- test
- ttsc
- src/launcher/internal
- scripts
- tests/test-ttsc/src/features
- api
- ttsx-runtime
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
20 | 20 | | |
21 | 21 | | |
22 | 22 | | |
23 | | - | |
| 23 | + | |
24 | 24 | | |
25 | 25 | | |
26 | 26 | | |
27 | 27 | | |
28 | 28 | | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
29 | 35 | | |
30 | 36 | | |
31 | 37 | | |
| |||
61 | 67 | | |
62 | 68 | | |
63 | 69 | | |
| 70 | + | |
64 | 71 | | |
65 | 72 | | |
66 | 73 | | |
67 | | - | |
| 74 | + | |
68 | 75 | | |
69 | 76 | | |
70 | 77 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
364 | 364 | | |
365 | 365 | | |
366 | 366 | | |
367 | | - | |
| 367 | + | |
368 | 368 | | |
369 | 369 | | |
370 | 370 | | |
| |||
507 | 507 | | |
508 | 508 | | |
509 | 509 | | |
510 | | - | |
| 510 | + | |
511 | 511 | | |
512 | 512 | | |
513 | 513 | | |
| |||
521 | 521 | | |
522 | 522 | | |
523 | 523 | | |
| 524 | + | |
| 525 | + | |
| 526 | + | |
| 527 | + | |
| 528 | + | |
| 529 | + | |
| 530 | + | |
| 531 | + | |
| 532 | + | |
| 533 | + | |
| 534 | + | |
| 535 | + | |
| 536 | + | |
| 537 | + | |
| 538 | + | |
| 539 | + | |
| 540 | + | |
| 541 | + | |
| 542 | + | |
| 543 | + | |
| 544 | + | |
| 545 | + | |
| 546 | + | |
| 547 | + | |
| 548 | + | |
| 549 | + | |
| 550 | + | |
| 551 | + | |
| 552 | + | |
| 553 | + | |
| 554 | + | |
| 555 | + | |
| 556 | + | |
| 557 | + | |
| 558 | + | |
| 559 | + | |
| 560 | + | |
| 561 | + | |
| 562 | + | |
| 563 | + | |
| 564 | + | |
| 565 | + | |
| 566 | + | |
| 567 | + | |
| 568 | + | |
| 569 | + | |
| 570 | + | |
| 571 | + | |
| 572 | + | |
| 573 | + | |
| 574 | + | |
| 575 | + | |
| 576 | + | |
| 577 | + | |
| 578 | + | |
| 579 | + | |
| 580 | + | |
| 581 | + | |
| 582 | + | |
| 583 | + | |
| 584 | + | |
| 585 | + | |
| 586 | + | |
| 587 | + | |
| 588 | + | |
| 589 | + | |
| 590 | + | |
| 591 | + | |
| 592 | + | |
| 593 | + | |
| 594 | + | |
| 595 | + | |
524 | 596 | | |
525 | 597 | | |
526 | 598 | | |
| |||
Lines changed: 111 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
139 | 139 | | |
140 | 140 | | |
141 | 141 | | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
142 | 179 | | |
143 | 180 | | |
144 | 181 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
57 | 57 | | |
58 | 58 | | |
59 | 59 | | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
60 | 63 | | |
61 | 64 | | |
62 | 65 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
29 | 29 | | |
30 | 30 | | |
31 | 31 | | |
32 | | - | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
33 | 36 | | |
34 | 37 | | |
35 | 38 | | |
| |||
59 | 62 | | |
60 | 63 | | |
61 | 64 | | |
62 | | - | |
63 | | - | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
64 | 71 | | |
65 | 72 | | |
66 | 73 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
77 | 77 | | |
78 | 78 | | |
79 | 79 | | |
80 | | - | |
| 80 | + | |
81 | 81 | | |
82 | 82 | | |
83 | 83 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
49 | 49 | | |
50 | 50 | | |
51 | 51 | | |
52 | | - | |
| 52 | + | |
53 | 53 | | |
54 | 54 | | |
55 | 55 | | |
56 | 56 | | |
57 | 57 | | |
58 | | - | |
| 58 | + | |
59 | 59 | | |
60 | 60 | | |
61 | 61 | | |
62 | 62 | | |
63 | 63 | | |
64 | | - | |
| 64 | + | |
65 | 65 | | |
66 | 66 | | |
67 | 67 | | |
| |||
0 commit comments