5.3 KiB
5.3 KiB
OTO CLI – Guide for AI Assistants
Project Overview
OTO CLI is a Dart command-line tool that executes build/deploy pipelines defined in YAML files. It integrates with Jenkins, runs local test builds, and supports a scheduler mode.
Execution Flow
bin/main.dart
└── Application (singleton)
└── DataComposer ← parses YAML + Jenkins env
└── Pipeline
└── Command.byType(CommandType) → Command.execute(DataCommand)
bin/main.dart– Entry point. Registers three CLI commands:template,exe,scheduler.lib/cli/commands/command_exe.dart– Parses CLI flags (-jJenkins,-ttest,-ffile path) and callsApplication.build().lib/oto/application.dart– Singleton. Ownspropertymap,commonData,commandStates. CallsregisterAllCommands()then runs the pipeline.lib/oto/core/data_composer.dart– Reads YAML and Jenkins env into structured data.lib/oto/pipeline/pipeline.dart– IteratesDataCommandlist and dispatches toCommand.byType().lib/oto/commands/command_registry.dart– Single place where allCommandType → Commandmappings are registered.
BuildType Enum
Defined in lib/oto/application.dart:
| Value | Description |
|---|---|
jenkins |
CI mode – reads workspace and env from Jenkins environment variables |
test |
Local test mode – uses hardcoded test data |
file |
Reads pipeline YAML from a local file path |
scheduler |
Scheduler daemon mode |
Tag System (lib/oto/core/tag_system.dart)
Tags are resolved inside YAML values at runtime.
Read tag: <!namespace.key>
Substitutes a value from the runtime store.
param:
workspace: <!property.workspace> # flat property access
version: <!property.build.version> # nested property access
state: <!state.myCommandId> # command state (ready/progress/complete)
- If the tag occupies the entire string, the original type is returned (e.g. a List stays a List).
- If the tag is embedded in a string, it is converted via
toString().
Write tag: <@namespace.key>
Stores the command result back into a property.
param:
set-version: <@property.appVersion> # saves result into property["appVersion"]
Used via Command.setProperty() / TagSystem.setPropertyValue().
Adding a New Command
- Define data model in the appropriate
lib/oto/data/*_data.dartfile, extendingDataParam. - Add enum value to
CommandTypeinlib/oto/commands/command.dart. - Implement command class extending
Commandwithexecute(DataCommand). - Register in
lib/oto/commands/command_registry.dart. - Run
dart run build_runner buildif you added a new@JsonSerializableclass.
Key Directory Structure
lib/
├── bin/main.dart # entry point
├── cli/commands/ # CLI-layer commands (exe, template, scheduler)
└── oto/
├── application.dart # singleton orchestrator, BuildType enum
├── commands/
│ ├── command.dart # Command base class, CommandType enum
│ ├── command_registry.dart # all command registrations
│ ├── build/ # iOS/Flutter/Dart/MSBuild build commands
│ ├── file/ # file operations (copy, rename, delete, zip…)
│ ├── git/ # git commands
│ ├── infra/ # FTP, SMB
│ ├── notification/ # Slack, Mattermost
│ ├── process/ # process management
│ └── util/ # timers, JSON, string utils
├── core/
│ ├── tag_system.dart # tag substitution engine
│ ├── data_composer.dart # YAML + env → structured data
│ └── defined_data.dart # built-in YAML templates
├── data/
│ ├── base_data.dart # DataParam (base), DataCommon (Jenkins env)
│ ├── command_data.dart # DataCommand (re-exports all data types)
│ └── *_data.dart # domain-specific data models
└── pipeline/
└── pipeline.dart # command dispatch loop
Data Model Conventions
- All command parameters extend
DataParam(lib/oto/data/base_data.dart). - JSON serialization uses
json_annotation. Generated files are*.g.dart. *.g.dartfiles are normally generated bydart run build_runner buildbut can be edited directly when needed.DataCommonholds Jenkins environment data (workspace, job name, build number, etc.).DataCommand(incommand_data.dart) is the unified container passed to everyCommand.execute().
Error Handling
Application.build()inapplication.dartusescatch (e, stacktrace)(noton Exception) to also catchErrorsubtypes such asTypeError.- On error,
exit(10)is called to signal failure to the parent process.
Workspace Resolution (Command base class)
getWorkspace() in command.dart resolves in this order:
workspacefield on the command's data modelproperty['workspace']in the global property mapcommonData.workspace(Jenkins environment)