Tom Build

> Tom Build is part of the Tom framework by al-the-bear. > Distributed under the terms in this package's license — see > ../LICENSE.md.

Build tools and workspace analyzer for the Tom framework.

tom_build is the library that understands the monorepo. It walks a Dart/Flutter workspace, detects what each folder is (a Dart package, a Flutter app, a server, a test project), works out the order packages must be built in, and writes a single machine-readable description of the whole workspace to .tom_metadata/tom_master.yaml. Every other Tom devops tool — buildkit, testkit, issuekit, the tom CLI — reads that file instead of re-scanning the disk. tom_build also ships the scripting helpers (TomShell, TomFs, TomGlob, …) that D4rt build scripts use, the file object model that parses tom_workspace.yaml / tom_project.yaml, and a programmatic reflection-generator runner.

---

Overview

A Tom workspace is a tree of many Dart packages, Flutter apps and server projects spread across nested git repositories. Tools that operate on the workspace — building, testing, publishing, deploying — all need the same foundational facts:

  • What projects exist, where they live, and what type each one is.
  • How they depend on each other, so they can be built in a safe order.
  • What capabilities each one has (tests, examples, reflection, build_runner,

docker, assets) so a tool can decide what to do with it.

Re-deriving those facts on every invocation is slow and inconsistent. tom_build derives them once, in the WorkspaceAnalyzer, and writes the result to .tom_metadata/tom_master.yaml. That file is the single source of truth for workspace structure; the rest of the toolchain consumes it through the lightweight WorkspaceInfo / ToolContext readers.

The package has four cooperating concerns:

ConcernEntry typeWhat it does
Workspace analysis WorkspaceAnalyzer Scans the workspace, detects natures, computes build order, writes tom_master.yaml.
Metadata reading WorkspaceInfo, ToolContext Loads the generated metadata back into typed objects for consuming tools.
File object model WorkspaceParser, TomMaster, TomProject Parses tom_workspace.yaml / tom_project.yaml into a rich configuration model (modes, actions, pipelines).
Scripting helpers TomShell, TomFs, TomGlob, … Shell-script-like static helpers for D4rt-based build scripts.

A fifth, smaller concern — driving the reflection generator from code — is exposed through ReflectionGeneratorRunner.

tom_build depends only on the analyzer toolchain and the core Tom packages; it deliberately does not depend on tom_build_cli, so the analyzer binary can run with a minimal dependency closure.

---

Installation

tom_build is a workspace-internal package (publish_to: none). It is not published to pub.dev — it lives inside the Tom devops repository and is consumed in place by the other tools in this repo, which reference it as a workspace member. There is no dart pub add tom_build, and you should never add a manual path: override to reach it from outside the workspace; tools that need it already declare it as a workspace dependency.

Inside the workspace you typically use tom_build in one of two ways:

1. As a command — run the bundled workspace_analyzer binary (see Quick start). 2. As a library — import it from another package in the same workspace:

   import 'package:tom_build/tom_build.dart';        // analyzer, FOM, tools
   import 'package:tom_build/scripting.dart';        // scripting helpers only

SDK requirement: Dart ^3.10.4. The analyzer uses the analyzer, dart_style, yaml and pub_semver packages; the core dependencies (tom_core_kernel, tom_core_server, tom_dist_ledger, tom_process_monitor) are resolved as workspace members.

---

Features

Workspace analysis

CapabilityDescription
Project discovery Recursively scans the workspace, skipping ignored folders, and identifies every Dart/Flutter project.
Nature detection Classifies each project (package, Flutter app, server, CLI tool, test project).
Build-order resolution Derives a dependency-respecting build order across all projects.
Capability flags Records which projects have tests, examples, reflection, build_runner, docker, assets.
Parts & modules Captures sub-package structure ( PartInfo , ModuleInfo ) for multi-module projects.
Test-project filtering Excludes zom_* test projects by default; AnalyzerOptions.all includes them.
Metadata emission Writes .tom_metadata/tom_master.yaml plus per-action master files.

Metadata reading

TypeResponsibility
WorkspaceInfo Typed view of tom_master.yaml : buildOrder , projects , groups , workspaceModes , settings .
WorkspaceProject One project entry from the metadata (name, type, capabilities).
WorkspaceGroupA named group of projects.
ToolContext Process-wide singleton that loads and caches WorkspaceInfo plus platform info.
PlatformInfo Detected OS / CPU architecture and the derived cross-compile target list.

File object model

TypeResponsibility
WorkspaceParser Parses a workspace directory into a TomMaster.
TomWorkspace Base configuration from tom_workspace.yaml (modes, actions, project types, versions).
TomMaster The full workspace model (TomWorkspace + discovered projects).
TomProject One project's tom_project.yaml / pubspec-derived configuration.
ModeDefinitions, ActionDef, Pipeline The mode / action / pipeline configuration model used by the build tools.

Scripting helpers (package:tom_build/scripting.dart)

All helpers are static-method classes, designed to read cleanly inside D4rt build scripts but equally usable from plain Dart.

HelperWhat it covers
TomShell run , exec , capture , runAll , pipe , hasCommand , which .
TomFs read , readLines , tryRead , write , append , byte variants.
TomPth join , dirname , basename , basenameNoExt , extension , split , absolute .
TomGlob find , findFiles , findDirs , matches , filter , exclude .
TomText template , indent , dedent , wrap , truncate , lines .
TomEnv load , reload , loadFile , resolve , get.env and process env.
TomMaps, ScriptYaml, TomZoned, TomWs Map merging, YAML loading, zone values, workspace-metadata access.

Reflection generation

TypeResponsibility
ReflectionGeneratorRunner Drives the reflection generator for a project from code (generate, build).
ReflectionGeneratorRunnerOptions Generator options (target, mode, flags).
ReflectionGeneratorRunnerResult Outcome (success, message, error, stackTrace).

---

Quick start

Generate workspace metadata with the bundled binary. Run it from the tom_build package directory; by default it analyzes the parent directory (the workspace root):

# From tom_ai/devops/tom_build
dart run bin/workspace_analyzer.dart wa-path=/path/to/workspace
Analyzing workspace: /path/to/workspace
Note: Excluding test projects (zom_*). Use wa-include-tests to include them.

Workspace analysis complete!
Metadata written to: /path/to/workspace/.tom_metadata

The same thing programmatically:

import 'package:tom_build/tom_build.dart';

Future<void> main() async {
  final analyzer = WorkspaceAnalyzer(
    '/path/to/workspace',
    options: AnalyzerOptions.production, // excludes zom_* test projects
  );
  await analyzer.analyze();
  print('Metadata written to .tom_metadata/tom_master.yaml');
  // Metadata written to .tom_metadata/tom_master.yaml
}

---

Example projects

WhereDemonstrates
bin/workspace_analyzer.dart The minimal, dependency-light entry point that drives WorkspaceAnalyzer.
test/ 256 tests covering the analyzer, scripting helpers, file object model and file-structure detection — each is a runnable usage example.
tom_build_kit_sample The build framework exercised end to end through buildkit (planned — forward reference until the samples build-out lands) .

tom_build itself has no dedicated standalone sample package; the analyzer binary and the test suite are the canonical runnable examples, and the build-framework workflow is demonstrated by the buildkit sample above.

---

Usage

Running the analyzer (CLI)

The workspace_analyzer binary accepts both wa--prefixed and legacy options:

# Analyze an explicit workspace path
dart run bin/workspace_analyzer.dart wa-path=/path/to/workspace

# Include the zom_* test projects
dart run bin/workspace_analyzer.dart wa-path=. wa-include-tests

# Legacy positional + flag form
dart run bin/workspace_analyzer.dart /path/to/workspace --include-tests

# Help
dart run bin/workspace_analyzer.dart --help
OptionMeaning
wa-path=<path> Workspace root to analyze (default: parent of the current directory).
wa-include-tests Include zom_* test projects in the output.
--include-testsLegacy alias for wa-include-tests.
[path] (positional)Legacy way to pass the workspace path.
--help, -hShow usage.

Programmatic analysis

AnalyzerOptions controls whether test projects are included. Three forms:

import 'package:tom_build/tom_build.dart';

Future<void> main() async {
  // Production: exclude zom_* test projects (the default)
  await WorkspaceAnalyzer('.', options: AnalyzerOptions.production).analyze();

  // All: include test projects
  await WorkspaceAnalyzer('.', options: AnalyzerOptions.all).analyze();

  // Explicit
  await WorkspaceAnalyzer(
    '.',
    options: const AnalyzerOptions(includeTestProjects: true),
  ).analyze();
}

What the analyzer produces

analyze() writes .tom_metadata/tom_master.yaml — a single file describing the whole workspace. Its most-used top-level keys:

KeyContents
nameWorkspace name.
operating-systems / mobile-platforms Target platforms detected for the workspace.
workspace-modes Mode definitions (environment, execution, deployment, …).
project-typesThe recognised project-type catalogue.
actionsAction definitions used by the build tools.
groupsNamed project groups.
build-order The full dependency-respecting build order, as a flat list.
projects Per-project entries: type , description , build-after , features , and the embedded pubspec .

A trimmed excerpt of one project entry shows the capability flags the analyzer derives for every project:

build-order: [tom_basics, tom_build_base, tom_build_common, tom_build_kit, ...]

projects:
  tom_build:
    name: Tom Build
    type: dart_console
    description: "Build tools and workspace analyzer for the Tom framework."
    build-after: [tom_core_kernel, tom_core_server, ...]
    features:
      has-reflection: false
      has-build-runner: false
      has-native-deps: false
      has-assets: false
      publishable: false
      has-tests: true
      has-examples: false
      has-docker: false
      has-ci: false
Feature flagTrue when the project…
has-testshas a test/ directory with test files.
has-exampleshas an example/ directory.
has-reflectionuses Tom reflection (reflectable).
has-build-runnerdeclares a build_runner dev dependency.
has-native-depshas native/FFI dependencies.
has-assetsdeclares Flutter assets.
has-dockerships a Dockerfile.
has-cihas CI configuration.
publishable is intended for publication (not publish_to: none).

build-after records each project's upstream dependencies; the analyzer topologically flattens those relationships into the single build-order list that the tools iterate.

Reading generated metadata

Consuming tools rarely re-run the analyzer; they read the metadata it produced. ToolContext.load reads .tom_metadata/tom_master.yaml once and caches a typed WorkspaceInfo:

import 'package:tom_build/tom_build.dart';

Future<void> main() async {
  final context = await ToolContext.load(workspacePath: '/path/to/workspace');
  final ws = context.workspaceInfo;

  print(ws.buildOrder.first);     // e.g. tom_basics  (first to build)
  print(ws.projects.length);      // e.g. 142         (projects discovered)
  print(context.platform.os);     // e.g. OperatingSystem.linux
}

Once loaded, ToolContext.current returns the cached instance anywhere in the process — no parameter threading required:

final order = ToolContext.current.workspaceInfo.buildOrder;
for (final name in order) {
  print('build $name');
}

If you only have the YAML in hand, build a WorkspaceInfo directly:

import 'package:tom_build/tom_build.dart';
import 'package:yaml/yaml.dart';

void main() {
  final yaml = loadYaml(yamlString) as YamlMap;
  final ws = WorkspaceInfo.fromYaml(yaml);
  print(ws.buildOrder); // [tom_basics, tom_build_base, ...]
}

Parsing the file object model

When you need the configuration model (modes, actions, pipelines, project types) rather than the analyzer's discovery summary, use WorkspaceParser:

import 'package:tom_build/tom_build.dart';

void main() {
  final master = WorkspaceParser('/path/to/workspace').parse();

  print(master.projects.length);   // discovered TomProject entries
  for (final project in master.projects.values) {
    print('${project.name}: ${project.type}');
    // tom_build: dart-package
  }
}

TomMaster extends TomWorkspace, so the parsed result also carries the workspace-level mode/action/pipeline definitions read from tom_workspace.yaml.

Scripting helpers

The scripting.dart barrel gives D4rt build scripts (and ordinary Dart) a familiar shell-like vocabulary. Import only what you need:

import 'package:tom_build/scripting.dart';

void main() {
  // Find and process files
  final files = TomGlob.findFiles('lib/**/*.dart');
  for (final file in files) {
    final content = TomFs.read(file);
    final stamped = TomText.template(content, {'version': '1.0.0'});
    TomFs.write(file, stamped);
  }

  // Run a command and check the result
  final out = TomShell.capture('dart', ['--version']);
  print(out.contains('Dart')); // true

  // Guard on tool availability
  if (TomShell.hasCommand('flutter')) {
    TomShell.exec('flutter', ['pub', 'get']);
  }
}

Path manipulation and environment access follow the same static-method style:

import 'package:tom_build/scripting.dart';

void main() {
  final libDir = TomPth.join('packages', 'tom_build', 'lib');
  print(TomPth.basename(libDir)); // lib

  final env = TomEnv.load();                 // reads .env + process env
  final user = TomEnv.get('USER', 'nobody'); // with default
  print(user);
}

Driving the reflection generator

ReflectionGeneratorRunner wraps the reflection generator so build tools can regenerate a project's reflection data programmatically:

import 'package:tom_build/tom_build.dart';

Future<void> main() async {
  final runner = ReflectionGeneratorRunner(
    '/path/to/workspace/some_project',
    workspacePath: '/path/to/workspace',
  );

  final result = await runner.generate(target: 'lib/', all: true);
  print(result.success); // true
  if (!result.success) {
    print(result.error);
  }
}

Use runner.build() instead to honour the project's build.yaml configuration.

---

Architecture

The package is organised around the four concerns introduced above. The analyzer is the producer; everything else either reads what it produced or operates alongside it.

                         tom_workspace.yaml
                         tom_project.yaml (per project)
                                 │
                                 ▼
   ┌──────────────────────────────────────────────────────┐
   │                  WorkspaceAnalyzer                     │
   │  scan ─► detect nature ─► resolve build order ─►       │
   │  collect capabilities ─► emit metadata                 │
   └───────────────────────────┬──────────────────────────┘
                               │ writes
                               ▼
                  .tom_metadata/tom_master.yaml
                               │ read by
              ┌────────────────┼─────────────────┐
              ▼                ▼                  ▼
        WorkspaceInfo     ToolContext        File object model
        (typed view)      (singleton +       (WorkspaceParser →
                          platform info)      TomMaster/TomProject)
              │                │                  │
              └────────────────┴──────────────────┘
                               │ consumed by
                               ▼
              buildkit · testkit · issuekit · tom CLI

      Scripting helpers (TomShell/TomFs/TomGlob/…) run alongside,
      inside D4rt build scripts.

Key types

TypeResponsibility
WorkspaceAnalyzer Scans a workspace and writes tom_master.yaml; the producer of all metadata.
AnalyzerOptions Controls analysis ( includeTestProjects ); presets production / all .
ProjectInfo / PartInfo / ModuleInfo The analyzer's in-memory model of a discovered project and its sub-structure.
WorkspaceInfo Typed reader over the generated metadata ( buildOrder , projects , groups ).
ToolContext Process-wide cache of WorkspaceInfo + PlatformInfo ; load / current / reload .
PlatformInfo OS / CPU-architecture detection and cross-compile target derivation.
WorkspaceParser Parses raw YAML config into the TomMaster configuration model.
TomWorkspace / TomMaster / TomProject The configuration object model (modes, actions, pipelines, project types).
TomContextThe global tom object exposed to D4rt scripts.
TomShell / TomFs / TomGlob / TomText / TomPth / TomEnv Static scripting helpers for build scripts.
ReflectionGeneratorRunner Programmatic front end to the reflection generator.

---

Ecosystem

tom_build sits below the CLI tools and above the core Tom packages. It is the analysis engine the devops toolchain is built on, while staying free of any dependency on the CLI layer itself.

              tom CLI · buildkit · testkit · issuekit   (tom_build_cli + kits)
                                 │ read metadata via
                                 ▼
                            ┌──────────┐
                            │ tom_build│   ← you are here
                            └────┬─────┘
                                 │ builds on
        ┌──────────────┬─────────┼──────────────┬──────────────────┐
        ▼              ▼         ▼               ▼                  ▼
  tom_core_kernel  tom_core   tom_dist_     tom_process_      analyzer /
                   _server    ledger        monitor          dart_style / yaml

The shared CLI framework — tom_build_base — lives in the basics layer (tom_ai/basics/tom_build_base). tom_build provides workspace understanding; tom_build_base provides the CLI plumbing (arg parsing, help, traversal, pipelines). The tools combine the two.

---

Further documentation

In-package guides under doc/:

DocumentWhat's there
doc/tom_user_reference.md Quick reference for the Tom workspace build tool — the everyday command surface.
doc/tom_tool_specification.md Comprehensive specification of the Tom CLI build and management model.
doc/placeholders_d4rt_guide.md The placeholder syntax and D4rt scripting integration, with implementation detail.
doc/restructuring.md Package-restructuring analysis and rationale for the current module layout.

Related packages (don't duplicate — follow the link):

PackageRelationship
tom_build_cli The tom command surface; the CLI layer that drives tom_build.
tom_build_kit The buildkit orchestrator that reads tom_master.yaml to run pipelines.
tom_build_base The shared CLI / build framework every Tom tool builds on.
Tom DevOps map The repository-level index for the whole devops toolchain.

---

Status

  • Version: 1.0.0 (publish_to: none — workspace-internal)
  • SDK: Dart ^3.10.4
  • Tests: 256 tests across test/analyzer, test/scripting, test/tom and

test/file_structure. - Binary: workspace_analyzer.

---

License

See ../LICENSE.md; each package in this repository carries its own license terms.