create-droid 1.0.1 → 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/README.md +19 -5
- package/dist/template/generateProject.js +47 -0
- package/package.json +1 -1
- package/templates/base/.gradle/9.2.0/checksums/checksums.lock +0 -0
- package/templates/base/.gradle/9.2.0/executionHistory/executionHistory.lock +0 -0
- package/templates/base/.gradle/9.2.0/fileChanges/last-build.bin +0 -0
- package/templates/base/.gradle/9.2.0/fileHashes/fileHashes.lock +0 -0
- package/templates/base/.gradle/9.2.0/gc.properties +0 -0
- package/templates/base/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
- package/templates/base/.gradle/buildOutputCleanup/cache.properties +2 -0
- package/templates/base/.gradle/vcs-1/gc.properties +0 -0
- package/templates/base/_gitignore +23 -0
- package/templates/base/app/src/main/res/drawable/ic_launcher_background.xml +10 -0
- package/templates/base/app/src/main/res/drawable/ic_launcher_foreground.xml +9 -0
- package/templates/base/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +5 -0
- package/templates/base/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +5 -0
- package/templates/base/app/src/main/res/values/strings.xml +3 -0
- package/templates/base/app/src/main/res/values/themes.xml +4 -0
- package/templates/base/app/src/main/res/xml/backup_rules.xml +5 -0
- package/templates/base/app/src/main/res/xml/data_extraction_rules.xml +11 -0
- package/templates/base/scripts/adb.js +47 -0
package/README.md
CHANGED
|
@@ -42,16 +42,30 @@ Follow the interactive prompts:
|
|
|
42
42
|
```bash
|
|
43
43
|
cd my-app
|
|
44
44
|
|
|
45
|
-
#
|
|
46
|
-
|
|
45
|
+
# Start "Live Reload" mode (Continuous Build)
|
|
46
|
+
# Edits will auto-compile and install on your connected device!
|
|
47
|
+
npm run dev
|
|
47
48
|
|
|
48
|
-
#
|
|
49
|
-
|
|
49
|
+
# Or build manually
|
|
50
|
+
npm run build
|
|
50
51
|
```
|
|
51
52
|
|
|
52
53
|
## What's Inside?
|
|
53
54
|
|
|
54
|
-
The generated project is **clean** and follows modern best practices:
|
|
55
|
+
The generated project is **clean** and follows modern best practices. It includes a `package.json` with convenience scripts:
|
|
56
|
+
|
|
57
|
+
* `npm run dev`: Watches your code and auto-deploys changes (`./gradlew -t installDebug`).
|
|
58
|
+
* `npm run build`: Generates a release APK (`./gradlew assembleRelease`).
|
|
59
|
+
* `npm test`: Runs unit tests (`./gradlew test`).
|
|
60
|
+
|
|
61
|
+
### 📱 ADB Scripts (Wireless Debugging)
|
|
62
|
+
|
|
63
|
+
We include a robust `adb` wrapper that works even if `adb` is not in your PATH (uses the local SDK):
|
|
64
|
+
|
|
65
|
+
* `npm run adb:devices`: List connected devices.
|
|
66
|
+
* `npm run adb:connect <ip>`: Connect to a device via Wi-Fi.
|
|
67
|
+
* `npm run adb:pair <ip> <code>`: Pair a new device (Android 11+).
|
|
68
|
+
* `npm run adb:logcat`: View device logs.
|
|
55
69
|
|
|
56
70
|
```text
|
|
57
71
|
my-app/
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import fs from 'fs-extra';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import { fileURLToPath } from 'url';
|
|
4
|
+
import { execa } from 'execa';
|
|
4
5
|
import { CONSTANTS } from '../utils/constants.js';
|
|
5
6
|
import { logger } from '../utils/logger.js';
|
|
6
7
|
const __filename = fileURLToPath(import.meta.url);
|
|
@@ -20,6 +21,11 @@ export async function generateProject(options) {
|
|
|
20
21
|
// 3. Copy Base
|
|
21
22
|
logger.info(`Copying base template from ${baseTemplate}...`);
|
|
22
23
|
await fs.copy(baseTemplate, projectPath);
|
|
24
|
+
// Rename _gitignore to .gitignore
|
|
25
|
+
const gitignorePath = path.join(projectPath, '_gitignore');
|
|
26
|
+
if (fs.existsSync(gitignorePath)) {
|
|
27
|
+
await fs.move(gitignorePath, path.join(projectPath, '.gitignore'));
|
|
28
|
+
}
|
|
23
29
|
// 4. Copy UI specific files
|
|
24
30
|
if (fs.existsSync(uiTemplate)) {
|
|
25
31
|
logger.info(`Applying ${uiType} template...`);
|
|
@@ -58,6 +64,47 @@ export async function generateProject(options) {
|
|
|
58
64
|
// Create local.properties with SDK location
|
|
59
65
|
const localProperties = `sdk.dir=${sdkPath}`;
|
|
60
66
|
await fs.writeFile(path.join(projectPath, 'local.properties'), localProperties);
|
|
67
|
+
// 6. Setup NPM Scripts (The "Vite-like" experience)
|
|
68
|
+
logger.info('Adding npm convenience scripts...');
|
|
69
|
+
const packageJson = {
|
|
70
|
+
name: projectName.toLowerCase().replace(/[^a-z0-9-]/g, '-'),
|
|
71
|
+
version: "0.1.0",
|
|
72
|
+
private: true,
|
|
73
|
+
scripts: {
|
|
74
|
+
"dev": "./gradlew -t installDebug",
|
|
75
|
+
"start": "npm run dev",
|
|
76
|
+
"build": "./gradlew assembleRelease",
|
|
77
|
+
"build:debug": "./gradlew assembleDebug",
|
|
78
|
+
"test": "./gradlew test",
|
|
79
|
+
"lint": "./gradlew lint",
|
|
80
|
+
"clean": "./gradlew clean",
|
|
81
|
+
"help": "./gradlew --help",
|
|
82
|
+
"adb": "node scripts/adb.js",
|
|
83
|
+
"adb:devices": "npm run adb devices",
|
|
84
|
+
"adb:connect": "npm run adb connect",
|
|
85
|
+
"adb:pair": "npm run adb pair",
|
|
86
|
+
"adb:logcat": "npm run adb logcat",
|
|
87
|
+
"adb:reverse": "npm run adb reverse tcp:8081 tcp:8081"
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
await fs.writeJSON(path.join(projectPath, 'package.json'), packageJson, { spaces: 2 });
|
|
91
|
+
// Ensure scripts dir exists (since we copy base first, but adb.js is new)
|
|
92
|
+
// Wait, templates/base/scripts/adb.js is ALREADY in the base template.
|
|
93
|
+
// We just need to ensure the `scripts` folder is copied correctly.
|
|
94
|
+
// Since we copy `templates/base`, it should be fine.
|
|
95
|
+
// Make scripts executable if needed (node doesn't need +x but good practice)
|
|
96
|
+
// await fs.chmod(path.join(projectPath, 'scripts/adb.js'), 0o755);
|
|
97
|
+
// 7. Initialize Git
|
|
98
|
+
try {
|
|
99
|
+
logger.info('Initializing git repository...');
|
|
100
|
+
await execa('git', ['init'], { cwd: projectPath });
|
|
101
|
+
await execa('git', ['add', '.'], { cwd: projectPath });
|
|
102
|
+
await execa('git', ['commit', '-m', 'Initial commit via create-droid'], { cwd: projectPath });
|
|
103
|
+
logger.success('Git repository initialized.');
|
|
104
|
+
}
|
|
105
|
+
catch (e) {
|
|
106
|
+
logger.warn('Failed to initialize git repository. You may need to run "git init" manually.');
|
|
107
|
+
}
|
|
61
108
|
}
|
|
62
109
|
async function patchFile(filePath, replacements) {
|
|
63
110
|
if (!fs.existsSync(filePath))
|
package/package.json
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Gradle
|
|
2
|
+
.gradle/
|
|
3
|
+
build/
|
|
4
|
+
app/build/
|
|
5
|
+
|
|
6
|
+
# Local configuration file (sdk.dir is here)
|
|
7
|
+
local.properties
|
|
8
|
+
|
|
9
|
+
# Android Studio / IntelliJ
|
|
10
|
+
.idea/
|
|
11
|
+
*.iml
|
|
12
|
+
*.iws
|
|
13
|
+
*.ipr
|
|
14
|
+
*.xml
|
|
15
|
+
|
|
16
|
+
# Mac
|
|
17
|
+
.DS_Store
|
|
18
|
+
|
|
19
|
+
# Kotlin
|
|
20
|
+
.kotlin/
|
|
21
|
+
|
|
22
|
+
# Secrets (if any)
|
|
23
|
+
secrets.properties
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
3
|
+
android:width="108dp"
|
|
4
|
+
android:height="108dp"
|
|
5
|
+
android:viewportWidth="108"
|
|
6
|
+
android:viewportHeight="108">
|
|
7
|
+
<path
|
|
8
|
+
android:fillColor="#3DDC84"
|
|
9
|
+
android:pathData="M0,0h108v108h-108z" />
|
|
10
|
+
</vector>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
2
|
+
android:width="108dp"
|
|
3
|
+
android:height="108dp"
|
|
4
|
+
android:viewportWidth="108"
|
|
5
|
+
android:viewportHeight="108">
|
|
6
|
+
<path
|
|
7
|
+
android:fillColor="#FFFFFF"
|
|
8
|
+
android:pathData="M66,66L66,66C66,66 66,66 66,66L66,66C66,66 66,66 66,66L66,66C66,66 66,66 66,66L66,66ZM42,42L42,42C42,42 42,42 42,42L42,42C42,42 42,42 42,42L42,42C42,42 42,42 42,42L42,42ZM54,24L54,24C54,24 54,24 54,24L54,24C54,24 54,24 54,24L54,24C54,24 54,24 54,24L54,24ZM84,54L84,54C84,54 84,54 84,54L84,54C84,54 84,54 84,54L84,54C84,54 84,54 84,54L84,54ZM24,54L24,54C24,54 24,54 24,54L24,54C24,54 24,54 24,54L24,54C24,54 24,54 24,54L24,54ZM54,84L54,84C54,84 54,84 54,84L54,84C54,84 54,84 54,84L54,84C54,84 54,84 54,84L54,84Z" />
|
|
9
|
+
</vector>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
|
3
|
+
<background android:drawable="@drawable/ic_launcher_background" />
|
|
4
|
+
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
|
5
|
+
</adaptive-icon>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
|
3
|
+
<background android:drawable="@drawable/ic_launcher_background" />
|
|
4
|
+
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
|
5
|
+
</adaptive-icon>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<data-extraction-rules>
|
|
3
|
+
<cloud-backup>
|
|
4
|
+
<include domain="sharedpref" path="."/>
|
|
5
|
+
<include domain="database" path="."/>
|
|
6
|
+
</cloud-backup>
|
|
7
|
+
<device-transfer>
|
|
8
|
+
<include domain="sharedpref" path="."/>
|
|
9
|
+
<include domain="database" path="."/>
|
|
10
|
+
</device-transfer>
|
|
11
|
+
</data-extraction-rules>
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const { spawn } = require('child_process');
|
|
4
|
+
const os = require('os');
|
|
5
|
+
|
|
6
|
+
// 1. Find SDK Location from local.properties
|
|
7
|
+
const projectRoot = path.resolve(__dirname, '..');
|
|
8
|
+
const localPropertiesPath = path.join(projectRoot, 'local.properties');
|
|
9
|
+
let sdkPath = process.env.ANDROID_HOME;
|
|
10
|
+
|
|
11
|
+
if (fs.existsSync(localPropertiesPath)) {
|
|
12
|
+
const content = fs.readFileSync(localPropertiesPath, 'utf8');
|
|
13
|
+
const match = content.match(/^sdk\.dir=(.*)$/m);
|
|
14
|
+
if (match) {
|
|
15
|
+
sdkPath = match[1].trim().replace(/\\\\/g, '\\'); // Handle Windows escaping if present
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (!sdkPath) {
|
|
20
|
+
console.error('❌ Could not find SDK location. Set ANDROID_HOME or create local.properties.');
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// 2. Resolve ADB binary
|
|
25
|
+
const isWin = os.platform() === 'win32';
|
|
26
|
+
const adbBinary = isWin ? 'adb.exe' : 'adb';
|
|
27
|
+
const adbPath = path.join(sdkPath, 'platform-tools', adbBinary);
|
|
28
|
+
|
|
29
|
+
if (!fs.existsSync(adbPath)) {
|
|
30
|
+
// Fallback to global adb if local not found
|
|
31
|
+
console.warn(`⚠️ Local ADB not found at ${adbPath}. Trying global 'adb'...`);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// 3. Run ADB with arguments
|
|
35
|
+
const args = process.argv.slice(2);
|
|
36
|
+
const finalAdbPath = fs.existsSync(adbPath) ? adbPath : 'adb';
|
|
37
|
+
|
|
38
|
+
const child = spawn(finalAdbPath, args, { stdio: 'inherit' });
|
|
39
|
+
|
|
40
|
+
child.on('error', (err) => {
|
|
41
|
+
console.error(`❌ Failed to start ADB: ${err.message}`);
|
|
42
|
+
process.exit(1);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
child.on('close', (code) => {
|
|
46
|
+
process.exit(code);
|
|
47
|
+
});
|