avd_manager 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/FUNDING.yml +3 -0
- package/.github/workflows/build-release.yml +103 -0
- package/.github/workflows/ci.yml +32 -0
- package/.versionrc.json +15 -0
- package/CHANGELOG.md +9 -0
- package/LICENSE +21 -0
- package/README.md +270 -0
- package/analysis_options.yaml +30 -0
- package/bin/avdm.dart +176 -0
- package/docs/.nojekyll +0 -0
- package/docs/404.html +28 -0
- package/docs/README.md +171 -0
- package/docs/_coverpage.md +8 -0
- package/docs/_sidebar.md +15 -0
- package/docs/assets/404.png +0 -0
- package/docs/assets/avdmbanner.png +0 -0
- package/docs/assets/badges.png +0 -0
- package/docs/assets/banner-light.png +0 -0
- package/docs/assets/cover.png +0 -0
- package/docs/assets/favicon.png +0 -0
- package/docs/assets/logo.png +0 -0
- package/docs/commands/create.md +24 -0
- package/docs/commands/delete.md +18 -0
- package/docs/commands/launch.md +17 -0
- package/docs/commands/list.md +32 -0
- package/docs/getting-started.md +135 -0
- package/docs/index.html +105 -0
- package/docs/theme.css +99 -0
- package/example/bin/example.dart +15 -0
- package/lib/avd_utils.dart +186 -0
- package/lib/commands/create.dart +86 -0
- package/lib/commands/delete.dart +31 -0
- package/lib/commands/launch.dart +68 -0
- package/lib/commands/list.dart +183 -0
- package/lib/src/version.dart +37 -0
- package/npm/LICENSE +21 -0
- package/npm/README.md +97 -0
- package/npm/bin/avdm-linux +0 -0
- package/npm/bin/avdm-macos +0 -0
- package/npm/bin/avdm-windows.exe +0 -0
- package/npm/index.js +16 -0
- package/npm/package.json +18 -0
- package/package.json +16 -0
- package/pubspec.yaml +28 -0
- package/scripts/debug_list_devices.dart +15 -0
- package/scripts/sync-versions.js +13 -0
- package/test/create_command_test.dart +38 -0
- package/test/list_avds_test.dart +76 -0
- package/test/utils_test.dart +52 -0
package/npm/README.md
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# AVD Manager CLI
|
|
2
|
+
|
|
3
|
+
Welcome to **AVD Manager CLI** — a simple and efficient command-line tool for managing Android Virtual Devices (AVDs) directly from your terminal.
|
|
4
|
+
|
|
5
|
+
This quick-start guide will help you install, configure, and use the CLI in just a few steps.
|
|
6
|
+
|
|
7
|
+
## 🧩 Prerequisites
|
|
8
|
+
|
|
9
|
+
Before you begin, make sure you have:
|
|
10
|
+
|
|
11
|
+
- **Android SDK** installed
|
|
12
|
+
- **Java JDK 11+**
|
|
13
|
+
- **Android SDK tools** (`avdmanager`, `sdkmanager`) available in your PATH
|
|
14
|
+
- **Node.js** (if installing via npm)
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
You can install AVD Manager CLI globally using npm:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install -g avd-manager-cli
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
or
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npm i avd-manager-cli
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Or clone the repository manually:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
git clone https://github.com/Tdbo21/avd_manager.git
|
|
34
|
+
cd avd_manager
|
|
35
|
+
npm install
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## First Run
|
|
39
|
+
|
|
40
|
+
After installation, verify the CLI is working:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
avdm --help
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
You should see a list of available commands and their usage.
|
|
47
|
+
|
|
48
|
+
## 🧭 Common Commands
|
|
49
|
+
|
|
50
|
+
| Command | Description |
|
|
51
|
+
| -------------------------------------------------------- | ------------------------ |
|
|
52
|
+
| `avdm `list | Lists all available AVDs |
|
|
53
|
+
| `avdm `create `Pixel_API_35 `--device `pixel `--api `35` | Creates a new AVD |
|
|
54
|
+
| `avdm `delete `Pixel_API_35` | Deletes an existing AVD |
|
|
55
|
+
| `avdm `launch `Pixel_API_35` | Launches an existing AVD |
|
|
56
|
+
|
|
57
|
+
## 🧪 Example Usage Workflow
|
|
58
|
+
|
|
59
|
+
List existing AVDs
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
avdm list
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Create a new AVD
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
avdm create Pixel_API_35 --device pixel --api 35
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Delete an AVD
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
avdm delete Pixel_API_35
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Launch an AVD
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
avdm launch Pixel_API_35
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## 🧰 Troubleshooting
|
|
84
|
+
|
|
85
|
+
If you encounter issues:
|
|
86
|
+
|
|
87
|
+
- Ensure your Android SDK path is correctly set
|
|
88
|
+
- Check permissions for the .android directory
|
|
89
|
+
|
|
90
|
+
## 🧩 Next Steps
|
|
91
|
+
|
|
92
|
+
- Visit the GitHub Repository - [](https://github.com/Tdebo21/avd_manager)
|
|
93
|
+
- Contribute or open issues to improve the tool
|
|
94
|
+
|
|
95
|
+
## License
|
|
96
|
+
|
|
97
|
+
MIT
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/npm/index.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const os = require("os");
|
|
3
|
+
const path = require("path");
|
|
4
|
+
const { spawn } = require("child_process");
|
|
5
|
+
|
|
6
|
+
const platform = os.platform();
|
|
7
|
+
let binary = "";
|
|
8
|
+
|
|
9
|
+
if (platform === "darwin") binary = "avdm-macos";
|
|
10
|
+
else if (platform === "win32") binary = "avdm-win.exe";
|
|
11
|
+
else binary = "avdm-linux";
|
|
12
|
+
|
|
13
|
+
const binPath = path.join(__dirname, "bin", binary);
|
|
14
|
+
|
|
15
|
+
const child = spawn(binPath, process.argv.slice(2), { stdio: "inherit" });
|
|
16
|
+
child.on("exit", (code) => process.exit(code));
|
package/npm/package.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "avd-manager-cli",
|
|
3
|
+
"version": "1.0.3",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"description": "A command-line tool to manage Android Virtual Devices (AVDs) with ease.",
|
|
6
|
+
"bin": {
|
|
7
|
+
"avdm": "index.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"index.js",
|
|
11
|
+
"bin/"
|
|
12
|
+
],
|
|
13
|
+
"os": [
|
|
14
|
+
"darwin",
|
|
15
|
+
"linux",
|
|
16
|
+
"win32"
|
|
17
|
+
]
|
|
18
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "avd_manager",
|
|
3
|
+
"version": "1.0.4",
|
|
4
|
+
"description": "A Dart CLI tool for AVD management",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"release": "standard-version",
|
|
7
|
+
"release:minor": "standard-version --release-as minor",
|
|
8
|
+
"release:major": "standard-version --release-as major",
|
|
9
|
+
"release:dry-run": "standard-version --dry-run",
|
|
10
|
+
"version": "node scripts/sync-versions.js && git add pubspec.yaml",
|
|
11
|
+
"postversion": "git push && git push --tags"
|
|
12
|
+
},
|
|
13
|
+
"devDependencies": {
|
|
14
|
+
"standard-version": "^9.5.0"
|
|
15
|
+
}
|
|
16
|
+
}
|
package/pubspec.yaml
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
name: avd_manager
|
|
2
|
+
description:
|
|
3
|
+
A lightweight CLI tool to create, patch, launch, delete, list, sort, and filter Android Virtual Devices (AVDs).
|
|
4
|
+
Like Android Studio's AVD Manager, but in your terminal.
|
|
5
|
+
|
|
6
|
+
version: 1.0.4 # Change from 1.0.2 to 1.0.4
|
|
7
|
+
|
|
8
|
+
# author: Tdebo21
|
|
9
|
+
repository: https://github.com/Tdebo21/avd_manager
|
|
10
|
+
homepage: https://Tdebo21.github.io/avd_manager
|
|
11
|
+
issue_tracker: https://github.com/Tdebo21/avd_manager/
|
|
12
|
+
documentation: https://github.com/Tdebo21/avd_manager
|
|
13
|
+
|
|
14
|
+
environment:
|
|
15
|
+
sdk: ">=3.0.0 <4.0.0"
|
|
16
|
+
|
|
17
|
+
dependencies:
|
|
18
|
+
process_run: ^1.0.1
|
|
19
|
+
path: ^1.9.0
|
|
20
|
+
args: ^2.5.0
|
|
21
|
+
yaml: ^3.1.0
|
|
22
|
+
|
|
23
|
+
executables:
|
|
24
|
+
avdm: avdm # Refers to bin/avdm.dart
|
|
25
|
+
|
|
26
|
+
dev_dependencies:
|
|
27
|
+
lints: ^6.0.0
|
|
28
|
+
test: ^1.24.0
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import 'package:avd_manager/avd_utils.dart';
|
|
2
|
+
|
|
3
|
+
Future<void> main() async {
|
|
4
|
+
final result = await runAvdManager(['list', 'device']);
|
|
5
|
+
print('exit=${result.exitCode}');
|
|
6
|
+
print('stdout=<<${result.stdout}>>');
|
|
7
|
+
print('stderr=<<${result.stderr}>>');
|
|
8
|
+
final regex = RegExp(r'id: \d+ or "(.*?)"');
|
|
9
|
+
for (final line in result.stdout.toString().split('\n')) {
|
|
10
|
+
final match = regex.firstMatch(line);
|
|
11
|
+
if (match != null) {
|
|
12
|
+
print('MATCH: ${match.group(1)}');
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const fs = require("fs");
|
|
2
|
+
const path = require("path");
|
|
3
|
+
|
|
4
|
+
// Read version from package.json
|
|
5
|
+
const packageJson = JSON.parse(fs.readFileSync("package.json", "utf8"));
|
|
6
|
+
const version = packageJson.version;
|
|
7
|
+
|
|
8
|
+
// Update pubspec.yaml
|
|
9
|
+
let pubspec = fs.readFileSync("pubspec.yaml", "utf8");
|
|
10
|
+
pubspec = pubspec.replace(/^version: .+$/m, `version: ${version}`);
|
|
11
|
+
fs.writeFileSync("pubspec.yaml", pubspec);
|
|
12
|
+
|
|
13
|
+
console.log(`✓ Synced version to ${version} in pubspec.yaml`);
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// test/create_command_test.dart
|
|
2
|
+
|
|
3
|
+
import 'package:test/test.dart';
|
|
4
|
+
import 'package:args/args.dart';
|
|
5
|
+
|
|
6
|
+
void main() {
|
|
7
|
+
test('create command has required options', () {
|
|
8
|
+
final parser = ArgParser()
|
|
9
|
+
..addFlag('help', abbr: 'h', negatable: false, help: 'Show usage')
|
|
10
|
+
..addCommand(
|
|
11
|
+
'create',
|
|
12
|
+
ArgParser()
|
|
13
|
+
..addOption('device', help: 'Device name (e.g. "pixel")')
|
|
14
|
+
..addOption('api', help: 'API level (e.g. 28)')
|
|
15
|
+
..addOption('abi',
|
|
16
|
+
help:
|
|
17
|
+
'ABI for the system image (e.g. x86, x86_64, arm64-v8a)'));
|
|
18
|
+
|
|
19
|
+
// Simulate running: `avd_manager create --device TestDevice --api android-33 --abi arm64-v8a`
|
|
20
|
+
final results = parser.parse([
|
|
21
|
+
'create',
|
|
22
|
+
'--device',
|
|
23
|
+
'TestDevice',
|
|
24
|
+
'--api',
|
|
25
|
+
'android-33',
|
|
26
|
+
'--abi',
|
|
27
|
+
'arm64-v8a'
|
|
28
|
+
]);
|
|
29
|
+
|
|
30
|
+
final command = results.command;
|
|
31
|
+
|
|
32
|
+
expect(command, isNotNull);
|
|
33
|
+
expect(command!.name, equals('create'));
|
|
34
|
+
expect(command['device'], equals('TestDevice'));
|
|
35
|
+
expect(command['api'], equals('android-33'));
|
|
36
|
+
expect(command['abi'], equals('arm64-v8a'));
|
|
37
|
+
});
|
|
38
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
// test/list_avds_test.dart
|
|
2
|
+
|
|
3
|
+
import 'package:test/test.dart';
|
|
4
|
+
import 'package:args/command_runner.dart';
|
|
5
|
+
import 'package:avd_manager/commands/list.dart';
|
|
6
|
+
import 'dart:async';
|
|
7
|
+
|
|
8
|
+
class ListCommand extends Command {
|
|
9
|
+
@override
|
|
10
|
+
final name = 'list';
|
|
11
|
+
@override
|
|
12
|
+
final description = 'Lists available AVDs.';
|
|
13
|
+
|
|
14
|
+
@override
|
|
15
|
+
void run() {
|
|
16
|
+
print('Listing all AVDs...');
|
|
17
|
+
// Simulate list output
|
|
18
|
+
print(' - pixel (API 33)');
|
|
19
|
+
print(' - nexus (API 30)');
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
void main() {
|
|
24
|
+
group('ListCommand', () {
|
|
25
|
+
test('prints list of AVDs', () async {
|
|
26
|
+
final runner = CommandRunner('avd_manager', 'Test CLI')
|
|
27
|
+
..addCommand(ListCommand());
|
|
28
|
+
|
|
29
|
+
final printLogs = <String>[];
|
|
30
|
+
final specPrint = ZoneSpecification(
|
|
31
|
+
print: (self, parent, zone, line) {
|
|
32
|
+
printLogs.add(line);
|
|
33
|
+
},
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
await Zone.current.fork(specification: specPrint).run(() async {
|
|
37
|
+
await runner.run(['list']);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
expect(printLogs, contains('Listing all AVDs...'));
|
|
41
|
+
expect(printLogs.any((line) => line.contains('pixel')), isTrue);
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
group('parseSize', () {
|
|
46
|
+
test('parses GB correctly', () {
|
|
47
|
+
expect(parseSize('2GB'), equals(2 * 1024 * 1024 * 1024));
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
test('parses MB correctly', () {
|
|
51
|
+
expect(parseSize('512MB'), equals(512 * 1024 * 1024));
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test('throws on invalid input', () {
|
|
55
|
+
expect(() => parseSize('0'), throwsA(isA<FormatException>()));
|
|
56
|
+
expect(() => parseSize('-100MB'), throwsA(isA<FormatException>()));
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
test('throws on invalid unit', () {
|
|
60
|
+
expect(() => parseSize('100Z'), throwsA(isA<FormatException>()));
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
test('throws on empty string', () {
|
|
64
|
+
expect(() => parseSize(''), throwsA(isA<FormatException>()));
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
group('formatSize', () {
|
|
68
|
+
test('formats size in GB', () {
|
|
69
|
+
expect(formatSize(3 * 1024 * 1024 * 1024), contains('3.00 GB'));
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
test('formats size in MB', () {
|
|
73
|
+
expect(formatSize(700 * 1024 * 1024), contains('700.00 MB'));
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import 'package:test/test.dart';
|
|
2
|
+
import 'package:avd_manager/avd_utils.dart';
|
|
3
|
+
|
|
4
|
+
void main() {
|
|
5
|
+
group('arg parser', () {
|
|
6
|
+
test('parses list args correctly', () {
|
|
7
|
+
final args = parseArguments(['list', '--sort', 'size']);
|
|
8
|
+
expect(args['sort'], equals('size'));
|
|
9
|
+
expect(args['min-size'], equals('0'));
|
|
10
|
+
expect(args.containsKey('command'), isFalse);
|
|
11
|
+
expect(args['name'], isNull);
|
|
12
|
+
expect(args['min-size'], isNotNull);
|
|
13
|
+
expect(args['list'], isNull);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
test('returns null on empty args, and correct values on populated args',
|
|
17
|
+
() {
|
|
18
|
+
final args = parseArguments([]);
|
|
19
|
+
expect(args, isA<Map<String, String>>());
|
|
20
|
+
expect(args.length, equals(2));
|
|
21
|
+
expect(args.containsKey('sort'), isTrue);
|
|
22
|
+
expect(args.containsKey('min-size'), isTrue);
|
|
23
|
+
expect(args['sort'], equals('name'));
|
|
24
|
+
expect(args['min-size'], equals('0'));
|
|
25
|
+
expect(args['command'], isNull);
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
// Function to format size in bytes to a human-readable string
|
|
30
|
+
// ignore: no_leading_underscores_for_local_identifiers
|
|
31
|
+
String _formatSize(int bytes) {
|
|
32
|
+
if (bytes < 1024) return '$bytes B';
|
|
33
|
+
final kb = bytes / 1024;
|
|
34
|
+
if (kb < 1024) return '${kb.toStringAsFixed(1)} KB';
|
|
35
|
+
final mb = kb / 1024;
|
|
36
|
+
if (mb < 1024) return '${mb.toStringAsFixed(1)} MB';
|
|
37
|
+
final gb = mb / 1024;
|
|
38
|
+
return '${gb.toStringAsFixed(1)} GB';
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
group('formatSize', () {
|
|
42
|
+
test('formats bytes correctly', () {
|
|
43
|
+
expect(_formatSize(500), equals('500 B'));
|
|
44
|
+
expect(_formatSize(1024), equals('1.0 KB'));
|
|
45
|
+
expect(_formatSize(1536), equals('1.5 KB'));
|
|
46
|
+
expect(_formatSize(1048576), equals('1.0 MB'));
|
|
47
|
+
expect(_formatSize(1572864), equals('1.5 MB'));
|
|
48
|
+
expect(_formatSize(1073741824), equals('1.0 GB'));
|
|
49
|
+
expect(_formatSize(1610612736), equals('1.5 GB'));
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
}
|