@jetstart/cli 1.5.2 → 1.5.3

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.
@@ -26,7 +26,15 @@ export declare class AndroidSDKManager {
26
26
  */
27
27
  installCmdlineTools(): Promise<void>;
28
28
  /**
29
- * Get path to sdkmanager executable
29
+ * Resolve sdkmanager path and tools root
30
+ * Checks multiple standard paths:
31
+ * 1. cmdline-tools/latest/bin (Standard)
32
+ * 2. cmdline-tools/bin (Alternative)
33
+ * 3. tools/bin (Legacy)
34
+ */
35
+ private resolveSDKToolsPath;
36
+ /**
37
+ * Get path to sdkmanager executable (Legacy method, kept for reference but unused internally now)
30
38
  */
31
39
  private getSDKManagerPath;
32
40
  /**
@@ -122,7 +122,38 @@ class AndroidSDKManager {
122
122
  (0, logger_1.success)('Android cmdline-tools installed');
123
123
  }
124
124
  /**
125
- * Get path to sdkmanager executable
125
+ * Resolve sdkmanager path and tools root
126
+ * Checks multiple standard paths:
127
+ * 1. cmdline-tools/latest/bin (Standard)
128
+ * 2. cmdline-tools/bin (Alternative)
129
+ * 3. tools/bin (Legacy)
130
+ */
131
+ async resolveSDKToolsPath() {
132
+ const sdkmanagerName = os.platform() === 'win32' ? 'sdkmanager.bat' : 'sdkmanager';
133
+ // Potential paths to check (in order of preference)
134
+ const candidates = [
135
+ {
136
+ bin: path.join(this.sdkRoot, 'cmdline-tools', 'latest', 'bin', sdkmanagerName),
137
+ root: path.join(this.sdkRoot, 'cmdline-tools', 'latest')
138
+ },
139
+ {
140
+ bin: path.join(this.sdkRoot, 'cmdline-tools', 'bin', sdkmanagerName),
141
+ root: path.join(this.sdkRoot, 'cmdline-tools')
142
+ },
143
+ {
144
+ bin: path.join(this.sdkRoot, 'tools', 'bin', sdkmanagerName),
145
+ root: path.join(this.sdkRoot, 'tools')
146
+ }
147
+ ];
148
+ for (const candidate of candidates) {
149
+ if (await fs.pathExists(candidate.bin)) {
150
+ return { binPath: candidate.bin, toolsRoot: candidate.root };
151
+ }
152
+ }
153
+ return { binPath: null, toolsRoot: '' };
154
+ }
155
+ /**
156
+ * Get path to sdkmanager executable (Legacy method, kept for reference but unused internally now)
126
157
  */
127
158
  getSDKManagerPath() {
128
159
  const sdkmanagerName = os.platform() === 'win32' ? 'sdkmanager.bat' : 'sdkmanager';
@@ -139,19 +170,19 @@ class AndroidSDKManager {
139
170
  * Run sdkmanager command
140
171
  */
141
172
  async runSDKManager(args, onProgress) {
142
- const sdkmanagerPath = this.getSDKManagerPath();
143
- if (!(await fs.pathExists(sdkmanagerPath))) {
173
+ // Resolve proper sdkmanager path and tools root
174
+ const { binPath, toolsRoot } = await this.resolveSDKToolsPath();
175
+ if (!binPath) {
144
176
  throw new Error('sdkmanager not found. Install cmdline-tools first.');
145
177
  }
146
178
  return new Promise((resolve, reject) => {
147
- const proc = (0, child_process_1.spawn)(sdkmanagerPath, args, {
179
+ const proc = (0, child_process_1.spawn)(binPath, args, {
148
180
  env: {
149
181
  ...process.env,
150
182
  ANDROID_HOME: this.sdkRoot,
151
183
  ANDROID_SDK_ROOT: this.sdkRoot,
152
184
  // Accept licenses automatically
153
- JAVA_OPTS: '-Dcom.android.sdkmanager.toolsdir=' +
154
- path.join(this.sdkRoot, 'cmdline-tools', 'latest'),
185
+ JAVA_OPTS: '-Dcom.android.sdkmanager.toolsdir=' + toolsRoot,
155
186
  },
156
187
  shell: true,
157
188
  });
@@ -198,20 +229,19 @@ class AndroidSDKManager {
198
229
  async acceptLicenses() {
199
230
  const spinner = (0, spinner_1.startSpinner)('Accepting SDK licenses...');
200
231
  try {
201
- const sdkmanagerPath = this.getSDKManagerPath();
202
- // Add path validation (like runSDKManager does)
203
- if (!(await fs.pathExists(sdkmanagerPath))) {
232
+ // Resolve tools path
233
+ const { binPath, toolsRoot } = await this.resolveSDKToolsPath();
234
+ if (!binPath) {
204
235
  throw new Error('sdkmanager not found. Install cmdline-tools first.');
205
236
  }
206
237
  await new Promise((resolve, reject) => {
207
- const proc = (0, child_process_1.spawn)(sdkmanagerPath, ['--licenses'], {
238
+ const proc = (0, child_process_1.spawn)(binPath, ['--licenses'], {
208
239
  env: {
209
240
  ...process.env,
210
241
  ANDROID_HOME: this.sdkRoot,
211
242
  ANDROID_SDK_ROOT: this.sdkRoot,
212
243
  // ADD MISSING JAVA_OPTS (critical fix)
213
- JAVA_OPTS: '-Dcom.android.sdkmanager.toolsdir=' +
214
- path.join(this.sdkRoot, 'cmdline-tools', 'latest'),
244
+ JAVA_OPTS: '-Dcom.android.sdkmanager.toolsdir=' + toolsRoot,
215
245
  },
216
246
  // ADD explicit stdio configuration
217
247
  stdio: ['pipe', 'pipe', 'pipe'],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jetstart/cli",
3
- "version": "1.5.2",
3
+ "version": "1.5.3",
4
4
  "description": "Command-line interface for JetStart",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -36,8 +36,8 @@
36
36
  },
37
37
  "homepage": "https://github.com/dev-phantom/jetstart#readme",
38
38
  "dependencies": {
39
- "@jetstart/core": "^1.5.2",
40
- "@jetstart/shared": "^1.5.2",
39
+ "@jetstart/core": "^1.5.3",
40
+ "@jetstart/shared": "^1.5.3",
41
41
  "axios": "^1.6.2",
42
42
  "chalk": "^4.1.2",
43
43
  "commander": "^11.1.0",
@@ -111,7 +111,42 @@ export class AndroidSDKManager {
111
111
  }
112
112
 
113
113
  /**
114
- * Get path to sdkmanager executable
114
+ * Resolve sdkmanager path and tools root
115
+ * Checks multiple standard paths:
116
+ * 1. cmdline-tools/latest/bin (Standard)
117
+ * 2. cmdline-tools/bin (Alternative)
118
+ * 3. tools/bin (Legacy)
119
+ */
120
+ private async resolveSDKToolsPath(): Promise<{ binPath: string | null; toolsRoot: string }> {
121
+ const sdkmanagerName = os.platform() === 'win32' ? 'sdkmanager.bat' : 'sdkmanager';
122
+
123
+ // Potential paths to check (in order of preference)
124
+ const candidates = [
125
+ {
126
+ bin: path.join(this.sdkRoot, 'cmdline-tools', 'latest', 'bin', sdkmanagerName),
127
+ root: path.join(this.sdkRoot, 'cmdline-tools', 'latest')
128
+ },
129
+ {
130
+ bin: path.join(this.sdkRoot, 'cmdline-tools', 'bin', sdkmanagerName),
131
+ root: path.join(this.sdkRoot, 'cmdline-tools')
132
+ },
133
+ {
134
+ bin: path.join(this.sdkRoot, 'tools', 'bin', sdkmanagerName),
135
+ root: path.join(this.sdkRoot, 'tools')
136
+ }
137
+ ];
138
+
139
+ for (const candidate of candidates) {
140
+ if (await fs.pathExists(candidate.bin)) {
141
+ return { binPath: candidate.bin, toolsRoot: candidate.root };
142
+ }
143
+ }
144
+
145
+ return { binPath: null, toolsRoot: '' };
146
+ }
147
+
148
+ /**
149
+ * Get path to sdkmanager executable (Legacy method, kept for reference but unused internally now)
115
150
  */
116
151
  private getSDKManagerPath(): string {
117
152
  const sdkmanagerName = os.platform() === 'win32' ? 'sdkmanager.bat' : 'sdkmanager';
@@ -133,22 +168,22 @@ export class AndroidSDKManager {
133
168
  args: string[],
134
169
  onProgress?: (progress: number, message: string) => void
135
170
  ): Promise<string> {
136
- const sdkmanagerPath = this.getSDKManagerPath();
171
+ // Resolve proper sdkmanager path and tools root
172
+ const { binPath, toolsRoot } = await this.resolveSDKToolsPath();
137
173
 
138
- if (!(await fs.pathExists(sdkmanagerPath))) {
174
+ if (!binPath) {
139
175
  throw new Error('sdkmanager not found. Install cmdline-tools first.');
140
176
  }
141
177
 
142
178
  return new Promise((resolve, reject) => {
143
- const proc = spawn(sdkmanagerPath, args, {
179
+ const proc = spawn(binPath, args, {
144
180
  env: {
145
181
  ...process.env,
146
182
  ANDROID_HOME: this.sdkRoot,
147
183
  ANDROID_SDK_ROOT: this.sdkRoot,
148
184
  // Accept licenses automatically
149
185
  JAVA_OPTS:
150
- '-Dcom.android.sdkmanager.toolsdir=' +
151
- path.join(this.sdkRoot, 'cmdline-tools', 'latest'),
186
+ '-Dcom.android.sdkmanager.toolsdir=' + toolsRoot,
152
187
  },
153
188
  shell: true,
154
189
  });
@@ -208,23 +243,22 @@ export class AndroidSDKManager {
208
243
  const spinner = startSpinner('Accepting SDK licenses...');
209
244
 
210
245
  try {
211
- const sdkmanagerPath = this.getSDKManagerPath();
246
+ // Resolve tools path
247
+ const { binPath, toolsRoot } = await this.resolveSDKToolsPath();
212
248
 
213
- // Add path validation (like runSDKManager does)
214
- if (!(await fs.pathExists(sdkmanagerPath))) {
249
+ if (!binPath) {
215
250
  throw new Error('sdkmanager not found. Install cmdline-tools first.');
216
251
  }
217
252
 
218
253
  await new Promise<void>((resolve, reject) => {
219
- const proc = spawn(sdkmanagerPath, ['--licenses'], {
254
+ const proc = spawn(binPath, ['--licenses'], {
220
255
  env: {
221
256
  ...process.env,
222
257
  ANDROID_HOME: this.sdkRoot,
223
258
  ANDROID_SDK_ROOT: this.sdkRoot,
224
259
  // ADD MISSING JAVA_OPTS (critical fix)
225
260
  JAVA_OPTS:
226
- '-Dcom.android.sdkmanager.toolsdir=' +
227
- path.join(this.sdkRoot, 'cmdline-tools', 'latest'),
261
+ '-Dcom.android.sdkmanager.toolsdir=' + toolsRoot,
228
262
  },
229
263
  // ADD explicit stdio configuration
230
264
  stdio: ['pipe', 'pipe', 'pipe'],