Skip to content

Commit c125d72

Browse files
authored
feature(version): add version command (#2)
1 parent 15e795e commit c125d72

14 files changed

Lines changed: 252 additions & 20 deletions

CHANGELOG.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,13 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8-
## [Unreleased]
8+
## [0.0.2] - 2026-03-16
9+
10+
### Added
11+
12+
- Add version command
13+
14+
## [0.0.1]
915

1016
### Added
1117

@@ -16,7 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1622
- Fix UI layout
1723
- Fix idle message doesn't change when change panel
1824

19-
## [0.0.1]
25+
## [0.0.1] - 2026-03-15
2026

2127
### Added
2228

bin/simutil.dart

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import 'package:nocterm/nocterm.dart';
2-
import 'package:simutil/simutil.dart';
2+
import 'package:simutil/cli/simutil_command_runner.dart';
3+
import 'package:simutil/simutil_app.dart';
34

45
void main(List<String> arguments) {
5-
runApp(
6-
Navigator(
7-
home: SimutilApp(),
8-
),
9-
);
6+
if (arguments.isEmpty) {
7+
runApp(Navigator(home: SimutilApp()));
8+
} else {
9+
SimutilCommandRunner().run(arguments);
10+
}
1011
}

build.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
targets:
2+
$default:
3+
builders:
4+
build_version:
5+
options:
6+
output: lib/utils/version.dart
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import 'package:args/command_runner.dart';
2+
import 'package:mason_logger/mason_logger.dart';
3+
4+
abstract class SimutilCommand extends Command<int> {
5+
SimutilCommand({Logger? logger}) : _logger = logger;
6+
Logger get logger => _logger ??= Logger();
7+
8+
Logger? _logger;
9+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import 'package:simutil/cli/commands/simutil_command.dart';
2+
import 'package:simutil/utils/version.dart';
3+
4+
class VersionCommand extends SimutilCommand {
5+
VersionCommand({super.logger});
6+
7+
@override
8+
String get name => 'version';
9+
10+
@override
11+
String get description => 'Print the current version';
12+
13+
@override
14+
Future<int> run() async {
15+
logger.success('Simutil v$packageVersion');
16+
return 0;
17+
}
18+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import 'package:args/command_runner.dart';
2+
import 'package:mason_logger/mason_logger.dart';
3+
import 'package:simutil/cli/commands/version_command.dart';
4+
5+
class SimutilCommandRunner extends CommandRunner<int> {
6+
SimutilCommandRunner({Logger? logger})
7+
: _logger = logger ?? Logger(),
8+
super(
9+
'simutil',
10+
'An utility TUI application for launching iOS simulators / Android emulators and more',
11+
) {
12+
addCommand(VersionCommand(logger: _logger));
13+
}
14+
15+
final Logger _logger;
16+
}

lib/components/app_header.dart

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import 'package:nocterm/nocterm.dart';
22
import 'package:simutil/components/simutil_icons.dart';
33
import 'package:simutil/components/simutil_theme.dart';
4+
import 'package:simutil/utils/version.dart';
45

56
class AppHeader extends StatelessComponent {
67
const AppHeader({super.key, required this.themeName});
@@ -14,8 +15,11 @@ class AppHeader extends StatelessComponent {
1415
height: 1,
1516
child: Row(
1617
children: [
17-
Text(' ${SimutilIcons.on} SimUtil ', style: st.sectionHeader),
18-
Expanded(child: Text('Theme: $themeName ', style: st.muted)),
18+
Text(
19+
' ${SimutilIcons.on} SimUtil v$packageVersion ',
20+
style: st.sectionHeader,
21+
),
22+
Expanded(child: Text('Theme: $themeName', style: st.muted)),
1923
],
2024
),
2125
);

lib/services/android_device_service.dart

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class AndroidDeviceService implements DeviceService {
3737
}
3838

3939
@override
40-
Future<List<Device>> listDevices() => _listEmulators();
40+
Future<List<Device>> getSimulators() => _listEmulators();
4141

4242
Future<List<Device>> _listEmulators() async {
4343
try {
@@ -238,6 +238,36 @@ class AndroidDeviceService implements DeviceService {
238238
return AdbConnectResult(success: false, message: e.toString());
239239
}
240240
}
241+
242+
@override
243+
Future<List<Device>> getPhysicalDevices() async {
244+
try {
245+
final result = await _exec.run(adbPath, arguments: ['devices']);
246+
if (!result.success) return [];
247+
248+
final devices = result.stdout
249+
.split('\n')
250+
.skip(1)
251+
.map((l) => l.trim())
252+
.where((l) => l.isNotEmpty && l.contains('device'))
253+
.map((l) => l.split('\t').first)
254+
.where((s) => !s.startsWith('emulator-'))
255+
.toList();
256+
257+
return devices.map((serial) {
258+
return Device(
259+
id: serial,
260+
name: serial,
261+
os: Os.android,
262+
type: DeviceType.physical,
263+
platform: 'Android',
264+
state: DeviceState.booted,
265+
);
266+
}).toList();
267+
} catch (e) {
268+
return [];
269+
}
270+
}
241271
}
242272

243273
class AdbConnectResult {

lib/services/device_service.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ import 'package:simutil/models/device.dart';
33
abstract class DeviceService {
44
Future<bool> isAvailable();
55

6-
Future<List<Device>> listDevices();
6+
Future<List<Device>> getPhysicalDevices();
7+
8+
Future<List<Device>> getSimulators();
79

810
Future<void> launchDevice({
911
required String deviceId,

lib/services/ios_device_service.dart

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class IOSDeviceService implements DeviceService {
2828
}
2929

3030
@override
31-
Future<List<Device>> listDevices() async {
31+
Future<List<Device>> getSimulators() async {
3232
if (!Platform.isMacOS) return [];
3333
return _listSimulators();
3434
}
@@ -127,4 +127,10 @@ class IOSDeviceService implements DeviceService {
127127
(m) => '${m[1]} ${m[2]?.replaceAll(' ', '.')}',
128128
);
129129
}
130+
131+
@override
132+
Future<List<Device>> getPhysicalDevices() {
133+
// TODO: implement getPhysicalDevices
134+
throw UnimplementedError();
135+
}
130136
}

0 commit comments

Comments
 (0)