@gengjiawen/os-init 1.5.1 → 1.7.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/.husky/pre-commit +1 -0
- package/CHANGELOG.md +19 -0
- package/README.md +28 -0
- package/android-setup.md +128 -0
- package/bin/bin.js +26 -0
- package/build/android-setup.d.ts +8 -0
- package/build/android-setup.js +175 -0
- package/build/dev-setup.js +4 -4
- package/build/index.d.ts +1 -0
- package/build/index.js +3 -1
- package/dev-setup/{Dockerfile.txt → Dockerfile} +2 -1
- package/dev-setup/docker-compose.yml +2 -1
- package/dev-setup/{sshd_config.txt → sshd_config} +1 -0
- package/libs/android-setup.ts +243 -0
- package/libs/dev-setup.ts +5 -5
- package/libs/index.ts +3 -0
- package/package.json +3 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
pnpm lint-staged
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.7.0](https://github.com/gengjiawen/os-init/compare/v1.6.0...v1.7.0) (2025-11-09)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* add setup android sdk ([cb18d40](https://github.com/gengjiawen/os-init/commit/cb18d40e53e312b0aedc66a9cde6738bc2f4f1ba))
|
|
9
|
+
|
|
10
|
+
## [1.6.0](https://github.com/gengjiawen/os-init/compare/v1.5.1...v1.6.0) (2025-10-25)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Features
|
|
14
|
+
|
|
15
|
+
* update Docker configuration to expose additional ports for development ([c1f0be1](https://github.com/gengjiawen/os-init/commit/c1f0be1f5f7559a32cbb2e5f1a829fd79f85d910))
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Bug Fixes
|
|
19
|
+
|
|
20
|
+
* set-dev build issues ([728c0e9](https://github.com/gengjiawen/os-init/commit/728c0e9964d19cdd7624a7e9c5f2e68efaf4858f))
|
|
21
|
+
|
|
3
22
|
## [1.5.1](https://github.com/gengjiawen/os-init/compare/v1.5.0...v1.5.1) (2025-10-25)
|
|
4
23
|
|
|
5
24
|
|
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
## os-init CLI
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/@gengjiawen/os-init)
|
|
4
|
+
|
|
3
5
|
A CLI tool to quickly configure AI development tools and environments.
|
|
4
6
|
|
|
5
7
|
## Usage
|
|
@@ -52,6 +54,32 @@ Example:
|
|
|
52
54
|
pnpx @gengjiawen/os-init set-dev "ssh-rsa AAAAB3NzaC1yc2..."
|
|
53
55
|
```
|
|
54
56
|
|
|
57
|
+
### Setup Android Development Environment
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
pnpx @gengjiawen/os-init set-android [options]
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Sets up a complete Android development environment on macOS and Linux. This command will:
|
|
64
|
+
- Install Android SDK to `~/Android` (or custom path with `--android-home <path>`)
|
|
65
|
+
- Download and install Android SDK Command-line Tools, Platform Tools, Build Tools, CMake, and NDK
|
|
66
|
+
- Automatically accept Android SDK licenses
|
|
67
|
+
- Configure environment variables in your shell config (~/.bashrc, ~/.zshrc, or ~/.config/fish/config.fish)
|
|
68
|
+
- Works on both macOS (Intel and Apple Silicon) and Linux
|
|
69
|
+
- No sudo access required
|
|
70
|
+
|
|
71
|
+
Example:
|
|
72
|
+
```bash
|
|
73
|
+
# Basic installation
|
|
74
|
+
pnpx @gengjiawen/os-init set-android
|
|
75
|
+
|
|
76
|
+
# Custom installation path
|
|
77
|
+
pnpx @gengjiawen/os-init set-android --android-home ~/my-android-sdk
|
|
78
|
+
|
|
79
|
+
# Skip environment variable configuration
|
|
80
|
+
pnpx @gengjiawen/os-init set-android --skip-env-vars
|
|
81
|
+
```
|
|
82
|
+
|
|
55
83
|
---
|
|
56
84
|
|
|
57
85
|
Project generated by [gengjiawen/ts-scaffold](https://github.com/gengjiawen/ts-scaffold)
|
package/android-setup.md
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# Android Development Environment Setup
|
|
2
|
+
|
|
3
|
+
This command sets up a complete Android development environment on macOS and Linux systems.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
os-init set-android [options]
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## What It Does
|
|
12
|
+
|
|
13
|
+
The `set-android` command:
|
|
14
|
+
|
|
15
|
+
1. **Creates Android SDK directory** at `~/Android` (or custom path)
|
|
16
|
+
2. **Downloads and installs Android SDK** command-line tools (automatically detects macOS or Linux)
|
|
17
|
+
3. **Accepts Android SDK licenses** automatically
|
|
18
|
+
4. **Installs essential components**:
|
|
19
|
+
- Platform tools (adb, fastboot, etc.)
|
|
20
|
+
- Android 36 platform
|
|
21
|
+
- Build tools 36.0.0
|
|
22
|
+
- CMake 3.30.5
|
|
23
|
+
- NDK 29.0.14206865
|
|
24
|
+
5. **Configures environment variables** in your shell configuration file (~/.bashrc, ~/.zshrc, or ~/.config/fish/config.fish)
|
|
25
|
+
|
|
26
|
+
## Options
|
|
27
|
+
|
|
28
|
+
- `--android-home <path>` - Custom Android SDK installation path (default: `~/Android`)
|
|
29
|
+
- `--skip-env-vars` - Skip adding environment variables to shell config
|
|
30
|
+
|
|
31
|
+
## Examples
|
|
32
|
+
|
|
33
|
+
### Basic Installation
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
os-init set-android
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
This installs the Android SDK to `~/Android` and adds environment variables to your shell config.
|
|
40
|
+
|
|
41
|
+
### Custom Installation Path
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
os-init set-android --android-home /home/user/android-sdk
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Skip Environment Variables
|
|
48
|
+
|
|
49
|
+
If you prefer to manage environment variables manually:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
os-init set-android --skip-env-vars
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Requirements
|
|
56
|
+
|
|
57
|
+
- **macOS or Linux operating system**
|
|
58
|
+
- Internet connection to download Android SDK
|
|
59
|
+
- Node.js 22.12.0 or higher
|
|
60
|
+
|
|
61
|
+
The script uses `@compilets/unzip-url` package to download and extract the Android SDK, so no external `curl` or `unzip` tools are required. No sudo access is needed as the SDK is installed in your home directory.
|
|
62
|
+
|
|
63
|
+
## Environment Variables
|
|
64
|
+
|
|
65
|
+
After installation, the following environment variables will be set:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
export ANDROID_HOME=~/Android
|
|
69
|
+
export ANDROID_SDK_ROOT=${ANDROID_HOME}
|
|
70
|
+
export ANDROID_NDK_HOME=${ANDROID_HOME}/ndk/29.0.14206865
|
|
71
|
+
export PATH=${ANDROID_HOME}/cmdline-tools/latest/bin:${ANDROID_HOME}/emulator:${ANDROID_HOME}/platform-tools:${ANDROID_HOME}/tools:${ANDROID_HOME}/tools/bin:${PATH}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Activating the Environment
|
|
75
|
+
|
|
76
|
+
After installation, activate the environment in your current shell:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
source ~/.bashrc # or ~/.zshrc, or ~/.config/fish/config.fish
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Or simply open a new terminal session.
|
|
83
|
+
|
|
84
|
+
## Verifying Installation
|
|
85
|
+
|
|
86
|
+
Check that the Android SDK is properly installed:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
adb --version
|
|
90
|
+
sdkmanager --list
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Platform-Specific Notes
|
|
94
|
+
|
|
95
|
+
### macOS
|
|
96
|
+
- The SDK is downloaded from Google's macOS-specific distribution
|
|
97
|
+
- Works on both Intel and Apple Silicon Macs
|
|
98
|
+
- No sudo permissions required
|
|
99
|
+
|
|
100
|
+
### Linux
|
|
101
|
+
- The SDK is downloaded from Google's Linux-specific distribution
|
|
102
|
+
- Tested on Ubuntu and Debian-based systems
|
|
103
|
+
- No sudo permissions required when installing to home directory
|
|
104
|
+
|
|
105
|
+
## Troubleshooting
|
|
106
|
+
|
|
107
|
+
### Command Not Found After Installation
|
|
108
|
+
|
|
109
|
+
Make sure you've sourced your shell configuration file or opened a new terminal:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
source ~/.bashrc # or your shell's config file
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Download Failures
|
|
116
|
+
|
|
117
|
+
If the Android SDK download fails, check your internet connection and try again. The script will show detailed error messages.
|
|
118
|
+
|
|
119
|
+
## What Gets Installed
|
|
120
|
+
|
|
121
|
+
- **Android SDK Command-line Tools** (version 11076708)
|
|
122
|
+
- **Platform Tools** - adb, fastboot, etc.
|
|
123
|
+
- **Android Platform 36** - Latest Android API level
|
|
124
|
+
- **Build Tools 36.0.0** - Tools for building Android apps
|
|
125
|
+
- **CMake 3.30.5** - For native code compilation
|
|
126
|
+
- **NDK 29.0.14206865** - Native Development Kit for C/C++ code
|
|
127
|
+
|
|
128
|
+
|
package/bin/bin.js
CHANGED
|
@@ -8,6 +8,7 @@ const {
|
|
|
8
8
|
installCodexDeps,
|
|
9
9
|
writeRaycastConfig,
|
|
10
10
|
setupDevEnvironment,
|
|
11
|
+
setupAndroidEnvironment,
|
|
11
12
|
} = require('../build')
|
|
12
13
|
|
|
13
14
|
const program = new Command()
|
|
@@ -102,4 +103,29 @@ program
|
|
|
102
103
|
}
|
|
103
104
|
})
|
|
104
105
|
|
|
106
|
+
program
|
|
107
|
+
.command('set-android')
|
|
108
|
+
.description('setup Android development environment (macOS and Linux)')
|
|
109
|
+
.option('--android-home <path>', 'Custom Android SDK installation path')
|
|
110
|
+
.option(
|
|
111
|
+
'--skip-env-vars',
|
|
112
|
+
'Skip adding environment variables to shell config'
|
|
113
|
+
)
|
|
114
|
+
.action(async (options) => {
|
|
115
|
+
try {
|
|
116
|
+
const { androidHome, envVarsAdded, shellRcFile } =
|
|
117
|
+
await setupAndroidEnvironment({
|
|
118
|
+
androidHome: options.androidHome,
|
|
119
|
+
skipEnvVars: options.skipEnvVars,
|
|
120
|
+
})
|
|
121
|
+
console.log(`\n✅ Android SDK installed at: ${androidHome}`)
|
|
122
|
+
if (envVarsAdded && shellRcFile) {
|
|
123
|
+
console.log(`✅ Environment variables added to: ${shellRcFile}`)
|
|
124
|
+
}
|
|
125
|
+
} catch (err) {
|
|
126
|
+
console.error('Failed to setup Android environment:', err.message)
|
|
127
|
+
process.exit(1)
|
|
128
|
+
}
|
|
129
|
+
})
|
|
130
|
+
|
|
105
131
|
program.parse(process.argv)
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.setupAndroidEnvironment = setupAndroidEnvironment;
|
|
4
|
+
const fs = require("fs");
|
|
5
|
+
const path = require("path");
|
|
6
|
+
const os = require("os");
|
|
7
|
+
const execa_1 = require("execa");
|
|
8
|
+
const unzip_url_1 = require("@compilets/unzip-url");
|
|
9
|
+
const ANDROID_CONFIG = {
|
|
10
|
+
sdkVersion: '11076708',
|
|
11
|
+
platformVersion: 'android-36',
|
|
12
|
+
buildToolsVersion: '36.0.0',
|
|
13
|
+
cmakeVersion: '3.30.5',
|
|
14
|
+
ndkVersion: '29.0.14206865',
|
|
15
|
+
};
|
|
16
|
+
function getDefaultAndroidHome() {
|
|
17
|
+
return path.join(os.homedir(), 'Android');
|
|
18
|
+
}
|
|
19
|
+
function getSdkDownloadUrl(sdkVersion) {
|
|
20
|
+
const platform = os.platform();
|
|
21
|
+
if (platform === 'darwin') {
|
|
22
|
+
return `https://dl.google.com/android/repository/commandlinetools-mac-${sdkVersion}_latest.zip`;
|
|
23
|
+
}
|
|
24
|
+
else if (platform === 'linux') {
|
|
25
|
+
return `https://dl.google.com/android/repository/commandlinetools-linux-${sdkVersion}_latest.zip`;
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
throw new Error(`Unsupported platform: ${platform}. Only macOS and Linux are supported.`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function getAndroidEnvVars(androidHome, ndkVersion) {
|
|
32
|
+
return `
|
|
33
|
+
# Android development environment
|
|
34
|
+
export ANDROID_HOME=${androidHome}
|
|
35
|
+
export ANDROID_SDK_ROOT=\${ANDROID_HOME}
|
|
36
|
+
export ANDROID_NDK_HOME=\${ANDROID_HOME}/ndk/${ndkVersion}
|
|
37
|
+
export PATH=\${ANDROID_HOME}/cmdline-tools/latest/bin:\${ANDROID_HOME}/emulator:\${ANDROID_HOME}/platform-tools:\${ANDROID_HOME}/tools:\${ANDROID_HOME}/tools/bin:\${PATH}
|
|
38
|
+
`;
|
|
39
|
+
}
|
|
40
|
+
function getShellRcFile() {
|
|
41
|
+
const shell = process.env.SHELL || '';
|
|
42
|
+
const homeDir = os.homedir();
|
|
43
|
+
if (shell.includes('zsh')) {
|
|
44
|
+
return path.join(homeDir, '.zshrc');
|
|
45
|
+
}
|
|
46
|
+
else if (shell.includes('fish')) {
|
|
47
|
+
return path.join(homeDir, '.config', 'fish', 'config.fish');
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
return path.join(homeDir, '.bashrc');
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function hasAndroidEnvVars(rcFile) {
|
|
54
|
+
if (!fs.existsSync(rcFile)) {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
const content = fs.readFileSync(rcFile, 'utf-8');
|
|
58
|
+
return content.includes('ANDROID_HOME');
|
|
59
|
+
}
|
|
60
|
+
function appendEnvVarsToShellConfig(rcFile, envVars) {
|
|
61
|
+
const dir = path.dirname(rcFile);
|
|
62
|
+
if (!fs.existsSync(dir)) {
|
|
63
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
64
|
+
}
|
|
65
|
+
fs.appendFileSync(rcFile, envVars);
|
|
66
|
+
console.log(`Environment variables added to: ${rcFile}`);
|
|
67
|
+
}
|
|
68
|
+
async function setupAndroidEnvironment(options) {
|
|
69
|
+
const androidHome = options?.androidHome || getDefaultAndroidHome();
|
|
70
|
+
const { sdkVersion, platformVersion, buildToolsVersion, cmakeVersion, ndkVersion, } = ANDROID_CONFIG;
|
|
71
|
+
console.log('Starting Android development environment setup...\n');
|
|
72
|
+
const platform = os.platform();
|
|
73
|
+
if (platform !== 'linux' && platform !== 'darwin') {
|
|
74
|
+
throw new Error(`Unsupported platform: ${platform}. Only macOS and Linux are supported.`);
|
|
75
|
+
}
|
|
76
|
+
console.log(`Platform: ${platform === 'darwin' ? 'macOS' : 'Linux'}`);
|
|
77
|
+
console.log(`Creating Android SDK directory at: ${androidHome}`);
|
|
78
|
+
try {
|
|
79
|
+
if (!fs.existsSync(androidHome)) {
|
|
80
|
+
fs.mkdirSync(androidHome, { recursive: true });
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
throw new Error(`Failed to create Android directory: ${error instanceof Error ? error.message : String(error)}`);
|
|
85
|
+
}
|
|
86
|
+
console.log('\nDownloading and setting up Android SDK...');
|
|
87
|
+
const sdkUrl = getSdkDownloadUrl(sdkVersion);
|
|
88
|
+
try {
|
|
89
|
+
const cmdlineToolsPath = path.join(androidHome, 'cmdline-tools');
|
|
90
|
+
if (!fs.existsSync(cmdlineToolsPath)) {
|
|
91
|
+
fs.mkdirSync(cmdlineToolsPath, { recursive: true });
|
|
92
|
+
}
|
|
93
|
+
console.log(`Downloading and extracting from: ${sdkUrl}`);
|
|
94
|
+
await (0, unzip_url_1.unzip)(sdkUrl, cmdlineToolsPath);
|
|
95
|
+
const tempToolsPath = path.join(cmdlineToolsPath, 'cmdline-tools');
|
|
96
|
+
const latestToolsPath = path.join(cmdlineToolsPath, 'latest');
|
|
97
|
+
if (fs.existsSync(tempToolsPath)) {
|
|
98
|
+
fs.renameSync(tempToolsPath, latestToolsPath);
|
|
99
|
+
}
|
|
100
|
+
console.log('Android SDK extracted successfully');
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
throw new Error(`Failed to download/extract Android SDK: ${error instanceof Error ? error.message : String(error)}`);
|
|
104
|
+
}
|
|
105
|
+
const sdkmanagerEnv = {
|
|
106
|
+
...process.env,
|
|
107
|
+
ANDROID_HOME: androidHome,
|
|
108
|
+
ANDROID_SDK_ROOT: androidHome,
|
|
109
|
+
PATH: `${androidHome}/cmdline-tools/latest/bin:${process.env.PATH}`,
|
|
110
|
+
};
|
|
111
|
+
console.log('\nAccepting Android SDK licenses...');
|
|
112
|
+
try {
|
|
113
|
+
await (0, execa_1.execa)('bash', ['-c', 'yes | sdkmanager --licenses'], {
|
|
114
|
+
env: sdkmanagerEnv,
|
|
115
|
+
stdio: 'inherit',
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
console.warn('Warning: License acceptance may have failed, but continuing...');
|
|
120
|
+
}
|
|
121
|
+
console.log('\nInstalling Android SDK components...');
|
|
122
|
+
const components = [
|
|
123
|
+
'platform-tools',
|
|
124
|
+
`platforms;${platformVersion}`,
|
|
125
|
+
`build-tools;${buildToolsVersion}`,
|
|
126
|
+
`cmake;${cmakeVersion}`,
|
|
127
|
+
`ndk;${ndkVersion}`,
|
|
128
|
+
];
|
|
129
|
+
try {
|
|
130
|
+
const componentsList = components.join(' ');
|
|
131
|
+
await (0, execa_1.execa)('bash', ['-c', `yes | sdkmanager ${componentsList}`], {
|
|
132
|
+
env: sdkmanagerEnv,
|
|
133
|
+
stdio: 'inherit',
|
|
134
|
+
});
|
|
135
|
+
console.log('Android SDK components installed successfully');
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
throw new Error(`Failed to install SDK components: ${error instanceof Error ? error.message : String(error)}`);
|
|
139
|
+
}
|
|
140
|
+
const androidConfigDir = path.join(androidHome, '.android');
|
|
141
|
+
if (fs.existsSync(androidConfigDir)) {
|
|
142
|
+
fs.rmSync(androidConfigDir, { recursive: true, force: true });
|
|
143
|
+
}
|
|
144
|
+
if (platform === 'linux' && androidHome.startsWith('/opt')) {
|
|
145
|
+
try {
|
|
146
|
+
await (0, execa_1.execa)('chmod', ['-R', '777', androidHome], { stdio: 'inherit' });
|
|
147
|
+
}
|
|
148
|
+
catch (error) {
|
|
149
|
+
console.warn('Warning: Failed to set permissions, but continuing...');
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
console.log('\n✅ Android SDK installation completed!');
|
|
153
|
+
let envVarsAdded = false;
|
|
154
|
+
let shellRcFile;
|
|
155
|
+
if (!options?.skipEnvVars) {
|
|
156
|
+
shellRcFile = getShellRcFile();
|
|
157
|
+
console.log(`\nConfiguring shell environment in: ${shellRcFile}`);
|
|
158
|
+
if (hasAndroidEnvVars(shellRcFile)) {
|
|
159
|
+
console.log('Android environment variables already exist in shell config, skipping...');
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
const envVars = getAndroidEnvVars(androidHome, ndkVersion);
|
|
163
|
+
appendEnvVarsToShellConfig(shellRcFile, envVars);
|
|
164
|
+
envVarsAdded = true;
|
|
165
|
+
}
|
|
166
|
+
console.log('\n📋 To activate the environment in your current shell, run:');
|
|
167
|
+
console.log(` source ${shellRcFile}`);
|
|
168
|
+
}
|
|
169
|
+
console.log('\n✅ Android development environment setup completed successfully!');
|
|
170
|
+
return {
|
|
171
|
+
androidHome,
|
|
172
|
+
envVarsAdded,
|
|
173
|
+
shellRcFile,
|
|
174
|
+
};
|
|
175
|
+
}
|
package/build/dev-setup.js
CHANGED
|
@@ -43,15 +43,15 @@ async function setupDevEnvironment(sshPublicKey, targetDir) {
|
|
|
43
43
|
}
|
|
44
44
|
console.log(`Copying dev-setup to: ${targetPath}`);
|
|
45
45
|
copyDirSync(sourceDir, targetPath);
|
|
46
|
-
const dockerfilePath = path.join(targetPath, 'Dockerfile
|
|
46
|
+
const dockerfilePath = path.join(targetPath, 'Dockerfile');
|
|
47
47
|
if (fs.existsSync(dockerfilePath)) {
|
|
48
48
|
let content = fs.readFileSync(dockerfilePath, 'utf-8');
|
|
49
49
|
content = content.replace('ssh-public-key-placeholder', sshPublicKey);
|
|
50
50
|
fs.writeFileSync(dockerfilePath, content);
|
|
51
|
-
console.log('SSH public key has been configured in Dockerfile
|
|
51
|
+
console.log('SSH public key has been configured in Dockerfile');
|
|
52
52
|
}
|
|
53
53
|
else {
|
|
54
|
-
throw new Error(`Dockerfile
|
|
54
|
+
throw new Error(`Dockerfile not found in ${targetPath}`);
|
|
55
55
|
}
|
|
56
56
|
const hasDockerCompose = await commandExists('docker-compose');
|
|
57
57
|
if (hasDockerCompose) {
|
|
@@ -84,7 +84,7 @@ async function setupDevEnvironment(sshPublicKey, targetDir) {
|
|
|
84
84
|
console.log(' docker-compose build && docker-compose up -d');
|
|
85
85
|
}
|
|
86
86
|
const localIp = ip.address();
|
|
87
|
-
console.log('\n
|
|
87
|
+
console.log('\n SSH Connection:');
|
|
88
88
|
console.log(` ssh gitpod@${localIp} -p 2222`);
|
|
89
89
|
console.log('\nOr use localhost if connecting from the same machine:');
|
|
90
90
|
console.log(' ssh gitpod@localhost -p 2222');
|
package/build/index.d.ts
CHANGED
package/build/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.setupDevEnvironment = void 0;
|
|
3
|
+
exports.setupAndroidEnvironment = exports.setupDevEnvironment = void 0;
|
|
4
4
|
exports.writeClaudeConfig = writeClaudeConfig;
|
|
5
5
|
exports.installDeps = installDeps;
|
|
6
6
|
exports.writeCodexConfig = writeCodexConfig;
|
|
@@ -165,3 +165,5 @@ function writeRaycastConfig(apiKey) {
|
|
|
165
165
|
}
|
|
166
166
|
var dev_setup_1 = require("./dev-setup");
|
|
167
167
|
Object.defineProperty(exports, "setupDevEnvironment", { enumerable: true, get: function () { return dev_setup_1.setupDevEnvironment; } });
|
|
168
|
+
var android_setup_1 = require("./android-setup");
|
|
169
|
+
Object.defineProperty(exports, "setupAndroidEnvironment", { enumerable: true, get: function () { return android_setup_1.setupAndroidEnvironment; } });
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import * as fs from 'fs'
|
|
2
|
+
import * as path from 'path'
|
|
3
|
+
import * as os from 'os'
|
|
4
|
+
import { execa } from 'execa'
|
|
5
|
+
import { unzip } from '@compilets/unzip-url'
|
|
6
|
+
|
|
7
|
+
/** Android SDK configuration */
|
|
8
|
+
const ANDROID_CONFIG = {
|
|
9
|
+
sdkVersion: '11076708',
|
|
10
|
+
platformVersion: 'android-36',
|
|
11
|
+
buildToolsVersion: '36.0.0',
|
|
12
|
+
cmakeVersion: '3.30.5',
|
|
13
|
+
ndkVersion: '29.0.14206865',
|
|
14
|
+
} as const
|
|
15
|
+
|
|
16
|
+
/** Get default Android home directory */
|
|
17
|
+
function getDefaultAndroidHome(): string {
|
|
18
|
+
return path.join(os.homedir(), 'Android')
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** Get SDK download URL based on platform */
|
|
22
|
+
function getSdkDownloadUrl(sdkVersion: string): string {
|
|
23
|
+
const platform = os.platform()
|
|
24
|
+
if (platform === 'darwin') {
|
|
25
|
+
return `https://dl.google.com/android/repository/commandlinetools-mac-${sdkVersion}_latest.zip`
|
|
26
|
+
} else if (platform === 'linux') {
|
|
27
|
+
return `https://dl.google.com/android/repository/commandlinetools-linux-${sdkVersion}_latest.zip`
|
|
28
|
+
} else {
|
|
29
|
+
throw new Error(
|
|
30
|
+
`Unsupported platform: ${platform}. Only macOS and Linux are supported.`
|
|
31
|
+
)
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** Get Android environment variables */
|
|
36
|
+
function getAndroidEnvVars(androidHome: string, ndkVersion: string): string {
|
|
37
|
+
return `
|
|
38
|
+
# Android development environment
|
|
39
|
+
export ANDROID_HOME=${androidHome}
|
|
40
|
+
export ANDROID_SDK_ROOT=\${ANDROID_HOME}
|
|
41
|
+
export ANDROID_NDK_HOME=\${ANDROID_HOME}/ndk/${ndkVersion}
|
|
42
|
+
export PATH=\${ANDROID_HOME}/cmdline-tools/latest/bin:\${ANDROID_HOME}/emulator:\${ANDROID_HOME}/platform-tools:\${ANDROID_HOME}/tools:\${ANDROID_HOME}/tools/bin:\${PATH}
|
|
43
|
+
`
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** Detect shell configuration file */
|
|
47
|
+
function getShellRcFile(): string {
|
|
48
|
+
const shell = process.env.SHELL || ''
|
|
49
|
+
const homeDir = os.homedir()
|
|
50
|
+
|
|
51
|
+
if (shell.includes('zsh')) {
|
|
52
|
+
return path.join(homeDir, '.zshrc')
|
|
53
|
+
} else if (shell.includes('fish')) {
|
|
54
|
+
return path.join(homeDir, '.config', 'fish', 'config.fish')
|
|
55
|
+
} else {
|
|
56
|
+
return path.join(homeDir, '.bashrc')
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** Check if Android environment variables already exist in shell config */
|
|
61
|
+
function hasAndroidEnvVars(rcFile: string): boolean {
|
|
62
|
+
if (!fs.existsSync(rcFile)) {
|
|
63
|
+
return false
|
|
64
|
+
}
|
|
65
|
+
const content = fs.readFileSync(rcFile, 'utf-8')
|
|
66
|
+
return content.includes('ANDROID_HOME')
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** Append Android environment variables to shell config */
|
|
70
|
+
function appendEnvVarsToShellConfig(rcFile: string, envVars: string): void {
|
|
71
|
+
const dir = path.dirname(rcFile)
|
|
72
|
+
if (!fs.existsSync(dir)) {
|
|
73
|
+
fs.mkdirSync(dir, { recursive: true })
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
fs.appendFileSync(rcFile, envVars)
|
|
77
|
+
console.log(`Environment variables added to: ${rcFile}`)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** Setup Android development environment */
|
|
81
|
+
export async function setupAndroidEnvironment(options?: {
|
|
82
|
+
androidHome?: string
|
|
83
|
+
skipEnvVars?: boolean
|
|
84
|
+
}): Promise<{
|
|
85
|
+
androidHome: string
|
|
86
|
+
envVarsAdded: boolean
|
|
87
|
+
shellRcFile?: string
|
|
88
|
+
}> {
|
|
89
|
+
const androidHome = options?.androidHome || getDefaultAndroidHome()
|
|
90
|
+
const {
|
|
91
|
+
sdkVersion,
|
|
92
|
+
platformVersion,
|
|
93
|
+
buildToolsVersion,
|
|
94
|
+
cmakeVersion,
|
|
95
|
+
ndkVersion,
|
|
96
|
+
} = ANDROID_CONFIG
|
|
97
|
+
|
|
98
|
+
console.log('Starting Android development environment setup...\n')
|
|
99
|
+
|
|
100
|
+
// Check if running on supported platform
|
|
101
|
+
const platform = os.platform()
|
|
102
|
+
if (platform !== 'linux' && platform !== 'darwin') {
|
|
103
|
+
throw new Error(
|
|
104
|
+
`Unsupported platform: ${platform}. Only macOS and Linux are supported.`
|
|
105
|
+
)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
console.log(`Platform: ${platform === 'darwin' ? 'macOS' : 'Linux'}`)
|
|
109
|
+
|
|
110
|
+
// Create Android directory
|
|
111
|
+
console.log(`Creating Android SDK directory at: ${androidHome}`)
|
|
112
|
+
try {
|
|
113
|
+
if (!fs.existsSync(androidHome)) {
|
|
114
|
+
fs.mkdirSync(androidHome, { recursive: true })
|
|
115
|
+
}
|
|
116
|
+
} catch (error) {
|
|
117
|
+
throw new Error(
|
|
118
|
+
`Failed to create Android directory: ${error instanceof Error ? error.message : String(error)}`
|
|
119
|
+
)
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Download and setup Android SDK
|
|
123
|
+
console.log('\nDownloading and setting up Android SDK...')
|
|
124
|
+
const sdkUrl = getSdkDownloadUrl(sdkVersion)
|
|
125
|
+
|
|
126
|
+
try {
|
|
127
|
+
// Create cmdline-tools directory
|
|
128
|
+
const cmdlineToolsPath = path.join(androidHome, 'cmdline-tools')
|
|
129
|
+
if (!fs.existsSync(cmdlineToolsPath)) {
|
|
130
|
+
fs.mkdirSync(cmdlineToolsPath, { recursive: true })
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Download and extract SDK using unzip-url
|
|
134
|
+
console.log(`Downloading and extracting from: ${sdkUrl}`)
|
|
135
|
+
await unzip(sdkUrl, cmdlineToolsPath)
|
|
136
|
+
|
|
137
|
+
// Move cmdline-tools to latest
|
|
138
|
+
const tempToolsPath = path.join(cmdlineToolsPath, 'cmdline-tools')
|
|
139
|
+
const latestToolsPath = path.join(cmdlineToolsPath, 'latest')
|
|
140
|
+
if (fs.existsSync(tempToolsPath)) {
|
|
141
|
+
fs.renameSync(tempToolsPath, latestToolsPath)
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
console.log('Android SDK extracted successfully')
|
|
145
|
+
} catch (error) {
|
|
146
|
+
throw new Error(
|
|
147
|
+
`Failed to download/extract Android SDK: ${error instanceof Error ? error.message : String(error)}`
|
|
148
|
+
)
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Set environment variables for sdkmanager
|
|
152
|
+
const sdkmanagerEnv = {
|
|
153
|
+
...process.env,
|
|
154
|
+
ANDROID_HOME: androidHome,
|
|
155
|
+
ANDROID_SDK_ROOT: androidHome,
|
|
156
|
+
PATH: `${androidHome}/cmdline-tools/latest/bin:${process.env.PATH}`,
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Accept licenses
|
|
160
|
+
console.log('\nAccepting Android SDK licenses...')
|
|
161
|
+
try {
|
|
162
|
+
await execa('bash', ['-c', 'yes | sdkmanager --licenses'], {
|
|
163
|
+
env: sdkmanagerEnv,
|
|
164
|
+
stdio: 'inherit',
|
|
165
|
+
})
|
|
166
|
+
} catch (error) {
|
|
167
|
+
console.warn(
|
|
168
|
+
'Warning: License acceptance may have failed, but continuing...'
|
|
169
|
+
)
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Install SDK components
|
|
173
|
+
console.log('\nInstalling Android SDK components...')
|
|
174
|
+
const components = [
|
|
175
|
+
'platform-tools',
|
|
176
|
+
`platforms;${platformVersion}`,
|
|
177
|
+
`build-tools;${buildToolsVersion}`,
|
|
178
|
+
`cmake;${cmakeVersion}`,
|
|
179
|
+
`ndk;${ndkVersion}`,
|
|
180
|
+
]
|
|
181
|
+
|
|
182
|
+
try {
|
|
183
|
+
const componentsList = components.join(' ')
|
|
184
|
+
await execa('bash', ['-c', `yes | sdkmanager ${componentsList}`], {
|
|
185
|
+
env: sdkmanagerEnv,
|
|
186
|
+
stdio: 'inherit',
|
|
187
|
+
})
|
|
188
|
+
console.log('Android SDK components installed successfully')
|
|
189
|
+
} catch (error) {
|
|
190
|
+
throw new Error(
|
|
191
|
+
`Failed to install SDK components: ${error instanceof Error ? error.message : String(error)}`
|
|
192
|
+
)
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Clean up .android directory
|
|
196
|
+
const androidConfigDir = path.join(androidHome, '.android')
|
|
197
|
+
if (fs.existsSync(androidConfigDir)) {
|
|
198
|
+
fs.rmSync(androidConfigDir, { recursive: true, force: true })
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Set permissions (only needed on Linux for system-wide installs)
|
|
202
|
+
if (platform === 'linux' && androidHome.startsWith('/opt')) {
|
|
203
|
+
try {
|
|
204
|
+
await execa('chmod', ['-R', '777', androidHome], { stdio: 'inherit' })
|
|
205
|
+
} catch (error) {
|
|
206
|
+
console.warn('Warning: Failed to set permissions, but continuing...')
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
console.log('\n✅ Android SDK installation completed!')
|
|
211
|
+
|
|
212
|
+
// Handle environment variables
|
|
213
|
+
let envVarsAdded = false
|
|
214
|
+
let shellRcFile: string | undefined
|
|
215
|
+
|
|
216
|
+
if (!options?.skipEnvVars) {
|
|
217
|
+
shellRcFile = getShellRcFile()
|
|
218
|
+
console.log(`\nConfiguring shell environment in: ${shellRcFile}`)
|
|
219
|
+
|
|
220
|
+
if (hasAndroidEnvVars(shellRcFile)) {
|
|
221
|
+
console.log(
|
|
222
|
+
'Android environment variables already exist in shell config, skipping...'
|
|
223
|
+
)
|
|
224
|
+
} else {
|
|
225
|
+
const envVars = getAndroidEnvVars(androidHome, ndkVersion)
|
|
226
|
+
appendEnvVarsToShellConfig(shellRcFile, envVars)
|
|
227
|
+
envVarsAdded = true
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
console.log('\n📋 To activate the environment in your current shell, run:')
|
|
231
|
+
console.log(` source ${shellRcFile}`)
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
console.log(
|
|
235
|
+
'\n✅ Android development environment setup completed successfully!'
|
|
236
|
+
)
|
|
237
|
+
|
|
238
|
+
return {
|
|
239
|
+
androidHome,
|
|
240
|
+
envVarsAdded,
|
|
241
|
+
shellRcFile,
|
|
242
|
+
}
|
|
243
|
+
}
|
package/libs/dev-setup.ts
CHANGED
|
@@ -57,15 +57,15 @@ export async function setupDevEnvironment(
|
|
|
57
57
|
console.log(`Copying dev-setup to: ${targetPath}`)
|
|
58
58
|
copyDirSync(sourceDir, targetPath)
|
|
59
59
|
|
|
60
|
-
// Replace SSH_PUBLIC_KEY placeholder in Dockerfile
|
|
61
|
-
const dockerfilePath = path.join(targetPath, 'Dockerfile
|
|
60
|
+
// Replace SSH_PUBLIC_KEY placeholder in Dockerfile
|
|
61
|
+
const dockerfilePath = path.join(targetPath, 'Dockerfile')
|
|
62
62
|
if (fs.existsSync(dockerfilePath)) {
|
|
63
63
|
let content = fs.readFileSync(dockerfilePath, 'utf-8')
|
|
64
64
|
content = content.replace('ssh-public-key-placeholder', sshPublicKey)
|
|
65
65
|
fs.writeFileSync(dockerfilePath, content)
|
|
66
|
-
console.log('SSH public key has been configured in Dockerfile
|
|
66
|
+
console.log('SSH public key has been configured in Dockerfile')
|
|
67
67
|
} else {
|
|
68
|
-
throw new Error(`Dockerfile
|
|
68
|
+
throw new Error(`Dockerfile not found in ${targetPath}`)
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
// Check if docker-compose is available
|
|
@@ -109,7 +109,7 @@ export async function setupDevEnvironment(
|
|
|
109
109
|
|
|
110
110
|
// Display SSH connection instructions
|
|
111
111
|
const localIp = ip.address()
|
|
112
|
-
console.log('\n
|
|
112
|
+
console.log('\n SSH Connection:')
|
|
113
113
|
console.log(` ssh gitpod@${localIp} -p 2222`)
|
|
114
114
|
console.log('\nOr use localhost if connecting from the same machine:')
|
|
115
115
|
console.log(' ssh gitpod@localhost -p 2222')
|
package/libs/index.ts
CHANGED
|
@@ -210,3 +210,6 @@ export function writeRaycastConfig(apiKey: string): { configPath: string } {
|
|
|
210
210
|
|
|
211
211
|
// Re-export dev-setup functionality
|
|
212
212
|
export { setupDevEnvironment } from './dev-setup'
|
|
213
|
+
|
|
214
|
+
// Re-export android-setup functionality
|
|
215
|
+
export { setupAndroidEnvironment } from './android-setup'
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gengjiawen/os-init",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.7.0",
|
|
5
5
|
"description": "",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"bin": {
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"scripts": {
|
|
11
11
|
"dev": "tsc -w",
|
|
12
12
|
"server": "nodemon --exec ts-node libs/index.ts",
|
|
13
|
-
"prepare": "husky
|
|
13
|
+
"prepare": "husky",
|
|
14
14
|
"clean": "rimraf build",
|
|
15
15
|
"format": "prettier --write \"{examples,libs,script,bin}/**/*.{js,ts}\" \"**/*.yml\"",
|
|
16
16
|
"format:check": "prettier --list-different \"{examples,libs,script,bin}/**/*.{js,ts}\" \"**/*.yml\"",
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
"postbuild": "cpy '**/*' '!**/*.ts' ../build/ --cwd=libs --parents"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
+
"@compilets/unzip-url": "^1.0.0",
|
|
22
23
|
"commander": "^12.1.0",
|
|
23
24
|
"ip": "^2.0.1",
|
|
24
25
|
"execa": "^8.0.1"
|