resolvedFixtureVersions static method

String resolvedFixtureVersions(
  1. String projectPath
)

The tom_* packages projectPath's lock resolved, as one line.

The FIXTURE's lock, not the calling package's. example/d4 is its own package with its own gitignored lock while it path-resolves the interpreter from the working tree, so it can freeze at a version that no longer compiles against HEAD — which is what happened at tom_d4rt_ast 0.19.0, whose exports lacked ConvertStdlib, CollectionStdlib, TypedDataStdlib and Logger.

Best-effort BY DESIGN: this runs on a path that has already failed, so a missing or unparseable lock must degrade to a note rather than throw and replace the real diagnosis with its own.

Public and static so the two test-local copies of this pipeline (tom_d4rt_exec's ExecTestSetup, tom_ast_generator's AstgenTestSetup) can delegate here rather than keep a third and fourth transcription — once they resolve a release carrying it. Measured 2026-09-22: both resolve tom_d4rt_generator 1.28.0 hosted against a working tree well past it, so until that publish they must duplicate (DGUC6), and each says so where it does.

Implementation

static String resolvedFixtureVersions(String projectPath) {
  final lock = File(p.join(projectPath, 'pubspec.lock'));
  if (!lock.existsSync()) {
    return 'no pubspec.lock in $projectPath — the fixture was never resolved';
  }
  try {
    final entry = RegExp(
      r'^  (tom_\w+):\n(?:.*\n)*?    source: (\S+)\n    version: "([^"]+)"',
      multiLine: true,
    );
    final found = [
      for (final m in entry.allMatches(lock.readAsStringSync()))
        '${m.group(1)} ${m.group(3)} (${m.group(2)})',
    ];
    if (found.isEmpty) return 'no tom_* packages in ${lock.path}';
    return found.join(', ');
  } catch (e) {
    return 'could not read ${lock.path}: $e';
  }
}