Skip to content

Commit bdf9829

Browse files
nadilasclaude
andcommitted
feat: generate TinyGo stdlib compatibility database
Run audit against TinyGo 0.40.0 wasip2 target: - 19/20 packages compile successfully - Only crypto/tls fails (missing Config.Clone, X509KeyPair) - Fix JSON generation to use jq for safe string escaping - Generate compat-db/tinygo-stdlib.json (machine-readable) - Generate compat-db/tinygo-stdlib-compat-table.md (human-readable) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent a519072 commit bdf9829

File tree

3 files changed

+282
-79
lines changed

3 files changed

+282
-79
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# TinyGo wasip2 Standard Library Compatibility
2+
3+
**Compiler**: TinyGo 0.40.0
4+
**Target**: wasip2
5+
**Go Version**: 1.25.1
6+
**Tested**: 2026-03-14T09:46:47Z
7+
**User Story**: US-302
8+
9+
## Summary
10+
11+
- **Pass**: 19/20 packages compile successfully
12+
- **Fail**: 1/20 packages fail to compile
13+
- **Partial**: 0/20 packages compile with warnings
14+
15+
## Compatibility Table
16+
17+
| Package | Import Path | Status | Errors | Notes |
18+
|---------|-------------|--------|--------|-------|
19+
| bytes | bytes | pass | 0 | Compiles successfully with TinyGo wasip2 |
20+
| context | context | pass | 0 | Compiles successfully with TinyGo wasip2 |
21+
| crypto/sha256 | crypto/sha256 | pass | 0 | Compiles successfully with TinyGo wasip2 |
22+
| crypto/tls | crypto/tls | fail | 2 | TinyGo wasip2 compilation failed with 2 error(s) |
23+
| database/sql | database/sql | pass | 0 | Compiles successfully with TinyGo wasip2 |
24+
| encoding/base64 | encoding/base64 | pass | 0 | Compiles successfully with TinyGo wasip2 |
25+
| encoding/json | encoding/json | pass | 0 | Compiles successfully with TinyGo wasip2 |
26+
| fmt | fmt | pass | 0 | Compiles successfully with TinyGo wasip2 |
27+
| io | io | pass | 0 | Compiles successfully with TinyGo wasip2 |
28+
| log | log | pass | 0 | Compiles successfully with TinyGo wasip2 |
29+
| math | math | pass | 0 | Compiles successfully with TinyGo wasip2 |
30+
| net | net | pass | 0 | Compiles successfully with TinyGo wasip2 |
31+
| net/http | net/http | pass | 0 | Compiles successfully with TinyGo wasip2 |
32+
| os | os | pass | 0 | Compiles successfully with TinyGo wasip2 |
33+
| regexp | regexp | pass | 0 | Compiles successfully with TinyGo wasip2 |
34+
| sort | sort | pass | 0 | Compiles successfully with TinyGo wasip2 |
35+
| strconv | strconv | pass | 0 | Compiles successfully with TinyGo wasip2 |
36+
| strings | strings | pass | 0 | Compiles successfully with TinyGo wasip2 |
37+
| sync | sync | pass | 0 | Compiles successfully with TinyGo wasip2 |
38+
| time | time | pass | 0 | Compiles successfully with TinyGo wasip2 |
39+
40+
---
41+
42+
*Generated by `scripts/audit-tinygo-stdlib.sh --table`*

compat-db/tinygo-stdlib.json

Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
{
2+
"compiler": "tinygo",
3+
"compilerVersion": "0.40.0",
4+
"target": "wasip2",
5+
"testedAt": "2026-03-14T09:46:47Z",
6+
"goVersion": "1.25.1",
7+
"userStory": "US-302",
8+
"packageCount": 20,
9+
"packages": [
10+
{
11+
"name": "bytes",
12+
"importPath": "bytes",
13+
"compileStatus": "pass",
14+
"errors": [],
15+
"errorCount": 0,
16+
"missingSymbols": [],
17+
"notes": "Compiles successfully with TinyGo wasip2"
18+
},
19+
{
20+
"name": "context",
21+
"importPath": "context",
22+
"compileStatus": "pass",
23+
"errors": [],
24+
"errorCount": 0,
25+
"missingSymbols": [],
26+
"notes": "Compiles successfully with TinyGo wasip2"
27+
},
28+
{
29+
"name": "crypto/sha256",
30+
"importPath": "crypto/sha256",
31+
"compileStatus": "pass",
32+
"errors": [],
33+
"errorCount": 0,
34+
"missingSymbols": [],
35+
"notes": "Compiles successfully with TinyGo wasip2"
36+
},
37+
{
38+
"name": "crypto/tls",
39+
"importPath": "crypto/tls",
40+
"compileStatus": "fail",
41+
"errors": [
42+
"# command-line-arguments",
43+
"tests/fixtures/go-stdlib-compat/pkg_crypto_tls/main.go:18:16: cfg.Clone undefined (type *tls.Config has no field or method Clone)",
44+
"tests/fixtures/go-stdlib-compat/pkg_crypto_tls/main.go:39:16: undefined: tls.X509KeyPair"
45+
],
46+
"errorCount": 2,
47+
"missingSymbols": [
48+
"tls.X509KeyPair"
49+
],
50+
"notes": "TinyGo wasip2 compilation failed with 2 error(s)"
51+
},
52+
{
53+
"name": "database/sql",
54+
"importPath": "database/sql",
55+
"compileStatus": "pass",
56+
"errors": [],
57+
"errorCount": 0,
58+
"missingSymbols": [],
59+
"notes": "Compiles successfully with TinyGo wasip2"
60+
},
61+
{
62+
"name": "encoding/base64",
63+
"importPath": "encoding/base64",
64+
"compileStatus": "pass",
65+
"errors": [],
66+
"errorCount": 0,
67+
"missingSymbols": [],
68+
"notes": "Compiles successfully with TinyGo wasip2"
69+
},
70+
{
71+
"name": "encoding/json",
72+
"importPath": "encoding/json",
73+
"compileStatus": "pass",
74+
"errors": [],
75+
"errorCount": 0,
76+
"missingSymbols": [],
77+
"notes": "Compiles successfully with TinyGo wasip2"
78+
},
79+
{
80+
"name": "fmt",
81+
"importPath": "fmt",
82+
"compileStatus": "pass",
83+
"errors": [],
84+
"errorCount": 0,
85+
"missingSymbols": [],
86+
"notes": "Compiles successfully with TinyGo wasip2"
87+
},
88+
{
89+
"name": "io",
90+
"importPath": "io",
91+
"compileStatus": "pass",
92+
"errors": [],
93+
"errorCount": 0,
94+
"missingSymbols": [],
95+
"notes": "Compiles successfully with TinyGo wasip2"
96+
},
97+
{
98+
"name": "log",
99+
"importPath": "log",
100+
"compileStatus": "pass",
101+
"errors": [],
102+
"errorCount": 0,
103+
"missingSymbols": [],
104+
"notes": "Compiles successfully with TinyGo wasip2"
105+
},
106+
{
107+
"name": "math",
108+
"importPath": "math",
109+
"compileStatus": "pass",
110+
"errors": [],
111+
"errorCount": 0,
112+
"missingSymbols": [],
113+
"notes": "Compiles successfully with TinyGo wasip2"
114+
},
115+
{
116+
"name": "net",
117+
"importPath": "net",
118+
"compileStatus": "pass",
119+
"errors": [],
120+
"errorCount": 0,
121+
"missingSymbols": [],
122+
"notes": "Compiles successfully with TinyGo wasip2"
123+
},
124+
{
125+
"name": "net/http",
126+
"importPath": "net/http",
127+
"compileStatus": "pass",
128+
"errors": [],
129+
"errorCount": 0,
130+
"missingSymbols": [],
131+
"notes": "Compiles successfully with TinyGo wasip2"
132+
},
133+
{
134+
"name": "os",
135+
"importPath": "os",
136+
"compileStatus": "pass",
137+
"errors": [],
138+
"errorCount": 0,
139+
"missingSymbols": [],
140+
"notes": "Compiles successfully with TinyGo wasip2"
141+
},
142+
{
143+
"name": "regexp",
144+
"importPath": "regexp",
145+
"compileStatus": "pass",
146+
"errors": [],
147+
"errorCount": 0,
148+
"missingSymbols": [],
149+
"notes": "Compiles successfully with TinyGo wasip2"
150+
},
151+
{
152+
"name": "sort",
153+
"importPath": "sort",
154+
"compileStatus": "pass",
155+
"errors": [],
156+
"errorCount": 0,
157+
"missingSymbols": [],
158+
"notes": "Compiles successfully with TinyGo wasip2"
159+
},
160+
{
161+
"name": "strconv",
162+
"importPath": "strconv",
163+
"compileStatus": "pass",
164+
"errors": [],
165+
"errorCount": 0,
166+
"missingSymbols": [],
167+
"notes": "Compiles successfully with TinyGo wasip2"
168+
},
169+
{
170+
"name": "strings",
171+
"importPath": "strings",
172+
"compileStatus": "pass",
173+
"errors": [],
174+
"errorCount": 0,
175+
"missingSymbols": [],
176+
"notes": "Compiles successfully with TinyGo wasip2"
177+
},
178+
{
179+
"name": "sync",
180+
"importPath": "sync",
181+
"compileStatus": "pass",
182+
"errors": [],
183+
"errorCount": 0,
184+
"missingSymbols": [],
185+
"notes": "Compiles successfully with TinyGo wasip2"
186+
},
187+
{
188+
"name": "time",
189+
"importPath": "time",
190+
"compileStatus": "pass",
191+
"errors": [],
192+
"errorCount": 0,
193+
"missingSymbols": [],
194+
"notes": "Compiles successfully with TinyGo wasip2"
195+
}
196+
]
197+
}

scripts/audit-tinygo-stdlib.sh

Lines changed: 43 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -165,95 +165,59 @@ run_build() {
165165
fi
166166
fi
167167

168-
# Extract error details
169-
local errors_json="[]"
170-
local error_count=0
171-
local missing_symbols_json="[]"
172-
local notes=""
173-
168+
# Build JSON entry for this package using jq for safe escaping
169+
local entry
174170
if [ "${compile_status}" != "pass" ] && [ -n "${compile_output}" ]; then
175-
# Count error lines
176-
error_count=$(echo "${compile_output}" | grep -c 'error:\|Error\|cannot\|undefined\|not declared\|missing' 2>/dev/null || echo "0")
177-
178-
# Collect individual error messages (first 20 lines)
179-
local error_lines=""
180-
while IFS= read -r line; do
181-
if [ -n "${line}" ]; then
182-
local escaped
183-
escaped=$(echo "${line}" | sed 's/\\/\\\\/g; s/"/\\"/g; s/\t/ /g')
184-
if [ -n "${error_lines}" ]; then
185-
error_lines="${error_lines}, "
186-
fi
187-
error_lines="${error_lines}\"${escaped}\""
188-
fi
189-
done < <(echo "${compile_output}" | head -20)
190-
if [ -n "${error_lines}" ]; then
191-
errors_json="[${error_lines}]"
192-
fi
193-
194-
# Extract missing/undefined symbols
195-
local symbols=""
196-
while IFS= read -r sym; do
197-
if [ -n "${sym}" ]; then
198-
local escaped_sym
199-
escaped_sym=$(echo "${sym}" | sed 's/\\/\\\\/g; s/"/\\"/g')
200-
if [ -n "${symbols}" ]; then
201-
symbols="${symbols}, "
202-
fi
203-
symbols="${symbols}\"${escaped_sym}\""
204-
fi
205-
done < <(echo "${compile_output}" | grep -oP 'undefined: \K[a-zA-Z0-9_.]+' 2>/dev/null || true)
206-
if [ -n "${symbols}" ]; then
207-
missing_symbols_json="[${symbols}]"
208-
fi
209-
210-
notes="TinyGo wasip2 compilation failed with ${error_count} error(s)"
171+
local error_count
172+
error_count=$(echo "${compile_output}" | grep -c 'error:\|Error\|cannot\|undefined\|not declared\|missing' || true)
173+
error_count=${error_count:-0}
174+
175+
# Use jq to safely construct JSON with proper escaping
176+
local errors_array
177+
errors_array=$(echo "${compile_output}" | head -20 | jq -R -s 'split("\n") | map(select(length > 0))')
178+
179+
local missing_array
180+
missing_array=$(echo "${compile_output}" | grep -oP 'undefined: \K[a-zA-Z0-9_.]+' 2>/dev/null | jq -R -s 'split("\n") | map(select(length > 0))' || echo "[]")
181+
182+
local notes="TinyGo wasip2 compilation failed with ${error_count} error(s)"
183+
184+
entry=$(jq -n \
185+
--arg name "${pkg_name}" \
186+
--arg importPath "${import_path}" \
187+
--arg status "${compile_status}" \
188+
--argjson errors "${errors_array}" \
189+
--argjson errorCount "${error_count}" \
190+
--argjson missing "${missing_array}" \
191+
--arg notes "${notes}" \
192+
'{name: $name, importPath: $importPath, compileStatus: $status, errors: $errors, errorCount: $errorCount, missingSymbols: $missing, notes: $notes}')
211193
else
212-
notes="Compiles successfully with TinyGo wasip2"
194+
entry=$(jq -n \
195+
--arg name "${pkg_name}" \
196+
--arg importPath "${import_path}" \
197+
--arg status "${compile_status}" \
198+
'{name: $name, importPath: $importPath, compileStatus: $status, errors: [], errorCount: 0, missingSymbols: [], notes: "Compiles successfully with TinyGo wasip2"}')
213199
fi
214200

215-
# Build JSON entry
216-
local entry
217-
entry=$(cat <<ENTRYEOF
218-
{
219-
"name": "${pkg_name}",
220-
"importPath": "${import_path}",
221-
"compileStatus": "${compile_status}",
222-
"errors": ${errors_json},
223-
"errorCount": ${error_count},
224-
"missingSymbols": ${missing_symbols_json},
225-
"notes": "${notes}"
226-
}
227-
ENTRYEOF
228-
)
229-
230-
if [ -n "${packages_json}" ]; then
231-
packages_json="${packages_json},
232-
${entry}"
233-
else
234-
packages_json="${entry}"
235-
fi
201+
# Accumulate entries into a temp file
202+
echo "${entry}" >> "${TMP_DIR}/results.jsonl"
236203
done
237204

238205
# Extract compiler version number
239206
local compiler_version
240207
compiler_version=$(echo "${tinygo_version}" | grep -oP '\d+\.\d+\.\d+' | head -1 || echo "unknown")
241208

242-
# Write final JSON
243-
cat > "${JSON_OUTPUT}" <<JSONEOF
244-
{
245-
"compiler": "tinygo",
246-
"compilerVersion": "${compiler_version}",
247-
"target": "wasip2",
248-
"testedAt": "${tested_at}",
249-
"goVersion": "${go_version}",
250-
"userStory": "US-302",
251-
"packageCount": ${pkg_count},
252-
"packages": [
253-
${packages_json}
254-
]
255-
}
256-
JSONEOF
209+
# Assemble final JSON from collected entries using jq
210+
jq -n \
211+
--arg compiler "tinygo" \
212+
--arg compilerVersion "${compiler_version}" \
213+
--arg target "wasip2" \
214+
--arg testedAt "${tested_at}" \
215+
--arg goVersion "${go_version}" \
216+
--arg userStory "US-302" \
217+
--argjson packageCount "${pkg_count}" \
218+
--slurpfile packages "${TMP_DIR}/results.jsonl" \
219+
'{compiler: $compiler, compilerVersion: $compilerVersion, target: $target, testedAt: $testedAt, goVersion: $goVersion, userStory: $userStory, packageCount: $packageCount, packages: $packages}' \
220+
> "${JSON_OUTPUT}"
257221

258222
echo ""
259223
log "Results written to ${JSON_OUTPUT}"

0 commit comments

Comments
 (0)