ttsc 0.12.3 → 0.12.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cmd/platform/main.go +9 -0
- package/cmd/ttsc/api_compile.go +109 -101
- package/cmd/ttsc/api_compile_branches_test.go +55 -57
- package/cmd/ttsc/api_transform.go +54 -49
- package/cmd/ttsc/api_transform_branches_test.go +30 -32
- package/cmd/ttsc/build.go +111 -108
- package/cmd/ttsc/build_branches_test.go +95 -97
- package/cmd/ttsc/helpers_test.go +39 -28
- package/cmd/ttsc/main.go +111 -104
- package/cmd/ttsc/main_alias_branches_test.go +21 -23
- package/cmd/ttscserver/main.go +96 -90
- package/cmd/ttscserver/run_lsp_prefers_tsgo_flag_test.go +22 -22
- package/cmd/ttscserver/run_lsp_reports_server_error_test.go +22 -22
- package/cmd/ttscserver/run_lsp_uses_tsgo_environment_test.go +23 -23
- package/cmd/utility-host/main.go +30 -23
- package/driver/lsp.go +53 -7
- package/driver/plugins.go +88 -72
- package/driver/program.go +362 -339
- package/driver/rewrite.go +442 -380
- package/internal/lspserver/lsp_envelope.go +64 -64
- package/internal/lspserver/lsp_frame.go +60 -60
- package/internal/lspserver/lsp_plugin.go +57 -57
- package/internal/lspserver/lsp_proxy.go +265 -251
- package/internal/lspserver/lsp_server.go +155 -144
- package/lib/TtscCompiler.d.ts +7 -0
- package/lib/TtscCompiler.js +7 -0
- package/lib/TtscCompiler.js.map +1 -1
- package/lib/compiler/internal/buildNativeCompiler.d.ts +11 -1
- package/lib/compiler/internal/buildNativeCompiler.js +23 -3
- package/lib/compiler/internal/buildNativeCompiler.js.map +1 -1
- package/lib/compiler/internal/compileProjectInMemory.d.ts +9 -0
- package/lib/compiler/internal/compileProjectInMemory.js +36 -21
- package/lib/compiler/internal/compileProjectInMemory.js.map +1 -1
- package/lib/compiler/internal/paths.d.ts +27 -0
- package/lib/compiler/internal/paths.js +70 -0
- package/lib/compiler/internal/paths.js.map +1 -0
- package/lib/compiler/internal/project/readProjectConfig.d.ts +9 -1
- package/lib/compiler/internal/project/readProjectConfig.js +80 -1
- package/lib/compiler/internal/project/readProjectConfig.js.map +1 -1
- package/lib/compiler/internal/project/resolveProjectConfig.d.ts +13 -1
- package/lib/compiler/internal/project/resolveProjectConfig.js +24 -1
- package/lib/compiler/internal/project/resolveProjectConfig.js.map +1 -1
- package/lib/compiler/internal/resolveBinary.d.ts +9 -1
- package/lib/compiler/internal/resolveBinary.js +17 -1
- package/lib/compiler/internal/resolveBinary.js.map +1 -1
- package/lib/compiler/internal/resolveEmittedJavaScript.d.ts +16 -1
- package/lib/compiler/internal/resolveEmittedJavaScript.js +42 -10
- package/lib/compiler/internal/resolveEmittedJavaScript.js.map +1 -1
- package/lib/compiler/internal/resolveTsgo.d.ts +21 -1
- package/lib/compiler/internal/resolveTsgo.js +23 -1
- package/lib/compiler/internal/resolveTsgo.js.map +1 -1
- package/lib/compiler/internal/runBuild.d.ts +19 -0
- package/lib/compiler/internal/runBuild.js +112 -46
- package/lib/compiler/internal/runBuild.js.map +1 -1
- package/lib/compiler/internal/runSingleFileEmit.d.ts +10 -1
- package/lib/compiler/internal/runSingleFileEmit.js +14 -1
- package/lib/compiler/internal/runSingleFileEmit.js.map +1 -1
- package/lib/compiler/internal/sharedHostHelpers.d.ts +5 -0
- package/lib/compiler/internal/sharedHostHelpers.js +6 -2
- package/lib/compiler/internal/sharedHostHelpers.js.map +1 -1
- package/lib/compiler/internal/spawnNative.d.ts +21 -0
- package/lib/compiler/internal/spawnNative.js +59 -0
- package/lib/compiler/internal/spawnNative.js.map +1 -0
- package/lib/compiler/internal/transformProjectInMemory.d.ts +15 -1
- package/lib/compiler/internal/transformProjectInMemory.js +57 -61
- package/lib/compiler/internal/transformProjectInMemory.js.map +1 -1
- package/lib/launcher/internal/getCompilerVersionText.js +7 -0
- package/lib/launcher/internal/getCompilerVersionText.js.map +1 -1
- package/lib/launcher/internal/prepareExecution.js +32 -0
- package/lib/launcher/internal/prepareExecution.js.map +1 -1
- package/lib/launcher/internal/resolveCacheDir.d.ts +9 -0
- package/lib/launcher/internal/resolveCacheDir.js +22 -0
- package/lib/launcher/internal/resolveCacheDir.js.map +1 -0
- package/lib/launcher/internal/resolveTtscserverBinary.js +2 -0
- package/lib/launcher/internal/resolveTtscserverBinary.js.map +1 -1
- package/lib/launcher/internal/runTtsc.d.ts +10 -0
- package/lib/launcher/internal/runTtsc.js +22 -9
- package/lib/launcher/internal/runTtsc.js.map +1 -1
- package/lib/launcher/internal/runTtscserver.js +10 -35
- package/lib/launcher/internal/runTtscserver.js.map +1 -1
- package/lib/launcher/internal/runTtsx.d.ts +8 -0
- package/lib/launcher/internal/runTtsx.js +33 -7
- package/lib/launcher/internal/runTtsx.js.map +1 -1
- package/lib/plugin/internal/buildSourcePlugin.d.ts +38 -0
- package/lib/plugin/internal/buildSourcePlugin.js +40 -17
- package/lib/plugin/internal/buildSourcePlugin.js.map +1 -1
- package/lib/plugin/internal/loadProjectPlugins.d.ts +26 -0
- package/lib/plugin/internal/loadProjectPlugins.js +32 -18
- package/lib/plugin/internal/loadProjectPlugins.js.map +1 -1
- package/lib/structures/ITtscCompilerTransformation.d.ts +15 -2
- package/lib/structures/internal/TtscSingleFileEmitOptions.d.ts +0 -2
- package/package.json +9 -9
- package/shim/ast/shim.go +24 -0
- package/shim/checker/shim.go +35 -0
- package/shim/core/shim.go +17 -0
- package/shim/diagnosticwriter/shim.go +4 -0
- package/shim/lsp/shim.go +3 -3
- package/shim/printer/shim.go +20 -0
- package/src/TtscCompiler.ts +7 -0
- package/src/compiler/internal/buildNativeCompiler.ts +23 -3
- package/src/compiler/internal/compileProjectInMemory.ts +34 -25
- package/src/compiler/internal/paths.ts +68 -0
- package/src/compiler/internal/project/readProjectConfig.ts +86 -1
- package/src/compiler/internal/project/resolveProjectConfig.ts +24 -1
- package/src/compiler/internal/resolveBinary.ts +17 -1
- package/src/compiler/internal/resolveEmittedJavaScript.ts +43 -12
- package/src/compiler/internal/resolveTsgo.ts +29 -1
- package/src/compiler/internal/runBuild.ts +110 -55
- package/src/compiler/internal/runSingleFileEmit.ts +14 -1
- package/src/compiler/internal/sharedHostHelpers.ts +7 -7
- package/src/compiler/internal/spawnNative.ts +64 -0
- package/src/compiler/internal/transformProjectInMemory.ts +47 -67
- package/src/launcher/internal/getCompilerVersionText.ts +7 -0
- package/src/launcher/internal/prepareExecution.ts +32 -0
- package/src/launcher/internal/resolveCacheDir.ts +19 -0
- package/src/launcher/internal/resolveTtscserverBinary.ts +2 -0
- package/src/launcher/internal/runTtsc.ts +22 -10
- package/src/launcher/internal/runTtscserver.ts +9 -1
- package/src/launcher/internal/runTtsx.ts +33 -8
- package/src/plugin/internal/buildSourcePlugin.ts +40 -14
- package/src/plugin/internal/loadProjectPlugins.ts +42 -18
- package/src/structures/ITtscCompilerTransformation.ts +15 -2
- package/src/structures/ITtscPlugin.ts +0 -1
- package/src/structures/internal/TtscSingleFileEmitOptions.ts +0 -2
- package/tools/gen_shims/main.go +43 -8
- package/utility/host.go +294 -245
package/cmd/ttsc/build.go
CHANGED
|
@@ -8,15 +8,15 @@
|
|
|
8
8
|
package main
|
|
9
9
|
|
|
10
10
|
import (
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
"encoding/json"
|
|
12
|
+
"flag"
|
|
13
|
+
"fmt"
|
|
14
|
+
"os"
|
|
15
|
+
"path/filepath"
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
shimcompiler "github.com/microsoft/typescript-go/shim/compiler"
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
"github.com/samchon/ttsc/packages/ttsc/driver"
|
|
20
20
|
)
|
|
21
21
|
|
|
22
22
|
// runBuild implements the `ttsc` project-build lane. Two modes:
|
|
@@ -25,110 +25,113 @@ import (
|
|
|
25
25
|
// - --emit: also run tsgo's emit pipeline, patching every recognized native
|
|
26
26
|
// consumer call in the resulting .js files.
|
|
27
27
|
func runBuild(args []string) int {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
28
|
+
fs := flag.NewFlagSet("build", flag.ContinueOnError)
|
|
29
|
+
fs.SetOutput(stderr)
|
|
30
|
+
tsconfigPath := fs.String("tsconfig", "tsconfig.json", "path to tsconfig.json")
|
|
31
|
+
cwdOverride := fs.String("cwd", "", "override the working directory (defaults to process cwd)")
|
|
32
|
+
quiet := fs.Bool("quiet", true, "suppress the per-call diagnostic summary")
|
|
33
|
+
verbose := fs.Bool("verbose", false, "print the per-call diagnostic summary")
|
|
34
|
+
emit := fs.Bool("emit", false, "force emitted .js files (runs tsgo + ttsc rewrite)")
|
|
35
|
+
noEmit := fs.Bool("noEmit", false, "force analysis-only run with no file writes")
|
|
36
|
+
outDir := fs.String("outDir", "", "override compilerOptions.outDir for this build")
|
|
37
|
+
manifestPath := fs.String("manifest", "", "write emitted file list as JSON to this path")
|
|
38
|
+
if err := fs.Parse(args); err != nil {
|
|
39
|
+
return 2
|
|
40
|
+
}
|
|
41
|
+
if *emit && *noEmit {
|
|
42
|
+
fmt.Fprintln(stderr, "ttsc: --emit and --noEmit are mutually exclusive")
|
|
43
|
+
return 2
|
|
44
|
+
}
|
|
45
|
+
if *verbose {
|
|
46
|
+
*quiet = false
|
|
47
|
+
}
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
49
|
+
cwd := *cwdOverride
|
|
50
|
+
if cwd == "" {
|
|
51
|
+
var err error
|
|
52
|
+
cwd, err = getwd()
|
|
53
|
+
if err != nil {
|
|
54
|
+
fmt.Fprintf(stderr, "ttsc: could not get working directory: %v\n", err)
|
|
55
|
+
return 2
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
58
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
59
|
+
prog, diags, err := driver.LoadProgram(cwd, *tsconfigPath, driver.LoadProgramOptions{
|
|
60
|
+
ForceEmit: *emit,
|
|
61
|
+
ForceNoEmit: *noEmit,
|
|
62
|
+
OutDir: *outDir,
|
|
63
|
+
})
|
|
64
|
+
if err != nil {
|
|
65
|
+
fmt.Fprintf(stderr, "ttsc: %v\n", err)
|
|
66
|
+
return 2
|
|
67
|
+
}
|
|
68
|
+
if len(diags) > 0 {
|
|
69
|
+
driver.WritePrettyDiagnostics(stderr, diags, cwd)
|
|
70
|
+
return 2
|
|
71
|
+
}
|
|
72
|
+
defer prog.Close()
|
|
73
|
+
if diags := prog.Diagnostics(); len(diags) > 0 {
|
|
74
|
+
driver.WritePrettyDiagnostics(stderr, diags, cwd)
|
|
75
|
+
return 2
|
|
76
|
+
}
|
|
77
77
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
78
|
+
rewrites := driver.NewRewriteSet()
|
|
79
|
+
// shouldEmit reflects the resolved tsconfig noEmit flag. The flag lives
|
|
80
|
+
// three levels deep in the parsed config because TypeScript-Go mirrors the
|
|
81
|
+
// tsconfig object structure verbatim, with a tri-state bool per option.
|
|
82
|
+
shouldEmit := !prog.ParsedConfig.ParsedConfig.CompilerOptions.NoEmit.IsTrue()
|
|
83
|
+
if !*quiet {
|
|
84
|
+
fmt.Fprintf(stdout, "// ttsc: tsconfig=%s cwd=%s sites=%d emit=%v\n", *tsconfigPath, cwd, 0, shouldEmit)
|
|
85
|
+
}
|
|
83
86
|
|
|
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
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
87
|
+
if shouldEmit {
|
|
88
|
+
// Emit is callback-driven in TypeScript-Go. ttsc keeps that shape and
|
|
89
|
+
// wraps only the final WriteFile step so native rewrites and custom output
|
|
90
|
+
// capture share the same path.
|
|
91
|
+
writeFile := shimcompiler.WriteFile(
|
|
92
|
+
func(fileName, text string, _ *shimcompiler.WriteFileData) error {
|
|
93
|
+
return driver.DefaultWriteFile(fileName, text)
|
|
94
|
+
},
|
|
95
|
+
)
|
|
96
|
+
res, eDiags, err := prog.EmitAll(rewrites, writeFile)
|
|
97
|
+
if err != nil {
|
|
98
|
+
fmt.Fprintf(stderr, "ttsc: emit failed: %v\n", err)
|
|
99
|
+
return 3
|
|
100
|
+
}
|
|
101
|
+
for _, d := range eDiags {
|
|
102
|
+
fmt.Fprintln(stderr, " -", d.String())
|
|
103
|
+
}
|
|
104
|
+
if driver.CountErrors(eDiags) > 0 {
|
|
105
|
+
return 2
|
|
106
|
+
}
|
|
107
|
+
if !*quiet {
|
|
108
|
+
fmt.Fprintf(stdout, "// ttsc: emitted=%d files\n", len(res.EmittedFiles))
|
|
109
|
+
for _, f := range res.EmittedFiles {
|
|
110
|
+
rel := f
|
|
111
|
+
if abs, err := filepath.Rel(cwd, f); err == nil {
|
|
112
|
+
rel = abs
|
|
113
|
+
}
|
|
114
|
+
fmt.Fprintln(stdout, " +", rel)
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
if *manifestPath != "" {
|
|
118
|
+
// The manifest is intentionally just the emitted file list. Higher
|
|
119
|
+
// layers already know the project and tsconfig, and tests compare this
|
|
120
|
+
// array as the build contract.
|
|
121
|
+
data, _ := json.Marshal(res.EmittedFiles)
|
|
122
|
+
if err := os.MkdirAll(filepath.Dir(*manifestPath), 0o755); err != nil {
|
|
123
|
+
fmt.Fprintf(stderr, "ttsc: manifest mkdir failed: %v\n", err)
|
|
124
|
+
return 3
|
|
125
|
+
}
|
|
126
|
+
if err := os.WriteFile(*manifestPath, data, 0o644); err != nil {
|
|
127
|
+
fmt.Fprintf(stderr, "ttsc: manifest write failed: %v\n", err)
|
|
128
|
+
return 3
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
129
132
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
133
|
+
if !*quiet {
|
|
134
|
+
fmt.Fprintf(stdout, "// ttsc: recognized=%d total=%d rewrites=%d\n", 0, 0, rewrites.Len())
|
|
135
|
+
}
|
|
136
|
+
return 0
|
|
134
137
|
}
|
|
@@ -1,130 +1,128 @@
|
|
|
1
1
|
package main
|
|
2
2
|
|
|
3
3
|
import (
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
"errors"
|
|
5
|
+
"path/filepath"
|
|
6
|
+
"strings"
|
|
7
|
+
"testing"
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
"github.com/samchon/ttsc/packages/ttsc/driver"
|
|
10
10
|
)
|
|
11
11
|
|
|
12
12
|
type buildApplyErrorPlugin struct{}
|
|
13
13
|
|
|
14
14
|
func (buildApplyErrorPlugin) ApplyProgram(*driver.Program, driver.PluginContext) error {
|
|
15
|
-
|
|
15
|
+
return errors.New("build apply boom")
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
* 3. Force manifest mkdir and write failures after a valid emit.
|
|
28
|
-
*/
|
|
18
|
+
// TestBuildBranches verifies build command branches report setup, emit, and manifest failures.
|
|
19
|
+
//
|
|
20
|
+
// The native build command is the fallback compiler host behind ttsc. It must
|
|
21
|
+
// fail before writing partial output when flags, cwd, tsconfig, disk emit, or
|
|
22
|
+
// manifest paths are invalid.
|
|
23
|
+
//
|
|
24
|
+
// 1. Exercise bad flags, cwd failure, and project-load failures.
|
|
25
|
+
// 2. Force emit through an invalid outDir.
|
|
26
|
+
// 3. Force manifest mkdir and write failures after a valid emit.
|
|
29
27
|
func TestBuildBranches(t *testing.T) {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
28
|
+
code, _, _ := captureCommand(t, func() int {
|
|
29
|
+
return runBuild([]string{"--cwd"})
|
|
30
|
+
})
|
|
31
|
+
if code != 2 {
|
|
32
|
+
t.Fatalf("bad flag status mismatch: %d", code)
|
|
33
|
+
}
|
|
34
|
+
code, _, errText := captureCommand(t, func() int {
|
|
35
|
+
getwd = failGetwd
|
|
36
|
+
return runBuild(nil)
|
|
37
|
+
})
|
|
38
|
+
if code != 2 || !strings.Contains(errText, "cwd boom") {
|
|
39
|
+
t.Fatalf("cwd error mismatch: code=%d stderr=%q", code, errText)
|
|
40
|
+
}
|
|
41
|
+
root := t.TempDir()
|
|
42
|
+
code, _, errText = captureCommand(t, func() int {
|
|
43
|
+
return runBuild([]string{"--cwd", root, "--tsconfig", "missing.json"})
|
|
44
|
+
})
|
|
45
|
+
if code != 2 || !strings.Contains(errText, "tsconfig not found") {
|
|
46
|
+
t.Fatalf("missing config mismatch: code=%d stderr=%q", code, errText)
|
|
47
|
+
}
|
|
50
48
|
|
|
51
|
-
|
|
49
|
+
writeCommandProjectFile(t, root, "tsconfig.json", `{
|
|
52
50
|
"compilerOptions": { "module": "commonjs", "target": "es2020", "strict": true },
|
|
53
51
|
"files": ["index.ts"]
|
|
54
52
|
}
|
|
55
53
|
`)
|
|
56
|
-
|
|
54
|
+
writeCommandProjectFile(t, root, "index.ts", `const value: number = "text";
|
|
57
55
|
export { value };
|
|
58
56
|
`)
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
57
|
+
code, _, errText = captureCommand(t, func() int {
|
|
58
|
+
return runBuild([]string{"--cwd", root, "--tsconfig", "tsconfig.json"})
|
|
59
|
+
})
|
|
60
|
+
if code != 2 || !strings.Contains(errText, "number") {
|
|
61
|
+
t.Fatalf("semantic diagnostics mismatch: code=%d stderr=%q", code, errText)
|
|
62
|
+
}
|
|
65
63
|
|
|
66
|
-
|
|
64
|
+
writeCommandProjectFile(t, root, "tsconfig.json", `{
|
|
67
65
|
"compilerOptions": { "module": "not-a-module-kind", "target": "es2020" },
|
|
68
66
|
"files": ["index.ts"]
|
|
69
67
|
}
|
|
70
68
|
`)
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
69
|
+
code, _, errText = captureCommand(t, func() int {
|
|
70
|
+
return runBuild([]string{"--cwd", root, "--tsconfig", "tsconfig.json"})
|
|
71
|
+
})
|
|
72
|
+
if code != 2 || !strings.Contains(errText, "not-a-module-kind") {
|
|
73
|
+
t.Fatalf("invalid config mismatch: code=%d stderr=%q", code, errText)
|
|
74
|
+
}
|
|
77
75
|
|
|
78
|
-
|
|
76
|
+
writeCommandProjectFile(t, root, "tsconfig.json", `{
|
|
79
77
|
"compilerOptions": { "module": "commonjs", "target": "es2020", "strict": true },
|
|
80
78
|
"files": ["index.ts"]
|
|
81
79
|
}
|
|
82
80
|
`)
|
|
83
|
-
|
|
81
|
+
writeCommandProjectFile(t, root, "index.ts", `export const value = 1;
|
|
84
82
|
`)
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
83
|
+
writeCommandProjectFile(t, root, "blocked", `not a directory`)
|
|
84
|
+
code, _, errText = captureCommand(t, func() int {
|
|
85
|
+
return runBuild([]string{"--cwd", root, "--tsconfig", "tsconfig.json", "--emit", "--outDir", "blocked"})
|
|
86
|
+
})
|
|
87
|
+
if code != 2 || !strings.Contains(errText, "not a directory") {
|
|
88
|
+
t.Fatalf("emit failure mismatch: code=%d stderr=%q", code, errText)
|
|
89
|
+
}
|
|
92
90
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
91
|
+
resetCommandLinkedPluginRegistry()
|
|
92
|
+
driver.RegisterPlugin(buildApplyErrorPlugin{})
|
|
93
|
+
t.Cleanup(resetCommandLinkedPluginRegistry)
|
|
94
|
+
t.Setenv(driver.LinkedPluginsEnv, `[{"name":"error","stage":"transform","config":{}}]`)
|
|
95
|
+
code, _, errText = captureCommand(t, func() int {
|
|
96
|
+
return runBuild([]string{"--cwd", root, "--tsconfig", "tsconfig.json", "--emit", "--outDir", "dist"})
|
|
97
|
+
})
|
|
98
|
+
if code != 3 || !strings.Contains(errText, "build apply boom") {
|
|
99
|
+
t.Fatalf("linked apply failure mismatch: code=%d stderr=%q", code, errText)
|
|
100
|
+
}
|
|
101
|
+
resetCommandLinkedPluginRegistry()
|
|
102
|
+
t.Setenv(driver.LinkedPluginsEnv, "")
|
|
105
103
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
104
|
+
code, _, errText = captureCommand(t, func() int {
|
|
105
|
+
return runBuild([]string{
|
|
106
|
+
"--cwd", root,
|
|
107
|
+
"--tsconfig", "tsconfig.json",
|
|
108
|
+
"--emit",
|
|
109
|
+
"--outDir", "dist",
|
|
110
|
+
"--manifest", filepath.Join(root, "index.ts", "manifest.json"),
|
|
111
|
+
})
|
|
112
|
+
})
|
|
113
|
+
if code != 3 || !strings.Contains(errText, "manifest mkdir failed") {
|
|
114
|
+
t.Fatalf("manifest mkdir mismatch: code=%d stderr=%q", code, errText)
|
|
115
|
+
}
|
|
116
|
+
code, _, errText = captureCommand(t, func() int {
|
|
117
|
+
return runBuild([]string{
|
|
118
|
+
"--cwd", root,
|
|
119
|
+
"--tsconfig", "tsconfig.json",
|
|
120
|
+
"--emit",
|
|
121
|
+
"--outDir", "dist",
|
|
122
|
+
"--manifest", root,
|
|
123
|
+
})
|
|
124
|
+
})
|
|
125
|
+
if code != 3 || !strings.Contains(errText, "manifest write failed") {
|
|
126
|
+
t.Fatalf("manifest write mismatch: code=%d stderr=%q", code, errText)
|
|
127
|
+
}
|
|
130
128
|
}
|
package/cmd/ttsc/helpers_test.go
CHANGED
|
@@ -1,47 +1,58 @@
|
|
|
1
1
|
package main
|
|
2
2
|
|
|
3
3
|
import (
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
"bytes"
|
|
5
|
+
"errors"
|
|
6
|
+
"os"
|
|
7
|
+
"path/filepath"
|
|
8
|
+
"testing"
|
|
9
|
+
_ "unsafe"
|
|
10
10
|
)
|
|
11
11
|
|
|
12
|
+
// driverPluginRegistry is a linkname alias for the unexported plugin slice in
|
|
13
|
+
// the driver package, allowing tests to reset registered plugins between cases.
|
|
14
|
+
//
|
|
12
15
|
//go:linkname driverPluginRegistry github.com/samchon/ttsc/packages/ttsc/driver.pluginRegistry
|
|
13
16
|
var driverPluginRegistry []any
|
|
14
17
|
|
|
18
|
+
// captureCommand redirects the package-level stdout/stderr/getwd seams around
|
|
19
|
+
// fn, then returns the exit code and the captured output strings.
|
|
15
20
|
func captureCommand(t *testing.T, fn func() int) (int, string, string) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
21
|
+
t.Helper()
|
|
22
|
+
prevOut, prevErr, prevGetwd := stdout, stderr, getwd
|
|
23
|
+
var out, err bytes.Buffer
|
|
24
|
+
stdout = &out
|
|
25
|
+
stderr = &err
|
|
26
|
+
defer func() {
|
|
27
|
+
stdout = prevOut
|
|
28
|
+
stderr = prevErr
|
|
29
|
+
getwd = prevGetwd
|
|
30
|
+
}()
|
|
31
|
+
code := fn()
|
|
32
|
+
return code, out.String(), err.String()
|
|
28
33
|
}
|
|
29
34
|
|
|
35
|
+
// failGetwd is a getwd stub that always returns an error, used to exercise the
|
|
36
|
+
// cwd-resolution failure path in command entrypoints.
|
|
30
37
|
func failGetwd() (string, error) {
|
|
31
|
-
|
|
38
|
+
return "", errors.New("cwd boom")
|
|
32
39
|
}
|
|
33
40
|
|
|
41
|
+
// writeCommandProjectFile writes contents to root/name, creating intermediate
|
|
42
|
+
// directories as needed. Slashes in name are normalised to the OS separator.
|
|
34
43
|
func writeCommandProjectFile(t *testing.T, root, name, contents string) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
44
|
+
t.Helper()
|
|
45
|
+
file := filepath.Join(root, filepath.FromSlash(name))
|
|
46
|
+
if err := os.MkdirAll(filepath.Dir(file), 0o755); err != nil {
|
|
47
|
+
t.Fatal(err)
|
|
48
|
+
}
|
|
49
|
+
if err := os.WriteFile(file, []byte(contents), 0o644); err != nil {
|
|
50
|
+
t.Fatal(err)
|
|
51
|
+
}
|
|
43
52
|
}
|
|
44
53
|
|
|
54
|
+
// resetCommandLinkedPluginRegistry clears the driver plugin registry so that
|
|
55
|
+
// tests that register plugins do not pollute subsequent test cases.
|
|
45
56
|
func resetCommandLinkedPluginRegistry() {
|
|
46
|
-
|
|
57
|
+
driverPluginRegistry = nil
|
|
47
58
|
}
|