oto/CLAUDE.md

119 lines
5.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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)