119 lines
5.3 KiB
Markdown
119 lines
5.3 KiB
Markdown
# 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)
|
||
```
|
||
|
||
1. **`bin/main.dart`** – Entry point. Registers three CLI commands: `template`, `exe`, `scheduler`.
|
||
2. **`lib/cli/commands/command_exe.dart`** – Parses CLI flags (`-j` Jenkins, `-t` test, `-f` file path) and calls `Application.build()`.
|
||
3. **`lib/oto/application.dart`** – Singleton. Owns `property` map, `commonData`, `commandStates`. Calls `registerAllCommands()` then runs the pipeline.
|
||
4. **`lib/oto/core/data_composer.dart`** – Reads YAML and Jenkins env into structured data.
|
||
5. **`lib/oto/pipeline/pipeline.dart`** – Iterates `DataCommand` list and dispatches to `Command.byType()`.
|
||
6. **`lib/oto/commands/command_registry.dart`** – Single place where all `CommandType → Command` mappings 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.
|
||
|
||
```yaml
|
||
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.
|
||
|
||
```yaml
|
||
param:
|
||
set-version: <@property.appVersion> # saves result into property["appVersion"]
|
||
```
|
||
|
||
Used via `Command.setProperty()` / `TagSystem.setPropertyValue()`.
|
||
|
||
## Adding a New Command
|
||
|
||
1. **Define data model** in the appropriate `lib/oto/data/*_data.dart` file, extending `DataParam`.
|
||
2. **Add enum value** to `CommandType` in `lib/oto/commands/command.dart`.
|
||
3. **Implement command class** extending `Command` with `execute(DataCommand)`.
|
||
4. **Register** in `lib/oto/commands/command_registry.dart`.
|
||
5. Run `dart run build_runner build` if you added a new `@JsonSerializable` class.
|
||
|
||
## 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.dart` files are normally generated by `dart run build_runner build` but can be edited directly when needed.
|
||
- `DataCommon` holds Jenkins environment data (workspace, job name, build number, etc.).
|
||
- `DataCommand` (in `command_data.dart`) is the unified container passed to every `Command.execute()`.
|
||
|
||
## Error Handling
|
||
|
||
- `Application.build()` in `application.dart` uses `catch (e, stacktrace)` (not `on Exception`) to also catch `Error` subtypes such as `TypeError`.
|
||
- 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:
|
||
1. `workspace` field on the command's data model
|
||
2. `property['workspace']` in the global property map
|
||
3. `commonData.workspace` (Jenkins environment)
|