goscript 0.2.4 → 0.2.5

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.
Files changed (117) hide show
  1. package/README.md +8 -8
  2. package/cmd/go_js_wasm_exec/main.go +1 -1
  3. package/cmd/go_js_wasm_exec/main_test.go +1 -1
  4. package/cmd/goscript/cmd-compile.go +9 -1
  5. package/cmd/goscript/cmd-test.go +1 -1
  6. package/cmd/goscript/cmd_compile_test.go +44 -0
  7. package/cmd/goscript/deps.go +1 -1
  8. package/cmd/goscript-wasm/main.go +2 -2
  9. package/compiler/compile-request.go +19 -0
  10. package/compiler/compile_bench_test.go +121 -0
  11. package/compiler/compliance_test.go +17 -1
  12. package/compiler/config.go +2 -0
  13. package/compiler/gotest/result.go +1 -1
  14. package/compiler/gotest/runner.go +2 -2
  15. package/compiler/gotest/runner_test.go +4 -7
  16. package/compiler/index.test.ts +28 -0
  17. package/compiler/index.ts +32 -16
  18. package/compiler/lowering.go +1238 -194
  19. package/compiler/lowering_bench_test.go +4 -0
  20. package/compiler/override-facts.go +1 -1
  21. package/compiler/package-graph.go +92 -0
  22. package/compiler/package-graph_test.go +113 -0
  23. package/compiler/runtime-contract.go +1 -1
  24. package/compiler/semantic-model.go +32 -0
  25. package/compiler/skeleton_test.go +241 -15
  26. package/compiler/wasm/compile.go +1 -1
  27. package/compiler/wasm/compile_test.go +1 -1
  28. package/dist/compiler/index.d.ts +4 -0
  29. package/dist/compiler/index.js +26 -15
  30. package/dist/compiler/index.js.map +1 -1
  31. package/dist/gs/database/sql/driver/index.d.ts +165 -0
  32. package/dist/gs/database/sql/driver/index.js +432 -0
  33. package/dist/gs/database/sql/driver/index.js.map +1 -0
  34. package/dist/gs/encoding/binary/index.d.ts +71 -0
  35. package/dist/gs/encoding/binary/index.js +778 -0
  36. package/dist/gs/encoding/binary/index.js.map +1 -0
  37. package/dist/gs/fmt/fmt.js +156 -57
  38. package/dist/gs/fmt/fmt.js.map +1 -1
  39. package/dist/gs/github.com/klauspost/cpuid/v2/index.d.ts +11 -0
  40. package/dist/gs/github.com/klauspost/cpuid/v2/index.js +28 -0
  41. package/dist/gs/github.com/klauspost/cpuid/v2/index.js.map +1 -0
  42. package/dist/gs/github.com/pkg/errors/errors.d.ts +0 -2
  43. package/dist/gs/github.com/pkg/errors/errors.js.map +1 -1
  44. package/dist/gs/github.com/pkg/errors/index.d.ts +2 -1
  45. package/dist/gs/github.com/pkg/errors/index.js +1 -1
  46. package/dist/gs/github.com/pkg/errors/index.js.map +1 -1
  47. package/dist/gs/github.com/pkg/errors/stack.d.ts +8 -19
  48. package/dist/gs/github.com/pkg/errors/stack.js +26 -61
  49. package/dist/gs/github.com/pkg/errors/stack.js.map +1 -1
  50. package/dist/gs/golang.org/x/crypto/cryptobyte/asn1/index.d.ts +19 -0
  51. package/dist/gs/golang.org/x/crypto/cryptobyte/asn1/index.js +25 -0
  52. package/dist/gs/golang.org/x/crypto/cryptobyte/asn1/index.js.map +1 -0
  53. package/dist/gs/golang.org/x/crypto/cryptobyte/index.d.ts +104 -0
  54. package/dist/gs/golang.org/x/crypto/cryptobyte/index.js +1107 -0
  55. package/dist/gs/golang.org/x/crypto/cryptobyte/index.js.map +1 -0
  56. package/dist/gs/golang.org/x/crypto/internal/alias/index.d.ts +3 -0
  57. package/dist/gs/golang.org/x/crypto/internal/alias/index.js +39 -0
  58. package/dist/gs/golang.org/x/crypto/internal/alias/index.js.map +1 -0
  59. package/dist/gs/runtime/runtime.d.ts +6 -1
  60. package/dist/gs/runtime/runtime.js +15 -8
  61. package/dist/gs/runtime/runtime.js.map +1 -1
  62. package/dist/gs/runtime/trace/index.d.ts +8 -5
  63. package/dist/gs/runtime/trace/index.js +324 -23
  64. package/dist/gs/runtime/trace/index.js.map +1 -1
  65. package/dist/gs/slices/slices.d.ts +2 -1
  66. package/dist/gs/slices/slices.js +9 -3
  67. package/dist/gs/slices/slices.js.map +1 -1
  68. package/dist/gs/sort/search.gs.d.ts +3 -1
  69. package/dist/gs/sort/search.gs.js +18 -53
  70. package/dist/gs/sort/search.gs.js.map +1 -1
  71. package/dist/gs/sync/sync.d.ts +1 -1
  72. package/dist/gs/sync/sync.js +3 -0
  73. package/dist/gs/sync/sync.js.map +1 -1
  74. package/dist/gs/time/time.d.ts +22 -29
  75. package/dist/gs/time/time.js +111 -32
  76. package/dist/gs/time/time.js.map +1 -1
  77. package/dist/gs/unsafe/unsafe.d.ts +3 -2
  78. package/dist/gs/unsafe/unsafe.js.map +1 -1
  79. package/go.mod +7 -5
  80. package/go.sum +12 -26
  81. package/gs/database/sql/driver/index.test.ts +88 -0
  82. package/gs/database/sql/driver/index.ts +675 -0
  83. package/gs/database/sql/driver/meta.json +3 -0
  84. package/gs/database/sql/driver/parity.json +144 -0
  85. package/gs/encoding/binary/index.test.ts +239 -0
  86. package/gs/encoding/binary/index.ts +999 -0
  87. package/gs/encoding/binary/meta.json +9 -0
  88. package/gs/encoding/binary/parity.json +72 -0
  89. package/gs/fmt/fmt.test.ts +28 -0
  90. package/gs/fmt/fmt.ts +198 -61
  91. package/gs/fmt/meta.json +2 -1
  92. package/gs/github.com/klauspost/cpuid/v2/index.ts +38 -0
  93. package/gs/github.com/klauspost/cpuid/v2/meta.json +3 -0
  94. package/gs/github.com/pkg/errors/errors.ts +1 -2
  95. package/gs/github.com/pkg/errors/index.ts +2 -1
  96. package/gs/github.com/pkg/errors/stack.ts +34 -62
  97. package/gs/golang.org/x/crypto/cryptobyte/asn1/index.test.ts +19 -0
  98. package/gs/golang.org/x/crypto/cryptobyte/asn1/index.ts +29 -0
  99. package/gs/golang.org/x/crypto/cryptobyte/index.test.ts +255 -0
  100. package/gs/golang.org/x/crypto/cryptobyte/index.ts +1441 -0
  101. package/gs/golang.org/x/crypto/cryptobyte/meta.json +3 -0
  102. package/gs/golang.org/x/crypto/internal/alias/index.test.ts +40 -0
  103. package/gs/golang.org/x/crypto/internal/alias/index.ts +40 -0
  104. package/gs/runtime/runtime.test.ts +16 -0
  105. package/gs/runtime/runtime.ts +17 -9
  106. package/gs/runtime/trace/index.test.ts +113 -14
  107. package/gs/runtime/trace/index.ts +384 -34
  108. package/gs/runtime/trace/meta.json +1 -0
  109. package/gs/slices/slices.test.ts +24 -1
  110. package/gs/slices/slices.ts +14 -4
  111. package/gs/sort/meta.json +1 -0
  112. package/gs/sort/search.gs.ts +20 -5
  113. package/gs/sync/sync.ts +4 -1
  114. package/gs/time/time.test.ts +79 -2
  115. package/gs/time/time.ts +133 -33
  116. package/gs/unsafe/unsafe.ts +4 -2
  117. package/package.json +2 -2
package/README.md CHANGED
@@ -9,13 +9,13 @@
9
9
  </p>
10
10
 
11
11
  <p>
12
- <a href="https://godoc.org/github.com/aperturerobotics/goscript">
13
- <img src="https://godoc.org/github.com/aperturerobotics/goscript?status.svg" alt="GoDoc" />
12
+ <a href="https://godoc.org/github.com/s4wave/goscript">
13
+ <img src="https://godoc.org/github.com/s4wave/goscript?status.svg" alt="GoDoc" />
14
14
  </a>
15
- <a href="https://goreportcard.com/report/github.com/aperturerobotics/goscript">
16
- <img src="https://goreportcard.com/badge/github.com/aperturerobotics/goscript" alt="Go Report Card" />
15
+ <a href="https://goreportcard.com/report/github.com/s4wave/goscript">
16
+ <img src="https://goreportcard.com/badge/github.com/s4wave/goscript" alt="Go Report Card" />
17
17
  </a>
18
- <a href="https://deepwiki.com/aperturerobotics/goscript">
18
+ <a href="https://deepwiki.com/s4wave/goscript">
19
19
  <img src="https://deepwiki.com/badge.svg" alt="Ask DeepWiki" />
20
20
  </a>
21
21
  </p>
@@ -120,7 +120,7 @@ curl -fsSL https://bun.sh/install | bash
120
120
  Install the CLI:
121
121
 
122
122
  ```bash
123
- go install github.com/aperturerobotics/goscript/cmd/goscript@latest
123
+ go install github.com/s4wave/goscript/cmd/goscript@latest
124
124
  ```
125
125
 
126
126
  Compile a Go package from a module directory:
@@ -231,7 +231,7 @@ package main
231
231
  import (
232
232
  "context"
233
233
 
234
- "github.com/aperturerobotics/goscript/compiler"
234
+ "github.com/s4wave/goscript/compiler"
235
235
  )
236
236
 
237
237
  func main() {
@@ -265,7 +265,7 @@ WASM adapter package:
265
265
  ```go
266
266
  package main
267
267
 
268
- import "github.com/aperturerobotics/goscript/compiler/wasm"
268
+ import "github.com/s4wave/goscript/compiler/wasm"
269
269
 
270
270
  func main() {
271
271
  ts, err := wasm.CompileSource(`
@@ -9,8 +9,8 @@ import (
9
9
  "strings"
10
10
  "time"
11
11
 
12
- "github.com/aperturerobotics/goscript/compiler/gotest"
13
12
  "github.com/pkg/errors"
13
+ "github.com/s4wave/goscript/compiler/gotest"
14
14
  )
15
15
 
16
16
  func main() {
@@ -6,7 +6,7 @@ import (
6
6
  "testing"
7
7
  "time"
8
8
 
9
- "github.com/aperturerobotics/goscript/compiler/gotest"
9
+ "github.com/s4wave/goscript/compiler/gotest"
10
10
  )
11
11
 
12
12
  func TestRequestFromGoToolArgsMapsSupportedFlags(t *testing.T) {
@@ -5,8 +5,8 @@ import (
5
5
  "slices"
6
6
 
7
7
  "github.com/aperturerobotics/cli"
8
- "github.com/aperturerobotics/goscript/compiler"
9
8
  "github.com/pkg/errors"
9
+ "github.com/s4wave/goscript/compiler"
10
10
  "github.com/sirupsen/logrus"
11
11
  )
12
12
 
@@ -19,6 +19,7 @@ func newCompileCommand() *cli.Command {
19
19
  var packages cli.StringSlice
20
20
  var buildFlags rawStringSlice
21
21
  var overrideDirs cli.StringSlice
22
+ var packageBlocklist cli.StringSlice
22
23
 
23
24
  return &cli.Command{
24
25
  Name: "compile",
@@ -27,6 +28,7 @@ func newCompileCommand() *cli.Command {
27
28
  Action: func(c *cli.Context) error {
28
29
  config.BuildFlags = buildFlags.Value()
29
30
  config.OverrideDirs = slices.Clone(overrideDirs.Value())
31
+ config.PackageBlocklist = slices.Clone(packageBlocklist.Value())
30
32
  return compilePackage(c.Context, &config, packages.Value())
31
33
  },
32
34
  Flags: []cli.Flag{
@@ -65,6 +67,12 @@ func newCompileCommand() *cli.Command {
65
67
  Destination: &overrideDirs,
66
68
  EnvVars: []string{"GOSCRIPT_GS_PATH"},
67
69
  },
70
+ &cli.StringSliceFlag{
71
+ Name: "package-blocklist",
72
+ Usage: "comma-separated Go import paths to reject from the compiled package graph",
73
+ Destination: &packageBlocklist,
74
+ EnvVars: []string{"GOSCRIPT_PACKAGE_BLOCKLIST"},
75
+ },
68
76
  &cli.BoolFlag{
69
77
  Name: "disable-emit-builtin",
70
78
  Usage: "disable emitting built-in packages that have handwritten equivalents",
@@ -11,8 +11,8 @@ import (
11
11
  "time"
12
12
 
13
13
  "github.com/aperturerobotics/cli"
14
- "github.com/aperturerobotics/goscript/compiler/gotest"
15
14
  "github.com/pkg/errors"
15
+ "github.com/s4wave/goscript/compiler/gotest"
16
16
  )
17
17
 
18
18
  func testCommands() []*cli.Command {
@@ -170,8 +170,52 @@ func TestCompileCommandPreservesCommaSeparatedBuildFlagEnvValue(t *testing.T) {
170
170
  }
171
171
  }
172
172
 
173
+ func TestCompileCommandForwardsPackageBlocklist(t *testing.T) {
174
+ dir := t.TempDir()
175
+ outputDir := filepath.Join(dir, "output")
176
+ writeFile(t, filepath.Join(dir, "go.mod"), "module example.test/cli\n\ngo 1.25.3\n")
177
+ writeFile(t, filepath.Join(dir, "main.go"), strings.Join([]string{
178
+ "package cli",
179
+ `import "example.test/cli/dep"`,
180
+ "func Selected() int { return dep.Value() }",
181
+ "",
182
+ }, "\n"))
183
+ writeFile(t, filepath.Join(dir, "dep", "dep.go"), strings.Join([]string{
184
+ "package dep",
185
+ "func Value() int { return 1 }",
186
+ "",
187
+ }, "\n"))
188
+
189
+ app := newApp()
190
+ err := app.Run([]string{
191
+ "goscript",
192
+ "compile",
193
+ "--package",
194
+ ".",
195
+ "--output",
196
+ outputDir,
197
+ "--dir",
198
+ dir,
199
+ "--all-dependencies",
200
+ "--package-blocklist=example.test/cli/dep,example.test/unused",
201
+ })
202
+ if err == nil {
203
+ t.Fatal("expected package blocklist error")
204
+ }
205
+ text := err.Error()
206
+ if !strings.Contains(text, "goscript/package-graph:blocklisted-package") {
207
+ t.Fatalf("expected blocklist diagnostic, got %q", text)
208
+ }
209
+ if !strings.Contains(text, "example.test/cli -> example.test/cli/dep") {
210
+ t.Fatalf("expected CLI diagnostic to include import chain, got %q", text)
211
+ }
212
+ }
213
+
173
214
  func writeFile(t *testing.T, path string, content string) {
174
215
  t.Helper()
216
+ if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
217
+ t.Fatalf("create parent for %s: %v", path, err)
218
+ }
175
219
  if err := os.WriteFile(path, []byte(content), 0o644); err != nil {
176
220
  t.Fatalf("write %s: %v", path, err)
177
221
  }
@@ -4,5 +4,5 @@ package main
4
4
 
5
5
  import (
6
6
  // _ ensure we include the root package
7
- _ "github.com/aperturerobotics/goscript"
7
+ _ "github.com/s4wave/goscript"
8
8
  )
@@ -6,8 +6,8 @@ import (
6
6
  "errors"
7
7
  "syscall/js"
8
8
 
9
- "github.com/aperturerobotics/goscript/compiler"
10
- "github.com/aperturerobotics/goscript/compiler/wasm"
9
+ "github.com/s4wave/goscript/compiler"
10
+ "github.com/s4wave/goscript/compiler/wasm"
11
11
  )
12
12
 
13
13
  func main() {
@@ -38,6 +38,8 @@ type CompileRequest struct {
38
38
  BuildFlags []string
39
39
  // OverrideDirs are additional GoScript override roots.
40
40
  OverrideDirs []string
41
+ // PackageBlocklist rejects package paths in the loaded dependency closure.
42
+ PackageBlocklist []string
41
43
  // DependencyMode controls whether dependencies are included in the graph.
42
44
  DependencyMode DependencyMode
43
45
  // RuntimeEmissionMode controls runtime package emission policy.
@@ -82,6 +84,7 @@ func (o *CompileRequestOwner) NewRequest(conf Config, patterns []string) *Compil
82
84
  OutputPath: strings.TrimSpace(conf.OutputPath),
83
85
  BuildFlags: append([]string(nil), conf.BuildFlags...),
84
86
  OverrideDirs: append([]string(nil), conf.OverrideDirs...),
87
+ PackageBlocklist: normalizePackageBlocklist(conf.PackageBlocklist),
85
88
  DependencyMode: dependencyMode,
86
89
  RuntimeEmissionMode: runtimeEmissionMode,
87
90
  ProtobufTypeScriptBinding: conf.ProtobufTypeScriptBinding,
@@ -235,6 +238,22 @@ func normalizePatterns(patterns []string) []string {
235
238
  return normalized
236
239
  }
237
240
 
241
+ func normalizePackageBlocklist(paths []string) []string {
242
+ var normalized []string
243
+ seen := make(map[string]bool)
244
+ for _, path := range paths {
245
+ for part := range strings.SplitSeq(path, ",") {
246
+ part = strings.TrimSpace(part)
247
+ if part == "" || seen[part] {
248
+ continue
249
+ }
250
+ seen[part] = true
251
+ normalized = append(normalized, part)
252
+ }
253
+ }
254
+ return normalized
255
+ }
256
+
238
257
  func hasGoMod(dir string) bool {
239
258
  abs, err := filepath.Abs(dir)
240
259
  if err != nil {
@@ -0,0 +1,121 @@
1
+ package compiler
2
+
3
+ import (
4
+ "context"
5
+ "os"
6
+ "path/filepath"
7
+ "testing"
8
+ "time"
9
+ )
10
+
11
+ // benchDependencyPatterns is a representative existing GoScript dependency
12
+ // package graph: real util packages whose closure pulls in generics, channels,
13
+ // sync primitives, and context wiring, so the per-stage attribution reflects a
14
+ // realistic compile rather than a toy fixture.
15
+ var benchDependencyPatterns = []string{
16
+ "github.com/aperturerobotics/util/broadcast",
17
+ "github.com/aperturerobotics/util/keyed",
18
+ "github.com/aperturerobotics/util/ccontainer",
19
+ "github.com/aperturerobotics/util/refcount",
20
+ "github.com/aperturerobotics/util/routine",
21
+ }
22
+
23
+ // BenchmarkCompilePipelineStages runs the full CompileService pipeline over a
24
+ // representative existing dependency package graph and attributes wall time to
25
+ // each stage owner: package-graph load, semantic-model build, lowering, and
26
+ // TypeScript emit. It reports per-stage milliseconds-per-op metrics so a single
27
+ // run names the dominant compile-time stage. Service construction (which builds
28
+ // the runtime contract owner) is measured once as serviceinit-ms because the
29
+ // runtime contract is static setup, not a per-package stage. Emit is measured
30
+ // via EmitToMemory to isolate code-generation cost from output disk writes.
31
+ func BenchmarkCompilePipelineStages(b *testing.B) {
32
+ moduleRoot := benchModuleRoot(b)
33
+ outputPath := b.TempDir()
34
+ req := &CompileRequest{
35
+ Dir: moduleRoot,
36
+ OutputPath: outputPath,
37
+ Patterns: benchDependencyPatterns,
38
+ DependencyMode: DependencyModeAll,
39
+ }
40
+
41
+ // Resolve the dependency graph once outside the timer to confirm the
42
+ // patterns load cleanly and fail fast before measuring.
43
+ if _, diagnostics := NewCompileService().PackageGraphOwner().Load(context.Background(), req); diagnosticsHaveErrors(diagnostics) {
44
+ b.Fatalf("load representative dependency graph: %v", diagnostics)
45
+ }
46
+
47
+ var serviceInit, graphLoad, semantic, lowering, emit time.Duration
48
+ loweringOpts := LoweringOptions{
49
+ SourceRoot: protobufTypeScriptBindingRoot(req.Dir),
50
+ DisplayRoot: req.Dir,
51
+ OutputPath: req.OutputPath,
52
+ }
53
+
54
+ b.ReportAllocs()
55
+ b.ResetTimer()
56
+ for i := 0; i < b.N; i++ {
57
+ start := time.Now()
58
+ service := NewCompileService()
59
+ serviceInit += time.Since(start)
60
+
61
+ start = time.Now()
62
+ graph, graphDiagnostics := service.PackageGraphOwner().Load(context.Background(), req)
63
+ graphLoad += time.Since(start)
64
+ if diagnosticsHaveErrors(graphDiagnostics) {
65
+ b.Fatalf("graph load: %v", graphDiagnostics)
66
+ }
67
+
68
+ start = time.Now()
69
+ model, semanticDiagnostics := service.SemanticModelOwner().Build(context.Background(), graph)
70
+ semantic += time.Since(start)
71
+ if diagnosticsHaveErrors(semanticDiagnostics) {
72
+ b.Fatalf("semantic build: %v", semanticDiagnostics)
73
+ }
74
+
75
+ start = time.Now()
76
+ program, loweringDiagnostics := service.LoweringOwner().Build(context.Background(), model, loweringOpts)
77
+ lowering += time.Since(start)
78
+ if diagnosticsHaveErrors(loweringDiagnostics) {
79
+ b.Fatalf("lowering: %v", loweringDiagnostics)
80
+ }
81
+
82
+ start = time.Now()
83
+ _, emitDiagnostics := service.TypeScriptEmitOwner().EmitToMemory(context.Background(), program)
84
+ emit += time.Since(start)
85
+ if diagnosticsHaveErrors(emitDiagnostics) {
86
+ b.Fatalf("emit: %v", emitDiagnostics)
87
+ }
88
+ }
89
+ b.StopTimer()
90
+
91
+ perOpMs := func(total time.Duration) float64 {
92
+ return float64(total.Nanoseconds()) / float64(b.N) / 1e6
93
+ }
94
+ b.ReportMetric(perOpMs(serviceInit), "serviceinit-ms/op")
95
+ b.ReportMetric(perOpMs(graphLoad), "graphload-ms/op")
96
+ b.ReportMetric(perOpMs(semantic), "semantic-ms/op")
97
+ b.ReportMetric(perOpMs(lowering), "lowering-ms/op")
98
+ b.ReportMetric(perOpMs(emit), "emit-ms/op")
99
+ }
100
+
101
+ // benchModuleRoot walks up from the test working directory to the module root
102
+ // that owns go.mod, so the bench loads util packages in the GoScript module's
103
+ // own dependency context (resolved go.sum and module cache) rather than a
104
+ // synthetic temp module.
105
+ func benchModuleRoot(tb testing.TB) string {
106
+ tb.Helper()
107
+ dir, err := os.Getwd()
108
+ if err != nil {
109
+ tb.Fatalf("getwd: %v", err)
110
+ }
111
+ for {
112
+ if _, err := os.Stat(filepath.Join(dir, "go.mod")); err == nil {
113
+ return dir
114
+ }
115
+ parent := filepath.Dir(dir)
116
+ if parent == dir {
117
+ tb.Fatal("module root with go.mod not found above test working directory")
118
+ }
119
+ dir = parent
120
+ }
121
+ }
@@ -7,7 +7,7 @@ import (
7
7
  "strings"
8
8
  "testing"
9
9
 
10
- "github.com/aperturerobotics/goscript/tests"
10
+ "github.com/s4wave/goscript/tests"
11
11
  )
12
12
 
13
13
  // TestCompliance runs the inherited GoScript compliance fixtures through the
@@ -59,6 +59,9 @@ func TestCompliance(t *testing.T) {
59
59
  if expectedV2ComplianceGaps[name] {
60
60
  t.Skip("expected v2 compliance gap")
61
61
  }
62
+ if complianceHarnessExcluded[name] {
63
+ t.Skip("validated by a dedicated oracle test, not stdout comparison")
64
+ }
62
65
 
63
66
  ranTests++
64
67
  tests.RunGoScriptTestDir(t, workspaceDir, testPath)
@@ -120,6 +123,19 @@ func complianceCategory(name string) string {
120
123
  }
121
124
  }
122
125
 
126
+ // complianceHarnessExcluded lists fixture directories that the shared stdout
127
+ // comparison harness must skip because a dedicated test validates them another
128
+ // way. runtime_trace_proof, runtime_trace_empty, and runtime_trace_multibatch
129
+ // emit Go execution-trace bytes whose GoScript subset is intentionally not
130
+ // byte-identical to the native runtime trace, so TestRuntimeTraceProof,
131
+ // TestRuntimeTraceEmptyCapture, and TestRuntimeTraceMultiBatch validate them
132
+ // through the upstream Go trace reader.
133
+ var complianceHarnessExcluded = map[string]bool{
134
+ "runtime_trace_proof": true,
135
+ "runtime_trace_empty": true,
136
+ "runtime_trace_multibatch": true,
137
+ }
138
+
123
139
  var expectedV2ComplianceGaps = map[string]bool{
124
140
  "bitwise_and_not_assignment": true,
125
141
  "buffer_value_field_error": true,
@@ -18,6 +18,8 @@ type Config struct {
18
18
  BuildFlags []string
19
19
  // OverrideDirs are additional GoScript override roots.
20
20
  OverrideDirs []string
21
+ // PackageBlocklist rejects package paths in the loaded dependency closure.
22
+ PackageBlocklist []string
21
23
  // AllDependencies controls whether dependencies are included in the graph.
22
24
  AllDependencies bool
23
25
  // DisableEmitBuiltin controls whether runtime packages are emitted.
@@ -1,6 +1,6 @@
1
1
  package gotest
2
2
 
3
- import "github.com/aperturerobotics/goscript/compiler"
3
+ import "github.com/s4wave/goscript/compiler"
4
4
 
5
5
  // Result describes one GoScript package-test run.
6
6
  type Result struct {
@@ -12,9 +12,9 @@ import (
12
12
  "sync"
13
13
  "time"
14
14
 
15
- "github.com/aperturerobotics/goscript/compiler"
16
- "github.com/aperturerobotics/goscript/compiler/tsworkspace"
17
15
  "github.com/pkg/errors"
16
+ "github.com/s4wave/goscript/compiler"
17
+ "github.com/s4wave/goscript/compiler/tsworkspace"
18
18
  )
19
19
 
20
20
  const combinedRuntimeResultPrefix = "__GOSCRIPT_PACKAGE_RESULT__"
@@ -11,7 +11,7 @@ import (
11
11
  "testing"
12
12
  "time"
13
13
 
14
- "github.com/aperturerobotics/goscript/compiler"
14
+ "github.com/s4wave/goscript/compiler"
15
15
  )
16
16
 
17
17
  func TestDiagnosticsSummaryUsesCompilerFormatter(t *testing.T) {
@@ -604,7 +604,7 @@ func TestRunnerScopesPackageLoadErrors(t *testing.T) {
604
604
  }
605
605
  }
606
606
 
607
- func TestRunnerScopesPackageCompileErrors(t *testing.T) {
607
+ func TestRunnerCompilesAddressOfDereferencePackage(t *testing.T) {
608
608
  moduleDir := writeFixture(t, map[string]string{
609
609
  "go.mod": "module example.test/mixedcompile\n\ngo 1.25.3\n",
610
610
  "clean/value.go": strings.Join([]string{
@@ -664,11 +664,8 @@ func TestRunnerScopesPackageCompileErrors(t *testing.T) {
664
664
  t.Fatalf("clean package should pass independently: %#v", clean)
665
665
  }
666
666
  broken := requirePackageResult(t, result, "example.test/mixedcompile/broken")
667
- if broken.Action != ActionFail || broken.Owner != OwnerLowering {
668
- t.Fatalf("broken package should carry lowering failure: %#v", broken)
669
- }
670
- if !strings.Contains(broken.Error, "unsupported address expression") {
671
- t.Fatalf("broken package error should preserve compile diagnostic: %#v", broken)
667
+ if broken.Action != ActionPass {
668
+ t.Fatalf("address-of-dereference package should pass: %#v", broken)
672
669
  }
673
670
  }
674
671
 
@@ -51,4 +51,32 @@ describe('GoScript Compiler API', () => {
51
51
  stderr: expect.stringContaining('main.go:4:'),
52
52
  })
53
53
  }, 30000)
54
+
55
+ it('forwards the package blocklist to closure compiles', async () => {
56
+ const dir = await mkdtemp(join(tmpdir(), 'goscript-api-blocklist-'))
57
+ const output = join(dir, 'output')
58
+ await mkdir(join(dir, 'dep'), { recursive: true })
59
+ await writeFile(join(dir, 'go.mod'), 'module example.test/apiblock\n\ngo 1.25.3\n')
60
+ await writeFile(join(dir, 'main.go'), [
61
+ 'package apiblock',
62
+ 'import "example.test/apiblock/dep"',
63
+ 'func Value() int { return dep.Value() }',
64
+ '',
65
+ ].join('\n'))
66
+ await writeFile(join(dir, 'dep', 'dep.go'), [
67
+ 'package dep',
68
+ 'func Value() int { return 1 }',
69
+ '',
70
+ ].join('\n'))
71
+
72
+ await expect(compile({
73
+ pkg: '.',
74
+ output,
75
+ dir,
76
+ allDependencies: true,
77
+ packageBlocklist: ['example.test/apiblock/dep'],
78
+ })).rejects.toMatchObject({
79
+ stderr: expect.stringContaining('example.test/apiblock -> example.test/apiblock/dep'),
80
+ })
81
+ }, 30000)
54
82
  })
package/compiler/index.ts CHANGED
@@ -19,6 +19,10 @@ export interface CompileConfig {
19
19
  output?: string
20
20
  /** The working directory for the compiler. Defaults to the current working directory. */
21
21
  dir?: string
22
+ /** Compile all transitive dependencies of the requested package. */
23
+ allDependencies?: boolean
24
+ /** Go import paths to reject from the compiled package graph. */
25
+ packageBlocklist?: string[] | string
22
26
  /** The path to the goscript executable. Defaults to `go run ./cmd/goscript`. */
23
27
  goscriptPath?: string
24
28
  }
@@ -33,33 +37,45 @@ export async function compile(config: CompileConfig): Promise<void> {
33
37
 
34
38
  const cwd = config.dir ? path.resolve(config.dir) : process.cwd()
35
39
  const output = config.output ? path.resolve(config.output) : './output'
40
+ const args = [
41
+ 'compile',
42
+ '--package',
43
+ config.pkg,
44
+ '--output',
45
+ output,
46
+ '--dir',
47
+ cwd,
48
+ ]
49
+ if (config.allDependencies) {
50
+ args.push('--all-dependencies')
51
+ }
52
+ const packageBlocklist = normalizePackageBlocklist(config.packageBlocklist)
53
+ if (packageBlocklist) {
54
+ args.push('--package-blocklist', packageBlocklist)
55
+ }
36
56
 
37
57
  if (config.goscriptPath) {
38
- await execFileAsync(config.goscriptPath, [
39
- 'compile',
40
- '--package',
41
- config.pkg,
42
- '--output',
43
- output,
44
- '--dir',
45
- cwd,
46
- ])
58
+ await execFileAsync(config.goscriptPath, args)
47
59
  return
48
60
  }
49
61
 
50
62
  await execFileAsync('go', [
51
63
  'run',
52
64
  path.join(projectRoot, 'cmd/goscript'),
53
- 'compile',
54
- '--package',
55
- config.pkg,
56
- '--output',
57
- output,
58
- '--dir',
59
- cwd,
65
+ ...args,
60
66
  ])
61
67
  }
62
68
 
69
+ function normalizePackageBlocklist(value: string[] | string | undefined): string {
70
+ if (!value) {
71
+ return ''
72
+ }
73
+ if (Array.isArray(value)) {
74
+ return value.map((item) => item.trim()).filter(Boolean).join(',')
75
+ }
76
+ return value.trim()
77
+ }
78
+
63
79
  /**
64
80
  * Default export for convenience.
65
81
  */