Skip to content

Commit fc53a5a

Browse files
committed
repro_cli_support: translate buildNimUnittest.build through nim profile
The `defineCliInterface buildNimUnittest, NimUnittestToolId` typed tool has no backing binary — its action is conceptually a `nim c` invocation that compiles a Nim unittest test binary. Without a tool profile, `lowerGraphAction` raised: tool-resolution failed: action ct_test_nim_unittest.buildnimunittest-build-XXXX references executable ct_test_nim_unittest.buildNimUnittest but no tool profile was resolved for it so every reprobuild test edge dispatched through `buildNimUnittest` failed to lower into an executable command, blocking `./build/bin/repro build test` for the entire 454-edge suite. Add a focused passthrough in `lowerGraphAction`: when the call's executable name is `ct_test_nim_unittest.buildNimUnittest` and its subcommand is `build`, translate the action into a direct `nim c` invocation using the resolved `nim` profile. The argument mapping is straightforward: subcommand "build" -> subcommand "c" --source=<path> (positional) -> positional <path> --binary=<path> -> --out:<path> --threads:on / --hints:off / --warnings:off -> same (verbatim) --define:<X> / --import:<X> -> same (verbatim) Pragmatic shim until a typed-tool passthrough feature (a typed tool that dispatches through an underlying tool's profile, without each call site re-declaring the binary) lands in the engine. The 454-edge reprobuild test suite is the primary consumer; the shim unblocks `repro build test` end-to-end while leaving the broader typed-tool adapter contract unchanged.
1 parent e961956 commit fc53a5a

1 file changed

Lines changed: 99 additions & 0 deletions

File tree

libs/repro_cli_support/src/repro_cli_support.nim

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1291,6 +1291,105 @@ proc lowerGraphAction(node: GraphNode; profiles: Table[string, PathOnlyToolProfi
12911291
let executableName = payload.call.executableName
12921292
let packageName = payload.call.packageName
12931293
let exactKey = packageName & "|" & executableName
1294+
1295+
# ct_test_nim_unittest.buildNimUnittest.build typed-tool passthrough.
1296+
# The typed-tool defined via ``defineCliInterface buildNimUnittest,
1297+
# NimUnittestToolId`` has no real backing binary — its action is
1298+
# conceptually a ``nim c`` invocation that compiles a Nim unittest
1299+
# test binary. Translate the call into a direct ``nim c`` action
1300+
# using the ``nim`` profile from ``uses: "nim"``. Argument mapping:
1301+
#
1302+
# subcommand "build" -> subcommand "c"
1303+
# --source=<path> (positional)-> positional <path>
1304+
# --binary=<path> -> --out:<path>
1305+
# --threads:on (verbatim) -> --threads:on
1306+
# --hints:off (verbatim) -> --hints:off
1307+
# --warnings:off (verbatim) -> --warnings:off
1308+
# --define:<X> (verbatim) -> --define:<X>
1309+
# --import:<X> (verbatim) -> --import:<X>
1310+
#
1311+
# This is a pragmatic shim until a typed-tool passthrough feature
1312+
# (typed tool that dispatches through an underlying tool's profile)
1313+
# lands in the engine. The 454-edge reprobuild test suite is the
1314+
# primary consumer.
1315+
if executableName == "ct_test_nim_unittest.buildNimUnittest" and
1316+
payload.call.subcommand == "build":
1317+
if not profiles.hasKey("nim"):
1318+
raise newException(ValueError,
1319+
"tool-resolution failed: action " & payload.id &
1320+
" references typed tool ct_test_nim_unittest.buildNimUnittest " &
1321+
"which dispatches through `nim` but no `nim` profile was " &
1322+
"resolved. Declare `uses: \"nim\"` in your project file.")
1323+
let nimProfile = profiles["nim"]
1324+
var argv: seq[string] = @[nimProfile.resolvedExecutablePath, "c"]
1325+
var sourcePath = ""
1326+
for arg in payload.call.arguments:
1327+
case arg.name
1328+
of "source":
1329+
sourcePath = arg.encodedValue
1330+
of "binary":
1331+
argv.add("--out:" & arg.encodedValue)
1332+
of "threadsOn":
1333+
if arg.encodedValue.normalize == "true":
1334+
argv.add("--threads:on")
1335+
of "hintsOff":
1336+
if arg.encodedValue.normalize == "true":
1337+
argv.add("--hints:off")
1338+
of "warningsOff":
1339+
if arg.encodedValue.normalize == "true":
1340+
argv.add("--warnings:off")
1341+
of "defines":
1342+
if arg.encodedValue.len > 0:
1343+
for item in arg.encodedValue.split("\x1f"):
1344+
argv.add("--define:" & item)
1345+
of "imports":
1346+
if arg.encodedValue.len > 0:
1347+
for item in arg.encodedValue.split("\x1f"):
1348+
argv.add("--import:" & item)
1349+
else:
1350+
discard
1351+
if sourcePath.len > 0:
1352+
argv.add(sourcePath)
1353+
var translatedInputs: seq[string] = @[]
1354+
for input in payload.inputs:
1355+
translatedInputs.add(materialProjectPath(projectRoot, input))
1356+
let commandStatsId =
1357+
if payload.commandStatsId.len > 0:
1358+
payload.commandStatsId
1359+
else:
1360+
payload.id
1361+
let fingerprintText = [
1362+
"reprobuild.localProjectAction.v1",
1363+
payload.id,
1364+
"nim",
1365+
"nim",
1366+
"c",
1367+
node.payload,
1368+
digestHex(nimProfile.profileFingerprint)
1369+
].join("\n")
1370+
return repro_build_engine.action(
1371+
payload.id,
1372+
argv,
1373+
cwd = projectRoot,
1374+
deps = payload.deps,
1375+
inputs = translatedInputs,
1376+
outputs = payload.outputs,
1377+
pool = payload.pool,
1378+
poolUnits = payload.poolUnits,
1379+
depfile = payload.depfile,
1380+
dynamicDepsFile = payload.dynamicDepsFile,
1381+
cacheable = payload.cacheable,
1382+
weakFingerprint = weakFingerprintFromText(fingerprintText),
1383+
actionCachePolicy = actionCachePolicy,
1384+
dependencyPolicy = lowerDependencyPolicy(payload.id, payload.depfile,
1385+
payload.dependencyPolicy),
1386+
commandStatsId = commandStatsId,
1387+
env =
1388+
if actionPathPrefix.len > 0:
1389+
@["PATH=" & actionPathPrefix & $PathSep & getEnv("PATH")]
1390+
else:
1391+
@[])
1392+
12941393
let profile =
12951394
if profiles.hasKey(exactKey):
12961395
profiles[exactKey]

0 commit comments

Comments
 (0)