droid-cli 1.0.0
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/README.md +268 -0
- package/dist/commands/build.d.ts +12 -0
- package/dist/commands/build.d.ts.map +1 -0
- package/dist/commands/build.js +375 -0
- package/dist/commands/build.js.map +1 -0
- package/dist/commands/device.d.ts +2 -0
- package/dist/commands/device.d.ts.map +1 -0
- package/dist/commands/device.js +177 -0
- package/dist/commands/device.js.map +1 -0
- package/dist/commands/gradle.d.ts +11 -0
- package/dist/commands/gradle.d.ts.map +1 -0
- package/dist/commands/gradle.js +147 -0
- package/dist/commands/gradle.js.map +1 -0
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +231 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/logcat.d.ts +6 -0
- package/dist/commands/logcat.d.ts.map +1 -0
- package/dist/commands/logcat.js +131 -0
- package/dist/commands/logcat.js.map +1 -0
- package/dist/commands/variant.d.ts +3 -0
- package/dist/commands/variant.d.ts.map +1 -0
- package/dist/commands/variant.js +77 -0
- package/dist/commands/variant.js.map +1 -0
- package/dist/config/config-manager.d.ts +33 -0
- package/dist/config/config-manager.d.ts.map +1 -0
- package/dist/config/config-manager.js +219 -0
- package/dist/config/config-manager.js.map +1 -0
- package/dist/config/schema.d.ts +21 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +41 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/core/adb.d.ts +48 -0
- package/dist/core/adb.d.ts.map +1 -0
- package/dist/core/adb.js +431 -0
- package/dist/core/adb.js.map +1 -0
- package/dist/core/android-project.d.ts +25 -0
- package/dist/core/android-project.d.ts.map +1 -0
- package/dist/core/android-project.js +155 -0
- package/dist/core/android-project.js.map +1 -0
- package/dist/core/gradle-wrapper.d.ts +21 -0
- package/dist/core/gradle-wrapper.d.ts.map +1 -0
- package/dist/core/gradle-wrapper.js +221 -0
- package/dist/core/gradle-wrapper.js.map +1 -0
- package/dist/core/terminal.d.ts +20 -0
- package/dist/core/terminal.d.ts.map +1 -0
- package/dist/core/terminal.js +186 -0
- package/dist/core/terminal.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +167 -0
- package/dist/index.js.map +1 -0
- package/dist/ui/interactive-menu.d.ts +2 -0
- package/dist/ui/interactive-menu.d.ts.map +1 -0
- package/dist/ui/interactive-menu.js +272 -0
- package/dist/ui/interactive-menu.js.map +1 -0
- package/dist/ui/logger.d.ts +20 -0
- package/dist/ui/logger.d.ts.map +1 -0
- package/dist/ui/logger.js +59 -0
- package/dist/ui/logger.js.map +1 -0
- package/dist/utils/process.d.ts +53 -0
- package/dist/utils/process.d.ts.map +1 -0
- package/dist/utils/process.js +62 -0
- package/dist/utils/process.js.map +1 -0
- package/dist/utils/validators.d.ts +11 -0
- package/dist/utils/validators.d.ts.map +1 -0
- package/dist/utils/validators.js +84 -0
- package/dist/utils/validators.js.map +1 -0
- package/package.json +54 -0
package/README.md
ADDED
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
# Droid CLI
|
|
2
|
+
|
|
3
|
+
A powerful, interactive CLI tool for Android development that brings the essential features of Android Studio to your terminal. Inspired by Expo CLI, this tool provides fast incremental builds, device management, and debugging without the heavy GUI overhead.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🔨 **Incremental Builds** - Fast builds using Gradle's build cache
|
|
8
|
+
- 📱 **Device Management** - Easy selection and management of emulators and physical devices
|
|
9
|
+
- 🚀 **Smart Emulator Startup** - Automatically offers to start emulators when no devices connected
|
|
10
|
+
- 📋 **Logcat Integration** - Spawns terminal with filtered app logs
|
|
11
|
+
- ⚙️ **Gradle Tasks** - Run common tasks like clean, sync, and custom tasks
|
|
12
|
+
- 🎯 **Interactive Menu** - User-friendly menu system for all operations
|
|
13
|
+
- 🛠️ **Configuration** - Project-specific settings via `droid-cli.json`
|
|
14
|
+
- 🔄 **Auto-detection** - Automatically detects Android projects and devices
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install -g droid-cli
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Prerequisites
|
|
23
|
+
|
|
24
|
+
- **Node.js** >= 14.0.0
|
|
25
|
+
- **Android SDK** with ADB in PATH
|
|
26
|
+
- **Java Development Kit (JDK)**
|
|
27
|
+
- An Android project with Gradle wrapper
|
|
28
|
+
|
|
29
|
+
## Quick Start
|
|
30
|
+
|
|
31
|
+
1. Navigate to your Android project directory
|
|
32
|
+
2. Initialize the CLI configuration:
|
|
33
|
+
```bash
|
|
34
|
+
droid-cli init
|
|
35
|
+
```
|
|
36
|
+
3. Start the interactive menu:
|
|
37
|
+
```bash
|
|
38
|
+
droid-cli
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Commands
|
|
42
|
+
|
|
43
|
+
### Global Options
|
|
44
|
+
|
|
45
|
+
All commands support the `--project` (or `-p`) flag to specify the Android project directory:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
droid-cli --project /path/to/android/project [command]
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
This allows you to run the CLI from anywhere while targeting a specific project.
|
|
52
|
+
|
|
53
|
+
### Interactive Mode
|
|
54
|
+
```bash
|
|
55
|
+
droid-cli [--project <path>]
|
|
56
|
+
```
|
|
57
|
+
Launches the main interactive menu with all available options.
|
|
58
|
+
|
|
59
|
+
### Direct Commands
|
|
60
|
+
|
|
61
|
+
#### Build & Run
|
|
62
|
+
```bash
|
|
63
|
+
droid-cli build [--variant debug|release] [--device device-id] [--project <path>]
|
|
64
|
+
```
|
|
65
|
+
Builds the app and deploys it to the selected device.
|
|
66
|
+
|
|
67
|
+
#### Device Management
|
|
68
|
+
```bash
|
|
69
|
+
droid-cli device [--project <path>]
|
|
70
|
+
```
|
|
71
|
+
List and select target devices/emulators.
|
|
72
|
+
|
|
73
|
+
#### Logcat
|
|
74
|
+
```bash
|
|
75
|
+
droid-cli logcat [--device device-id] [--project <path>]
|
|
76
|
+
```
|
|
77
|
+
Opens logcat in a new terminal window, filtered for your app.
|
|
78
|
+
|
|
79
|
+
#### Gradle Tasks
|
|
80
|
+
```bash
|
|
81
|
+
droid-cli gradle <task> [--args "additional arguments"] [--project <path>]
|
|
82
|
+
```
|
|
83
|
+
Run any Gradle task with optional arguments.
|
|
84
|
+
|
|
85
|
+
#### Initialize Configuration
|
|
86
|
+
```bash
|
|
87
|
+
droid-cli init [--project <path>]
|
|
88
|
+
```
|
|
89
|
+
Set up or reconfigure the CLI for your project.
|
|
90
|
+
|
|
91
|
+
#### Build Variant Selection
|
|
92
|
+
```bash
|
|
93
|
+
droid-cli variant [--project <path>]
|
|
94
|
+
```
|
|
95
|
+
Select the default build variant (debug/release) for the project.
|
|
96
|
+
|
|
97
|
+
## Configuration
|
|
98
|
+
|
|
99
|
+
The CLI uses an `droid-cli.json` file in your project root for configuration:
|
|
100
|
+
|
|
101
|
+
```json
|
|
102
|
+
{
|
|
103
|
+
"projectPath": "./app",
|
|
104
|
+
"defaultVariant": "debug",
|
|
105
|
+
"terminal": "auto",
|
|
106
|
+
"gradleTasks": {
|
|
107
|
+
"custom": ["myCustomTask"]
|
|
108
|
+
},
|
|
109
|
+
"buildCache": {
|
|
110
|
+
"enabled": true,
|
|
111
|
+
"maxSize": "1GB"
|
|
112
|
+
},
|
|
113
|
+
"logcat": {
|
|
114
|
+
"clearOnStart": true,
|
|
115
|
+
"colorize": true
|
|
116
|
+
},
|
|
117
|
+
"selectedDevice": "emulator-5554"
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Configuration Options
|
|
122
|
+
|
|
123
|
+
- **`projectPath`** - Path to your Android project directory
|
|
124
|
+
- **`defaultVariant`** - Default build variant (debug/release)
|
|
125
|
+
- **`terminal`** - Terminal to use for logcat (auto/iterm2/terminal/gnome-terminal/etc.)
|
|
126
|
+
- **`gradleTasks.custom`** - Array of custom Gradle tasks to show in menu
|
|
127
|
+
- **`buildCache.enabled`** - Enable Gradle build cache for faster builds
|
|
128
|
+
- **`buildCache.maxSize`** - Maximum cache size
|
|
129
|
+
- **`logcat.clearOnStart`** - Clear logcat before starting new session
|
|
130
|
+
- **`logcat.colorize`** - Enable colored logcat output
|
|
131
|
+
- **`selectedDevice`** - Last selected device (auto-saved)
|
|
132
|
+
|
|
133
|
+
## Supported Terminals
|
|
134
|
+
|
|
135
|
+
The CLI automatically detects and supports:
|
|
136
|
+
|
|
137
|
+
- **macOS**: iTerm2, Terminal.app
|
|
138
|
+
- **Linux**: gnome-terminal, konsole, xterm
|
|
139
|
+
- **Windows**: Windows Terminal
|
|
140
|
+
|
|
141
|
+
## Use Cases
|
|
142
|
+
|
|
143
|
+
### Daily Development Workflow
|
|
144
|
+
|
|
145
|
+
1. **Morning Setup**:
|
|
146
|
+
```bash
|
|
147
|
+
droid-cli device # Select your preferred device
|
|
148
|
+
droid-cli build # Build and deploy
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
2. **Development Loop**:
|
|
152
|
+
```bash
|
|
153
|
+
droid-cli # Interactive menu
|
|
154
|
+
# Select "Build & Run" for quick iterations
|
|
155
|
+
# Select "Open Logcat" when debugging
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
3. **Clean Builds**:
|
|
159
|
+
```bash
|
|
160
|
+
droid-cli gradle clean
|
|
161
|
+
droid-cli build
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### CI/CD Integration
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
# In your CI script
|
|
168
|
+
droid-cli gradle clean
|
|
169
|
+
droid-cli gradle assembleRelease
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Team Development
|
|
173
|
+
|
|
174
|
+
Share the `droid-cli.json` configuration with your team for consistent build settings.
|
|
175
|
+
|
|
176
|
+
## Comparison with Android Studio
|
|
177
|
+
|
|
178
|
+
| Feature | Android Studio | Droid CLI |
|
|
179
|
+
|---------|---------------|------------------------|
|
|
180
|
+
| Memory Usage | ~2-4 GB RAM | ~50-100 MB RAM |
|
|
181
|
+
| Build Speed | Full IDE overhead | Direct Gradle execution |
|
|
182
|
+
| Logcat | Built-in viewer | Native terminal |
|
|
183
|
+
| Device Management | GUI selection | CLI selection |
|
|
184
|
+
| Project Navigation | Full IDE | Terminal/Editor of choice |
|
|
185
|
+
| Debugging | Full debugger | Logcat + external tools |
|
|
186
|
+
|
|
187
|
+
## Troubleshooting
|
|
188
|
+
|
|
189
|
+
### Common Issues
|
|
190
|
+
|
|
191
|
+
1. **"ADB not found"**
|
|
192
|
+
- Ensure Android SDK is installed
|
|
193
|
+
- Add `adb` to your PATH
|
|
194
|
+
- Verify with: `adb version`
|
|
195
|
+
|
|
196
|
+
2. **"No Android project found"**
|
|
197
|
+
- Run `droid-cli init` in your project directory
|
|
198
|
+
- Ensure `build.gradle` and `settings.gradle` exist
|
|
199
|
+
|
|
200
|
+
3. **Device not detected**
|
|
201
|
+
- Enable USB debugging on your device
|
|
202
|
+
- Check device connection: `adb devices`
|
|
203
|
+
- For emulators, ensure they're running
|
|
204
|
+
|
|
205
|
+
4. **Build failures**
|
|
206
|
+
- Run `droid-cli gradle clean`
|
|
207
|
+
- Check Gradle wrapper permissions: `chmod +x gradlew`
|
|
208
|
+
- Verify Java version compatibility
|
|
209
|
+
|
|
210
|
+
### Debug Mode
|
|
211
|
+
|
|
212
|
+
Set environment variable for verbose logging:
|
|
213
|
+
```bash
|
|
214
|
+
DEBUG=droid-cli droid-cli build
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
## Contributing
|
|
218
|
+
|
|
219
|
+
1. Fork the repository
|
|
220
|
+
2. Create a feature branch
|
|
221
|
+
3. Make your changes
|
|
222
|
+
4. Add tests for new functionality
|
|
223
|
+
5. Submit a pull request
|
|
224
|
+
|
|
225
|
+
## Development
|
|
226
|
+
|
|
227
|
+
```bash
|
|
228
|
+
# Clone the repository
|
|
229
|
+
git clone https://github.com/your-username/droid-cli.git
|
|
230
|
+
cd droid-cli
|
|
231
|
+
|
|
232
|
+
# Install dependencies
|
|
233
|
+
yarn install
|
|
234
|
+
|
|
235
|
+
# Build the project
|
|
236
|
+
yarn build
|
|
237
|
+
|
|
238
|
+
# Run in development mode
|
|
239
|
+
yarn dev
|
|
240
|
+
|
|
241
|
+
# Run tests
|
|
242
|
+
yarn test
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
## License
|
|
246
|
+
|
|
247
|
+
MIT License - see LICENSE file for details.
|
|
248
|
+
|
|
249
|
+
## Roadmap
|
|
250
|
+
|
|
251
|
+
- [ ] Hot reload support
|
|
252
|
+
- [ ] Multiple app module support
|
|
253
|
+
- [ ] Wireless debugging integration
|
|
254
|
+
- [ ] Build performance profiling
|
|
255
|
+
- [ ] Plugin system
|
|
256
|
+
- [ ] VS Code extension
|
|
257
|
+
- [ ] Windows PowerShell support
|
|
258
|
+
- [ ] Docker container builds
|
|
259
|
+
|
|
260
|
+
## Support
|
|
261
|
+
|
|
262
|
+
- 📖 Documentation: [GitHub Wiki](https://github.com/your-username/droid-cli/wiki)
|
|
263
|
+
- 🐛 Bug Reports: [GitHub Issues](https://github.com/your-username/droid-cli/issues)
|
|
264
|
+
- 💬 Discussions: [GitHub Discussions](https://github.com/your-username/droid-cli/discussions)
|
|
265
|
+
|
|
266
|
+
---
|
|
267
|
+
|
|
268
|
+
**Made with ❤️ for Android developers who love the terminal**
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
interface BuildOptions {
|
|
2
|
+
variant?: string;
|
|
3
|
+
device?: string;
|
|
4
|
+
interactive?: boolean;
|
|
5
|
+
}
|
|
6
|
+
export interface BuildResult {
|
|
7
|
+
success: boolean;
|
|
8
|
+
error?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function buildCommand(options?: BuildOptions): Promise<BuildResult>;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=build.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/commands/build.ts"],"names":[],"mappings":"AAOA,UAAU,YAAY;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AA+SD,wBAAsB,YAAY,CAAC,OAAO,GAAE,YAAiB,GAAG,OAAO,CAAC,WAAW,CAAC,CAiJnF"}
|
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildCommand = buildCommand;
|
|
4
|
+
const logger_1 = require("../ui/logger");
|
|
5
|
+
const android_project_1 = require("../core/android-project");
|
|
6
|
+
const gradle_wrapper_1 = require("../core/gradle-wrapper");
|
|
7
|
+
const adb_1 = require("../core/adb");
|
|
8
|
+
const config_manager_1 = require("../config/config-manager");
|
|
9
|
+
const prompts_1 = require("@inquirer/prompts");
|
|
10
|
+
async function ensureDeviceAvailable(adbManager, options) {
|
|
11
|
+
const devices = await adbManager.getDevices();
|
|
12
|
+
let availableDevices = adbManager.getAvailableDevices();
|
|
13
|
+
if (availableDevices.length === 0) {
|
|
14
|
+
logger_1.Logger.warn('No devices are currently available.');
|
|
15
|
+
const physicalDevices = adbManager.getPhysicalDevices();
|
|
16
|
+
const runningEmulators = adbManager.getRunningEmulators();
|
|
17
|
+
logger_1.Logger.info(`Found: ${physicalDevices.length} physical device(s), ${runningEmulators.length} running emulator(s)`);
|
|
18
|
+
if (devices.length > 0) {
|
|
19
|
+
logger_1.Logger.info('Device states:');
|
|
20
|
+
devices.forEach(device => {
|
|
21
|
+
logger_1.Logger.info(` • ${device.name} (${device.id}): ${device.state}`);
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
// Check if we can start an emulator
|
|
25
|
+
const canStartEmulator = await adbManager.checkEmulatorCommand();
|
|
26
|
+
if (canStartEmulator) {
|
|
27
|
+
const availableEmulators = await adbManager.getAvailableEmulators();
|
|
28
|
+
if (availableEmulators.length > 0) {
|
|
29
|
+
logger_1.Logger.step('Would you like to start an emulator?');
|
|
30
|
+
const startEmulator = await (0, prompts_1.confirm)({
|
|
31
|
+
message: 'No devices connected. Start an emulator?',
|
|
32
|
+
default: true,
|
|
33
|
+
});
|
|
34
|
+
if (startEmulator) {
|
|
35
|
+
let selectedEmulator;
|
|
36
|
+
if (availableEmulators.length === 1) {
|
|
37
|
+
selectedEmulator = availableEmulators[0].name;
|
|
38
|
+
logger_1.Logger.info(`Starting emulator: ${availableEmulators[0].displayName}`);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
const emulatorChoices = availableEmulators.map(emu => ({
|
|
42
|
+
name: emu.displayName,
|
|
43
|
+
value: emu.name,
|
|
44
|
+
}));
|
|
45
|
+
selectedEmulator = await (0, prompts_1.select)({
|
|
46
|
+
message: 'Select emulator to start:',
|
|
47
|
+
choices: emulatorChoices,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
const emulatorStarted = await adbManager.startEmulator(selectedEmulator);
|
|
51
|
+
if (emulatorStarted) {
|
|
52
|
+
// Refresh device list after emulator starts
|
|
53
|
+
await adbManager.getDevices();
|
|
54
|
+
availableDevices = adbManager.getAvailableDevices();
|
|
55
|
+
if (availableDevices.length > 0) {
|
|
56
|
+
logger_1.Logger.success('Emulator is ready! Continuing with build...');
|
|
57
|
+
return { success: true };
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
const error = 'Emulator started but may still be booting. Please try again in a moment.';
|
|
61
|
+
logger_1.Logger.warn(error);
|
|
62
|
+
return { success: false, error };
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
const error = 'Failed to start emulator.';
|
|
67
|
+
logger_1.Logger.error(error);
|
|
68
|
+
return { success: false, error };
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
const error = 'No devices available and emulator startup declined.';
|
|
73
|
+
logger_1.Logger.error(error);
|
|
74
|
+
logger_1.Logger.info('Please connect a device or start an emulator manually.');
|
|
75
|
+
return { success: false, error };
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
const error = 'No emulators found. Please create an AVD or connect a physical device.';
|
|
80
|
+
logger_1.Logger.error(error);
|
|
81
|
+
return { success: false, error };
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
const error = 'Emulator command not found. Please connect a physical device.';
|
|
86
|
+
logger_1.Logger.error(error);
|
|
87
|
+
logger_1.Logger.info('To use emulators, ensure Android SDK emulator tools are installed.');
|
|
88
|
+
return { success: false, error };
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return { success: true };
|
|
92
|
+
}
|
|
93
|
+
async function launchAppAndComplete(adbManager, deviceId, packageName, buildDuration) {
|
|
94
|
+
// Launch the app
|
|
95
|
+
logger_1.Logger.step('Launching app...');
|
|
96
|
+
const launchSuccess = await adbManager.launchApp(deviceId, packageName);
|
|
97
|
+
if (!launchSuccess) {
|
|
98
|
+
logger_1.Logger.warn('App installed but failed to launch automatically.');
|
|
99
|
+
logger_1.Logger.info('You can manually launch the app from the device.');
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
logger_1.Logger.success('App launched successfully!');
|
|
103
|
+
}
|
|
104
|
+
logger_1.Logger.success('Build and deployment completed successfully!');
|
|
105
|
+
logger_1.Logger.info(`Total time: ${(buildDuration / 1000).toFixed(1)}s`);
|
|
106
|
+
logger_1.Logger.info('You can now run "droid-cli logcat" to view app logs.');
|
|
107
|
+
return { success: true };
|
|
108
|
+
}
|
|
109
|
+
async function handleInstallationFailure(adbManager, deviceId, packageName, installResult, apkPath, buildDuration) {
|
|
110
|
+
logger_1.Logger.error('Installation failed:', installResult.error || 'Unknown error');
|
|
111
|
+
if (installResult.suggestion) {
|
|
112
|
+
logger_1.Logger.info('💡 Suggestion:', installResult.suggestion);
|
|
113
|
+
}
|
|
114
|
+
// Show device storage info for storage-related errors
|
|
115
|
+
if (installResult.errorType === 'INSUFFICIENT_STORAGE') {
|
|
116
|
+
const storageInfo = await adbManager.getStorageInfo(deviceId);
|
|
117
|
+
if (storageInfo) {
|
|
118
|
+
logger_1.Logger.info(`📊 Device storage: ${storageInfo.available} available of ${storageInfo.total} total`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// Offer automated solutions for specific error types
|
|
122
|
+
switch (installResult.errorType) {
|
|
123
|
+
case 'INSUFFICIENT_STORAGE':
|
|
124
|
+
return await handleInsufficientStorage(adbManager, deviceId, packageName, apkPath, buildDuration);
|
|
125
|
+
case 'DUPLICATE_PACKAGE':
|
|
126
|
+
return await handleDuplicatePackage(adbManager, deviceId, packageName, apkPath, buildDuration);
|
|
127
|
+
default:
|
|
128
|
+
return {
|
|
129
|
+
success: false,
|
|
130
|
+
error: installResult.error || 'APK installation failed'
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
async function handleInsufficientStorage(adbManager, deviceId, packageName, apkPath, buildDuration) {
|
|
135
|
+
console.log(''); // Add spacing
|
|
136
|
+
const choice = await (0, prompts_1.select)({
|
|
137
|
+
message: 'How would you like to resolve the storage issue?',
|
|
138
|
+
choices: [
|
|
139
|
+
{ name: '🗑️ Uninstall the existing app and retry', value: 'uninstall' },
|
|
140
|
+
{ name: '📱 Clear app data and retry', value: 'clear' },
|
|
141
|
+
{ name: '❌ Skip installation (build completed)', value: 'skip' },
|
|
142
|
+
],
|
|
143
|
+
});
|
|
144
|
+
switch (choice) {
|
|
145
|
+
case 'uninstall':
|
|
146
|
+
logger_1.Logger.step('Uninstalling existing app...');
|
|
147
|
+
const uninstallSuccess = await adbManager.uninstallApp(deviceId, packageName);
|
|
148
|
+
if (uninstallSuccess) {
|
|
149
|
+
logger_1.Logger.step('Retrying installation...');
|
|
150
|
+
const retryResult = await adbManager.installApk(deviceId, apkPath);
|
|
151
|
+
if (retryResult.success) {
|
|
152
|
+
logger_1.Logger.success('APK installed successfully after uninstalling previous version!');
|
|
153
|
+
return await launchAppAndComplete(adbManager, deviceId, packageName, buildDuration);
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
return {
|
|
157
|
+
success: false,
|
|
158
|
+
error: `Installation failed again: ${retryResult.error}`
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
return {
|
|
164
|
+
success: false,
|
|
165
|
+
error: 'Failed to uninstall existing app'
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
case 'clear':
|
|
169
|
+
logger_1.Logger.step('Clearing app data...');
|
|
170
|
+
const clearSuccess = await adbManager.clearAppData(deviceId, packageName);
|
|
171
|
+
if (clearSuccess) {
|
|
172
|
+
logger_1.Logger.step('Retrying installation...');
|
|
173
|
+
const retryResult = await adbManager.installApk(deviceId, apkPath);
|
|
174
|
+
if (retryResult.success) {
|
|
175
|
+
logger_1.Logger.success('APK installed successfully after clearing app data!');
|
|
176
|
+
return await launchAppAndComplete(adbManager, deviceId, packageName, buildDuration);
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
return {
|
|
180
|
+
success: false,
|
|
181
|
+
error: `Installation failed again: ${retryResult.error}`
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
return {
|
|
187
|
+
success: false,
|
|
188
|
+
error: 'Failed to clear app data'
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
case 'skip':
|
|
192
|
+
logger_1.Logger.warn('Installation skipped. Build completed but app not installed.');
|
|
193
|
+
return {
|
|
194
|
+
success: false,
|
|
195
|
+
error: 'Installation skipped due to insufficient storage'
|
|
196
|
+
};
|
|
197
|
+
default:
|
|
198
|
+
return {
|
|
199
|
+
success: false,
|
|
200
|
+
error: 'Invalid choice'
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
async function handleDuplicatePackage(adbManager, deviceId, packageName, apkPath, buildDuration) {
|
|
205
|
+
console.log(''); // Add spacing
|
|
206
|
+
const choice = await (0, prompts_1.select)({
|
|
207
|
+
message: 'The app is already installed. How would you like to proceed?',
|
|
208
|
+
choices: [
|
|
209
|
+
{ name: '🔄 Force reinstall (uninstall + install)', value: 'force' },
|
|
210
|
+
{ name: '📱 Clear app data and update', value: 'clear' },
|
|
211
|
+
{ name: '❌ Skip installation', value: 'skip' },
|
|
212
|
+
],
|
|
213
|
+
});
|
|
214
|
+
switch (choice) {
|
|
215
|
+
case 'force':
|
|
216
|
+
logger_1.Logger.step('Force reinstalling app...');
|
|
217
|
+
await adbManager.uninstallApp(deviceId, packageName);
|
|
218
|
+
logger_1.Logger.step('Installing new version...');
|
|
219
|
+
const installResult = await adbManager.installApk(deviceId, apkPath);
|
|
220
|
+
if (installResult.success) {
|
|
221
|
+
logger_1.Logger.success('App force reinstalled successfully!');
|
|
222
|
+
return await launchAppAndComplete(adbManager, deviceId, packageName, buildDuration);
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
return {
|
|
226
|
+
success: false,
|
|
227
|
+
error: `Force reinstall failed: ${installResult.error}`
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
case 'clear':
|
|
231
|
+
logger_1.Logger.step('Clearing app data...');
|
|
232
|
+
const clearSuccess = await adbManager.clearAppData(deviceId, packageName);
|
|
233
|
+
if (clearSuccess) {
|
|
234
|
+
logger_1.Logger.success('App data cleared. The existing app is ready to use with new build.');
|
|
235
|
+
return await launchAppAndComplete(adbManager, deviceId, packageName, buildDuration);
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
return {
|
|
239
|
+
success: false,
|
|
240
|
+
error: 'Failed to clear app data'
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
case 'skip':
|
|
244
|
+
logger_1.Logger.info('Installation skipped. The existing app version remains installed.');
|
|
245
|
+
return {
|
|
246
|
+
success: false,
|
|
247
|
+
error: 'Installation skipped - app already exists'
|
|
248
|
+
};
|
|
249
|
+
default:
|
|
250
|
+
return {
|
|
251
|
+
success: false,
|
|
252
|
+
error: 'Invalid choice'
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
async function buildCommand(options = {}) {
|
|
257
|
+
try {
|
|
258
|
+
logger_1.Logger.step('Starting Android build process...');
|
|
259
|
+
// Load configuration
|
|
260
|
+
const configManager = config_manager_1.ConfigManager.getInstance();
|
|
261
|
+
const config = await configManager.load();
|
|
262
|
+
// Detect Android project
|
|
263
|
+
const project = await android_project_1.AndroidProject.detect(configManager.getProjectPath());
|
|
264
|
+
if (!project) {
|
|
265
|
+
const error = 'No Android project found. Please run this command from an Android project directory or run "droid-cli init" first.';
|
|
266
|
+
logger_1.Logger.error(error);
|
|
267
|
+
return { success: false, error };
|
|
268
|
+
}
|
|
269
|
+
const projectInfo = project.getInfo();
|
|
270
|
+
if (!projectInfo) {
|
|
271
|
+
const error = 'Failed to load Android project information.';
|
|
272
|
+
logger_1.Logger.error(error);
|
|
273
|
+
return { success: false, error };
|
|
274
|
+
}
|
|
275
|
+
logger_1.Logger.info(`Found Android project: ${projectInfo.packageName}`);
|
|
276
|
+
logger_1.Logger.info(`Project path: ${projectInfo.rootPath}`);
|
|
277
|
+
// Determine build variant
|
|
278
|
+
let variant = options.variant || config.defaultVariant;
|
|
279
|
+
const availableVariants = project.getBuildVariants();
|
|
280
|
+
// If interactive mode and no variant specified, ask user
|
|
281
|
+
if (options.interactive && !options.variant) {
|
|
282
|
+
logger_1.Logger.step('Select build variant:');
|
|
283
|
+
const variantChoices = availableVariants.map(v => ({
|
|
284
|
+
name: v.charAt(0).toUpperCase() + v.slice(1),
|
|
285
|
+
value: v,
|
|
286
|
+
}));
|
|
287
|
+
variant = await (0, prompts_1.select)({
|
|
288
|
+
message: 'Which variant would you like to build?',
|
|
289
|
+
choices: variantChoices,
|
|
290
|
+
default: config.defaultVariant,
|
|
291
|
+
});
|
|
292
|
+
// Update default variant in config if different
|
|
293
|
+
if (variant !== config.defaultVariant) {
|
|
294
|
+
config.defaultVariant = variant;
|
|
295
|
+
configManager.set(config);
|
|
296
|
+
await configManager.save();
|
|
297
|
+
logger_1.Logger.success(`Default variant updated to: ${variant}`);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
if (!availableVariants.includes(variant)) {
|
|
301
|
+
const error = `Invalid build variant: ${variant}. Available variants: ${availableVariants.join(', ')}`;
|
|
302
|
+
logger_1.Logger.error(`Invalid build variant: ${variant}`);
|
|
303
|
+
logger_1.Logger.info(`Available variants: ${availableVariants.join(', ')}`);
|
|
304
|
+
return { success: false, error };
|
|
305
|
+
}
|
|
306
|
+
// Get ADB manager and ensure device is available
|
|
307
|
+
const adbManager = adb_1.AdbManager.getInstance();
|
|
308
|
+
const deviceResult = await ensureDeviceAvailable(adbManager, options);
|
|
309
|
+
if (!deviceResult.success) {
|
|
310
|
+
return { success: false, error: deviceResult.error };
|
|
311
|
+
}
|
|
312
|
+
// Refresh device list after potential emulator start
|
|
313
|
+
await adbManager.getDevices();
|
|
314
|
+
const availableDevices = adbManager.getAvailableDevices();
|
|
315
|
+
// Determine target device
|
|
316
|
+
let targetDeviceId = options.device || config.selectedDevice;
|
|
317
|
+
if (!targetDeviceId || !availableDevices.find(d => d.id === targetDeviceId)) {
|
|
318
|
+
if (availableDevices.length === 1) {
|
|
319
|
+
targetDeviceId = availableDevices[0].id;
|
|
320
|
+
logger_1.Logger.info(`Using device: ${availableDevices[0].name} (${targetDeviceId})`);
|
|
321
|
+
}
|
|
322
|
+
else {
|
|
323
|
+
// Let user select device
|
|
324
|
+
logger_1.Logger.step('No device selected. Please choose a target device:');
|
|
325
|
+
const deviceChoices = availableDevices.map(device => ({
|
|
326
|
+
name: `${device.name} (${device.id}) - API ${device.apiLevel || 'Unknown'}`,
|
|
327
|
+
value: device.id,
|
|
328
|
+
}));
|
|
329
|
+
targetDeviceId = await (0, prompts_1.select)({
|
|
330
|
+
message: 'Select target device:',
|
|
331
|
+
choices: deviceChoices,
|
|
332
|
+
});
|
|
333
|
+
logger_1.Logger.success(`Selected device: ${adbManager.getDeviceById(targetDeviceId)?.name} (${targetDeviceId})`);
|
|
334
|
+
}
|
|
335
|
+
// Save selected device to config
|
|
336
|
+
configManager.setSelectedDevice(targetDeviceId);
|
|
337
|
+
await configManager.save();
|
|
338
|
+
}
|
|
339
|
+
const targetDevice = adbManager.getDeviceById(targetDeviceId);
|
|
340
|
+
if (!targetDevice) {
|
|
341
|
+
const error = `Device ${targetDeviceId} not found or not available.`;
|
|
342
|
+
logger_1.Logger.error(error);
|
|
343
|
+
return { success: false, error };
|
|
344
|
+
}
|
|
345
|
+
logger_1.Logger.device(`Target device: ${targetDevice.name} (${targetDevice.id})`);
|
|
346
|
+
// Build the project
|
|
347
|
+
const gradleWrapper = new gradle_wrapper_1.GradleWrapper(project);
|
|
348
|
+
logger_1.Logger.build(`Building ${variant} variant...`);
|
|
349
|
+
const buildResult = await gradleWrapper.build(variant, true);
|
|
350
|
+
if (!buildResult.success) {
|
|
351
|
+
const error = 'Build failed. Please check the error messages above.';
|
|
352
|
+
logger_1.Logger.error(error);
|
|
353
|
+
return { success: false, error: buildResult.error || error };
|
|
354
|
+
}
|
|
355
|
+
if (!buildResult.apkPath) {
|
|
356
|
+
const error = 'Build succeeded but APK path not found.';
|
|
357
|
+
logger_1.Logger.error(error);
|
|
358
|
+
return { success: false, error };
|
|
359
|
+
}
|
|
360
|
+
// Install APK on device
|
|
361
|
+
logger_1.Logger.step('Installing APK on device...');
|
|
362
|
+
const installResult = await adbManager.installApk(targetDevice.id, buildResult.apkPath);
|
|
363
|
+
if (!installResult.success) {
|
|
364
|
+
return await handleInstallationFailure(adbManager, targetDevice.id, projectInfo.packageName, installResult, buildResult.apkPath, buildResult.duration);
|
|
365
|
+
}
|
|
366
|
+
// Launch app and complete
|
|
367
|
+
return await launchAppAndComplete(adbManager, targetDevice.id, projectInfo.packageName, buildResult.duration);
|
|
368
|
+
}
|
|
369
|
+
catch (error) {
|
|
370
|
+
const errorMessage = `Build command failed: ${error instanceof Error ? error.message : String(error)}`;
|
|
371
|
+
logger_1.Logger.error('Build command failed:', error);
|
|
372
|
+
return { success: false, error: errorMessage };
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
//# sourceMappingURL=build.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/commands/build.ts"],"names":[],"mappings":"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"}
|