ADR: OmegaT CLI Modernization with PicoCLI¶
Status¶
Accepted - Implementation in progress
Context¶
The existing OmegaT command line interface suffered from several architectural and usability issues:
Problems with Legacy CLI¶
Complex nested options: Deep nesting made the CLI difficult to use and document
Monolithic architecture: All CLI logic was centralized in the
CLIParametersclass andMainclassPoor documentation: Help text was stored as a single large message in
Bundle.properties, causing translation and maintenance issuesLimited extensibility: No mechanism for plugins to add custom CLI commands
Inconsistent syntax: Mixed patterns that didn’t follow modern CLI conventions
User Experience Issues¶
PDF manual became unreadable due to excessive indentation from nested options
Help system was monolithic and difficult to navigate
No hierarchical help structure (e.g.,
--help <command>)Inconsistent command patterns across different operations
Decision¶
We decided to modernize the OmegaT CLI by adopting PicoCLI as the command-line parsing library and restructuring the entire CLI architecture.
Key Architectural Changes¶
1. PicoCLI Integration¶
Replace custom
CLIParametersclass with PicoCLI-based command structureImplement standard command-line patterns with proper sub-command support
Leverage PicoCLI’s automatic help generation and validation
2. Modular Command Architecture¶
Create dedicated command classes in
org.omegat.clipackageEach command becomes a self-contained class with its own logic and parameters
Each command shares mixin class
Parametersfor common options.Help messages are i18n-ed with Prameters.properties resource bundles.
3. New Command Structure¶
OmegaT [COMMAND] [SUB-COMMAND] [OPTIONS] [ARGUMENTS]
Supported Commands:
start- Launch OmegaT GUI (default when no command specified)team- Team project management utilitiesstats- Statistics generationtranslate- Console translation modealign- Document alignment utilities(CLI/GUI)pseudo- Pseudo TMX generation
4. Help example¶
$ ./OmegaT --help
Usage: omegat [-hV] [--disable-location-save] [--disable-project-locking]
[--no-team] [--alignDir=<path>] [--config-dir=<path>]
[--config-file=<path>] [--mode=<console-mode-name>]
[--output-file=<stats-output-file>] [--pseudotranslatetmx=<path>]
[--pseudotranslatetype=<equal_or_empty>]
[--resource-bundle=<bundle>] [--source-pattern=<sourcePattern>]
[--stats-type=<xml_or_text_or_json>] [-D=<String=String>]...
[<project>] [COMMAND]
OmegaT free translation memory application.
[<project>]
--alignDir=<path> The folder containing the translated files.
--config-dir=<path> The folder used to read or write OmegaT
configuration files.
--config-file=<path> A Java .properties file from which to load default
settings.
-D=<String=String>
--disable-location-save
Do not remember the last folder opened in the file
picker.
--disable-project-locking
Do not attempt to lock the omegat.project file.
-h, --help Show this help message and exit.
--mode=<console-mode-name>
Console mode name: console-translate,
console-createpseudotranslatetmx, console-align,
or console-stats
--no-team Disable team project functionality.
--output-file=<stats-output-file>
Prints to the specified file, or to standard
output
if no file is given or the option is not used.
--pseudotranslatetmx=<path>
The output pseudotranslated TMX file.
--pseudotranslatetype=<equal_or_empty>
What to put in the pseudotranslated TMX.
--resource-bundle=<bundle>
A Java .properties file to use for the interface
text.
--source-pattern=<sourcePattern>
A regex whitelist of source files to process.
--stats-type=<xml_or_text_or_json>
Specifies the output format.
If --stats-type is not specified, the format is
detected from the file extension.
Defaults to xml.
-V, --version Print version information and exit.
Commands:
start Start OmegaT GUI.
align Launch Align Tool.
translate Console translate command.
stats Show translation statistics.
team Team admin utility.
help Display help information about the specified command.
miurahr@miurahr-dragon:~/IdeaProjects/omegat/build/install/OmegaT$ ./OmegaT team init --help
Missing required parameters: '<source>', '<target>'
Usage: omegat team init <source> <target>
Team project tool.
Initialize a minimal team project with the specified languages.
If invoked in a git working tree or svn checkout, the results
will be staged/added.
<source> Source language
<target> Target langauge
$ ./OmegaT team --help
Usage: omegat team [-h] [COMMAND]
Team admin utility.
-h, --help Show this help message and exit.
Commands:
init Team project tool.
Initialize a minimal team project with the specified languages.
If invoked in a git working tree or svn checkout, the results
will be staged/added.
miurahr@miurahr-dragon:~/IdeaProjects/omegat/build/install/OmegaT$ ./OmegaT team
Usage: team [-h] [COMMAND]
-h, --help Show this help message and exit.
Commands:
init
$ ./OmegaT start --help
Usage: omegat start [-h] [--quiet] [--[no-]team] [--verbose]
[--ITokenizer=<tokenizerSource>]
[--ITokenizerTarget=<tokenizerTarget>] [--script=<path>]
[--tag-validation=<tagValidation>] <project>
Start OmegaT GUI.
<project> Project directory
-h, --help Show this help message and exit.
--ITokenizer=<tokenizerSource>
source-language tokenizer to use (overrides project
settings). See OmegaT.jar/META-INF/MANIFEST.MF for
valid values.
--ITokenizerTarget=<tokenizerTarget>
target-language tokenizer to use (overrides project
settings). See OmegaT.jar/META-INF/MANIFEST.MF for
valid values.
--quiet Reduce output to command line stdout.
--script=<path> A script file to execute on project events.
--tag-validation=<tagValidation>
Validate tags. Abort: Exit with an error if tags are
invalid. Warn: Report invalid tags to stdout.
--[no-]team Enable team project functionality[Default: ON].
--verbose Verbose output of command log messages.
Implementation Details¶
Package Structure¶
org.omegat.cli/
├── LegacyParameters.java # Main CLI legacy parameters
├── Parameters.java # Sub command common parameters
├── Common.java # Common operations among sub commands
├── AlignCommand.java # Alignment operations
├── PseudoTranslationCommand.java # Pseudo Translation operations
├── StartCommand.java # GUI startup
├── StatsCommand.java # Statistics generation
└── TeamCommand.java # Team project operations
├── TranslateCommand.java # Console translation
Core Changes¶
Removed Components¶
CLIParametersclass (replaced by PicoCLI structure)Legacy CLI parsing logic in
MainclassMonolithic help text in
Bundle.propertiesDeprecated CLI-related test classes
Added Components¶
PicoCLI dependency integration
Modular command classes with dedicated responsibilities
Runtime preferences for CLI-specific parameters
Enhanced help system with command-specific documentation
Modified Components¶
Mainclass: Streamlined to delegate to PicoCLICoreclass: Removed CLI parameter dependenciesProjectPropertiesDialog: Cleaned up CLI-related codeTest suites: Updated to reflect new CLI structure
Command Implementation Pattern¶
Each command follows a consistent pattern:
@Command(name = "commandname", description = "Command description")
public class ExampleCommand implements Callable<Integer> {
@Parameters(description = "Command parameters")
private List<String> parameters;
@Option(names = {"-o", "--option"}, description = "Option description")
private String option;
@Override
public int call() {
// Command implementation
return 0;
}
}
Runtime Integration¶
Preferences: New CLI parameters stored in
RuntimePreferencesLifecycle: Commands handle their own execution lifecycle
Error Handling: PicoCLI provides standardized error reporting
Validation: Built-in parameter validation and type conversion
Benefits¶
For Users¶
Intuitive syntax: Follows modern CLI conventions (similar to Git)
Better help system: Hierarchical help with
--helpand--help <command>Consistent patterns: Uniform command structure across all operations
Improved documentation: Clear, modular help text
For Developers¶
Modular architecture: Commands are self-contained and testable
Plugin extensibility: Framework ready for plugin-based command extensions
Maintainable code: Separation of concerns between commands
Standard library: Leverages proven PicoCLI patterns and features
For Translators¶
Granular messages: Help text split into manageable, translatable units
Context preservation: Command-specific help maintains proper context
Reduced complexity: Smaller, focused translation units
Migration Strategy¶
Backward Compatibility¶
Legacy command syntax continues to work during transition period
Gradual deprecation of old patterns with clear migration guidance
Existing scripts and integrations remain functional
Rollout Plan¶
Phase 1: Core PicoCLI integration with basic commands
Phase 2: Advanced command features and plugin framework
Phase 3: Legacy CLI deprecation and removal
Testing Strategy¶
Test Coverage¶
Unit tests: Individual command classes with focused test cases
Regression tests: Ensure backward compatibility during transition
Quality Assurance¶
Command parameter validation testing
Error handling and user feedback verification
Performance testing for large project operations
Cross-platform CLI behavior validation
Risks and Mitigations¶
Dependencies¶
Risk: Adding PicoCLI dependency increases application size
Mitigation: PicoCLI is lightweight and provides significant value
Complexity¶
Risk: New architecture might introduce learning curve
Mitigation: Comprehensive documentation and examples provided
Migration¶
Risk: Breaking changes for existing CLI users
Mitigation: Backward compatibility maintained during transition
Future Considerations¶
Plugin System Integration¶
The new CLI architecture provides foundation for:
Plugin-contributed commands
Dynamic command registration
Extensible parameter handling
Advanced Features¶
Command completion support
Configuration file integration
Enhanced scripting capabilities
References¶
Date: 2024-01-30
Authors: Hiroshi Miura, Thomas Cordonnier, Jean-Christophe Helary
Reviewers: OmegaT Development Team
Status: Implementation in Progress