Status
Accepted
Context
The Codexis build system currently passes build/session configuration as loose maps, with OutputPaths and other settings scattered across the build context. This leads to inconsistencies, path confusion, and bugs, especially as the system grows and more formats and features are added.
Problem
- No single source of truth for build/session-wide configuration.
- OutputPaths is used, but not always propagated or enforced consistently.
- Context is often a map, making it easy to miss or mutate keys.
- Testability and maintainability suffer due to lack of structure.
Decision
- Introduce a
Codexis.BuildConfigstruct that encapsulates all build/session configuration:output_paths :: OutputPaths.t()orchestratorbook_nameoptions- Any other session-wide settings
- Refactor all pipelines, builders, and stages to accept and propagate this struct instead of loose maps.
- Enforce that all path and directory logic uses
output_pathsfrom this struct. - Update documentation and tests to reflect the new pattern.
Consequences
- Stronger typing and structure for build context.
- Consistent path and directory handling across all formats and stages.
- Easier to override settings for test builds (e.g., output_root).
- Improved maintainability and testability.
- Requires a coordinated refactor of all build-related modules.
Migration Strategy
- Define the
Codexis.BuildConfigstruct in a central module. - Update all pipelines, builders, and stages to accept and use this struct.
- Update tests and documentation.
- Deprecate and remove legacy context map usage.
Related Decisions
- ADR-0016: Centralized Path Configuration
- ADR-0024: Pipeline Architecture
- ADR-0030: Elixir CLI Tools Architecture
BuildConfig Struct Documentation
Overview
The Codexis.BuildConfig struct is the central configuration object for all Codexis build sessions. It encapsulates all necessary context and settings for a build, ensuring consistency and type safety across pipelines, builders, and stages.
Fields
output_paths(Codexis.Core.OutputPaths.t()): All output path and directory logic for the build session. Required.orchestrator(Codexis.BuildManager.BuildOrchestrator.t()): The orchestrator struct managing the build lifecycle. Required.book_name(String.t()): The canonical book name, used for file naming and output. Required.options(keyword() | map(), default:[]): Builder/pipeline options, such as feature flags or format-specific settings.environment(map(), default:%{}): Session-wide environment variables or config overrides.
Example Usage
alias Codexis.Core.OutputPaths
alias Codexis.BuildManager.BuildOrchestrator
alias Codexis.BuildConfig
# Assume orchestrator is already created
output_paths = OutputPaths.new(orchestrator, "my_book", ".", output_root: "test_output")
build_config = BuildConfig.new(
output_paths,
orchestrator,
"my_book",
options: [use_mathjax: true],
environment: %{env: "test"}
)
Access Patterns
- Always access configuration via the struct fields, e.g.:
config.output_pathsconfig.options[:use_mathjax]config.environment["env"]
- Do not mutate the struct; create a new one if changes are needed.
Validation
Use BuildConfig.validate/1 to check for required fields and types:
case BuildConfig.validate(build_config) do
{:ok, config} -> ...
{:error, reason} -> ...
end
Migration Notes
- All pipelines, builders, and stages must now accept a
BuildConfigstruct instead of loose maps or individual parameters. - See the migration guide in
docs/migration/for before/after code and upgrade steps.