## Compiles Nim bots before battle tests. ## config.nims in each bot dir already sets --path and --outdir, so we just ## run `nim c src/BotName.nim` from the bot dir and let config.nims do the rest. import std/[os, osproc, streams, strformat, strutils, sequtils] proc compileBots*(botDirs: seq[string]): seq[string] = ## Compiles each bot dir, returns absolute paths to compiled binaries. ## Raises on first compilation failure, message includes compiler output. for dir in botDirs: let absDir = absolutePath(dir) # Infer main source: src/.nim where stem = last path component # minus optional _garage suffix (e.g. OscillatorBot_garage → OscillatorBot) var stem = lastPathPart(absDir) if stem.endsWith("_garage"): stem = stem[0 ..< stem.len - "_garage".len] let srcFile = absDir / "src" / stem & ".nim" if not fileExists(srcFile): # Fall back: pick the first .nim in src/ let candidates = toSeq(walkFiles(absDir / "src" / "*.nim")) if candidates.len == 0: raise newException(IOError, fmt"No .nim source found in {absDir}/src/") stem = splitFile(candidates[0]).name # ponytail: startProcess+streams for timeout; execCmdEx has no timeout param let p = startProcess("nim", workingDir = absDir, args = ["c", fmt"src/{stem}.nim"], options = {poUsePath, poStdErrToStdOut}) let exitCode = waitForExit(p, timeout = 30_000) let output = p.outputStream.readAll() p.close() if exitCode != 0: raise newException(OSError, fmt"Compilation failed for {absDir}:{'\n'}{output}") result.add absDir / "out" / stem when isMainModule: let botDir = currentSourcePath().parentDir().parentDir().parentDir() / "OscillatorBot_garage" echo "Compiling OscillatorBot from: ", botDir try: let bins = compileBots(@[botDir]) echo "OK — binary: ", bins[0] doAssert fileExists(bins[0]), "binary not found after compile" except CatchableError as e: echo "FAIL: ", e.msg quit(1)