Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,9 @@ not supported and fail fast.
## 💻 CLI Usage

```bash
# Show all options
openrom-core --help

# Detect file format and platform
openrom-core --detect game.iso

Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.9.7
3.9.8
34 changes: 29 additions & 5 deletions core/bin/openrom.dart
Original file line number Diff line number Diff line change
Expand Up @@ -185,41 +185,65 @@ ArgParser buildParser() {
negatable: false,
help: 'suppress per-job log output',
)
..addFlag(
'help',
abbr: 'h',
negatable: false,
help: 'show this help message',
)
..addFlag('version', abbr: 'v', negatable: false, help: 'show version');

return parser;
}

void printUsage(ArgParser parser, {bool toStderr = false}) {
final out = toStderr ? stderr : stdout;
out.writeln('OpenROM CLI — Universal ROM Compression Suite');
out.writeln();
out.writeln('Usage: openrom-core [options]');
out.writeln();
out.writeln(parser.usage);
}

Future<void> main(List<String> args) async {
// The Dart VM ignores an `int` returned from `main` (both JIT and AOT), so
// propagate the exit code explicitly.
exitCode = await _runCli(args);
}

Future<int> _runCli(List<String> args) async {
final parser = buildParser();

if (args.isEmpty) {
print('OpenROM CLI — Universal ROM Toolkit\nUsage: openrom [options]');
printUsage(parser);
return 0;
}

// Auto-load installed plugins
await PluginManager.instance.loadInstalledPlugins();

final parser = buildParser();
final ArgResults results;
try {
results = parser.parse(args);
} catch (e) {
stderr.writeln('Error parsing arguments: $e');
printUsage(parser, toStderr: true);
return 2;
}

// `--help` and `--version` exit before any side effects (e.g. loading
// installed plugins) so their output stays clean.
if (results['help'] == true) {
printUsage(parser);
return 0;
}

if (results['version'] == true) {
final version = readAppVersion();
print(version == 'unknown' ? 'OpenROM' : 'OpenROM v$version');
return 0;
}

// Auto-load installed plugins
await PluginManager.instance.loadInstalledPlugins();

final isJson = results['json'] == true;

if (results['install-plugin'] != null) {
Expand Down
2 changes: 1 addition & 1 deletion core/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: openrom_core
description: OpenROM Pure Dart Backend Core & Toolkit Library
version: 3.9.7
version: 3.9.8
publish_to: 'none'

environment:
Expand Down
53 changes: 53 additions & 0 deletions core/test/cli_help_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import 'dart:io';

import 'package:test/test.dart';

/// Runs the real CLI entrypoint and captures its output.
ProcessResult _runCli(List<String> args) {
return Process.runSync(
Platform.resolvedExecutable,
['bin/openrom.dart', ...args],
);
}

void main() {
group('CLI --help', () {
test('--help prints usage and exits 0', () {
final r = _runCli(['--help']);
expect(r.exitCode, 0);
final out = r.stdout as String;
expect(out, contains('Usage: openrom-core [options]'));
expect(out, contains('--help'));
expect(out, contains('--input'));
});

test('-h prints usage and exits 0', () {
final r = _runCli(['-h']);
expect(r.exitCode, 0);
expect(r.stdout as String, contains('Usage: openrom-core [options]'));
});

test('no arguments prints usage and exits 0', () {
final r = _runCli([]);
expect(r.exitCode, 0);
expect(r.stdout as String, contains('Usage: openrom-core [options]'));
});

test('unknown option exits 2 with an error and usage on stderr', () {
final r = _runCli(['--not-a-real-option']);
expect(r.exitCode, 2);
expect(r.stderr as String, contains('Error parsing arguments'));
expect(r.stderr as String, contains('Usage: openrom-core [options]'));
});

test('--version exits 0 and prints only the version line', () {
final r = _runCli(['--version']);
expect(r.exitCode, 0);
// Plugin loading must not run for `--version`, so nothing may precede it.
expect(
(r.stdout as String).trim(),
matches(RegExp(r'^OpenROM( v[0-9][0-9.]*)?$')),
);
});
});
}
6 changes: 3 additions & 3 deletions docs/DEVELOPER_ONBOARDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
> wrapped around a pure-Dart backend engine (`openrom-core`) that orchestrates
> native third-party tools (`chdman`, `maxcso`, `xdelta3`, …).

Version at time of writing: **3.9.7** (`VERSION`, `core/pubspec.yaml`,
`gui/pubspec.yaml` = `3.9.7+1`).
Version at time of writing: **3.9.8** (`VERSION`, `core/pubspec.yaml`,
`gui/pubspec.yaml` = `3.9.8+1`).

---

Expand Down Expand Up @@ -528,7 +528,7 @@ At runtime, `main.dart` queries the native library directory over a
`config.getToolPath()` returns `lib<tool>.so` inside that dir — this is the only
platform where tools are shared libraries rather than executables.

Android is **omitted from the v3.9.7 release**. The `build-android` job is guarded
Android is **omitted from the v3.9.8 release**. The `build-android` job is guarded
so the `release: published` trigger no longer fires it; re-enable by dispatching
`Android.yml` manually or setting the repository variable
`ENABLE_ANDROID_RELEASE=true`.
Expand Down
4 changes: 2 additions & 2 deletions gui/lib/utils/app_version.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ import 'package:openrom_core/openrom_core.dart';

class AppVersion {
/// Default fallback version matching current release tag.
static const String fallback = '3.9.7';
static const String fallback = '3.9.8';

/// Returns the resolved app version.
/// Priority:
/// 1. Compile-time environment variable (--dart-define=APP_VERSION=x.y.z)
/// 2. Version file read via `readAppVersion()` from `openrom_core`
/// 3. Fallback string ('3.9.7')
/// 3. Fallback string ('3.9.8')
static String get current {
const definedVersion = String.fromEnvironment('APP_VERSION');
if (definedVersion.isNotEmpty) {
Expand Down
2 changes: 1 addition & 1 deletion gui/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ packages:
path: "../core"
relative: true
source: path
version: "3.9.7"
version: "3.9.8"
package_config:
dependency: transitive
description:
Expand Down
4 changes: 2 additions & 2 deletions gui/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: gui
description: OpenROM — Universal ROM Compression Suite Desktop App
publish_to: 'none'
version: 3.9.7+1
version: 3.9.8+1

environment:
sdk: '>=3.0.0 <4.0.0'
Expand All @@ -23,7 +23,7 @@ dependencies:
path_provider: ^2.0.0
openrom_core:
path: ../core
version: 3.9.7
version: 3.9.8

dev_dependencies:
flutter_test:
Expand Down
2 changes: 1 addition & 1 deletion gui/test/app_version_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ void main() {
test('AppVersion.current returns dynamic current version string', () {
final version = AppVersion.current;
expect(version, isNotEmpty);
expect(version, equals('3.9.7'));
expect(version, equals('3.9.8'));
});
});
}
Loading