Skip to content

Commit 81d5a01

Browse files
committed
Merge remote-tracking branch 'nativescript/main'
# Conflicts: # package.json
2 parents ffcfde8 + a64f25b commit 81d5a01

11 files changed

Lines changed: 218 additions & 54 deletions

.prettierrc.json

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
11
{
2-
"useTabs": true
2+
"useTabs": true,
3+
"overrides": [
4+
{
5+
"files": "*.json",
6+
"options": {
7+
"useTabs": false
8+
}
9+
}
10+
]
311
}

CHANGELOG.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,29 @@
1+
## [8.7.2](https://github.com/NativeScript/nativescript-cli/compare/v8.7.1...v8.7.2) (2024-05-28)
2+
3+
### Bug Fixes
4+
5+
* fix `npm i -g nativescript` on npm 10.4.0+ ([9d2ec7c](https://github.com/NativeScript/nativescript-cli/commit/9d2ec7cb6a12ea10439ea287991812645a156473))
6+
7+
### Features
8+
9+
* don't uninstall app by default ([bac14c0](https://github.com/NativeScript/nativescript-cli/commit/bac14c06568c7a0538618d9ca1e369a56dd272b5))
10+
11+
12+
13+
## [8.7.1](https://github.com/NativeScript/nativescript-cli/compare/v8.7.0...v8.7.1) (2024-05-16)
14+
15+
16+
### Bug Fixes
17+
18+
* **windows:** make compatible with latest node patch levels ([#5802](https://github.com/NativeScript/nativescript-cli/issues/5802)) ([8795e98](https://github.com/NativeScript/nativescript-cli/commit/8795e98e7876d11ac0032135607fb13bf00d246d))
19+
20+
21+
### Features
22+
23+
* interactive typings generation for android ([#5798](https://github.com/NativeScript/nativescript-cli/issues/5798)) ([d3f2e70](https://github.com/NativeScript/nativescript-cli/commit/d3f2e70101d44a9bc8450c5d0b90419945c2604f))
24+
25+
26+
127
# [8.7.0](https://github.com/NativeScript/nativescript-cli/compare/v8.6.5...v8.7.0) (2024-04-08)
228

329

lib/base-package-manager.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ export abstract class BasePackageManager implements INodePackageManager {
111111
await this.$childProcess.spawnFromEvent(npmExecutable, params, "close", {
112112
cwd: opts.cwd,
113113
stdio: stdioValue,
114+
shell: this.$hostInfo.isWindows,
114115
});
115116

116117
// Whenever calling "npm install" or "yarn add" without any arguments (hence installing all dependencies) no output is emitted on stdout

lib/commands/typings.ts

Lines changed: 101 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1-
import { IOptions, IStaticConfig } from "../declarations";
1+
import { glob } from "glob";
2+
import { homedir } from "os";
3+
import * as path from "path";
4+
import { PromptObject } from "prompts";
5+
import { color } from "../color";
26
import { IChildProcess, IFileSystem, IHostInfo } from "../common/declarations";
37
import { ICommand, ICommandParameter } from "../common/definitions/commands";
48
import { injector } from "../common/yok";
9+
import { IOptions, IStaticConfig } from "../declarations";
510
import { IProjectData } from "../definitions/project";
6-
import * as path from "path";
711

812
export class TypingsCommand implements ICommand {
913
public allowedParameters: ICommandParameter[] = [];
@@ -15,7 +19,8 @@ export class TypingsCommand implements ICommand {
1519
private $mobileHelper: Mobile.IMobileHelper,
1620
private $childProcess: IChildProcess,
1721
private $hostInfo: IHostInfo,
18-
private $staticConfig: IStaticConfig
22+
private $staticConfig: IStaticConfig,
23+
private $prompter: IPrompter
1924
) {}
2025

2126
public async execute(args: string[]): Promise<void> {
@@ -49,8 +54,98 @@ export class TypingsCommand implements ICommand {
4954
return true;
5055
}
5156

57+
private async resolveGradleDependencies(target: string) {
58+
const gradleHome = path.resolve(
59+
process.env.GRADLE_USER_HOME ?? path.join(homedir(), `/.gradle`)
60+
);
61+
const gradleFiles = path.resolve(gradleHome, "caches/modules-2/files-2.1/");
62+
63+
if (!this.$fs.exists(gradleFiles)) {
64+
this.$logger.warn("No gradle files found");
65+
return;
66+
}
67+
68+
const pattern = `${target.replaceAll(":", "/")}/**/*.{jar,aar}`;
69+
70+
const res = await glob(pattern, {
71+
cwd: gradleFiles,
72+
});
73+
74+
if (!res || res.length === 0) {
75+
this.$logger.warn("No files found");
76+
return [];
77+
}
78+
79+
const items = res.map((item) => {
80+
const [group, artifact, version, sha1, file] = item.split("/");
81+
return {
82+
id: sha1 + version,
83+
group,
84+
artifact,
85+
version,
86+
sha1,
87+
file,
88+
path: path.resolve(gradleFiles, item),
89+
};
90+
});
91+
92+
this.$logger.clearScreen();
93+
94+
const choices = await this.$prompter.promptForChoice(
95+
`Select dependencies to generate typings for (${color.greenBright(
96+
target
97+
)})`,
98+
items
99+
.sort((a, b) => {
100+
if (a.artifact < b.artifact) return -1;
101+
if (a.artifact > b.artifact) return 1;
102+
103+
return a.version.localeCompare(b.version, undefined, {
104+
numeric: true,
105+
sensitivity: "base",
106+
});
107+
})
108+
.map((item) => {
109+
return {
110+
title: `${color.white(item.group)}:${color.greenBright(
111+
item.artifact
112+
)}:${color.yellow(item.version)} - ${color.cyanBright.bold(
113+
item.file
114+
)}`,
115+
value: item.id,
116+
};
117+
}),
118+
true,
119+
{
120+
optionsPerPage: process.stdout.rows - 6, // 6 lines are taken up by the instructions
121+
} as Partial<PromptObject>
122+
);
123+
124+
this.$logger.clearScreen();
125+
126+
return items
127+
.filter((item) => choices.includes(item.id))
128+
.map((item) => item.path);
129+
}
130+
52131
private async handleAndroidTypings() {
53-
if (!(this.$options.jar || this.$options.aar)) {
132+
const targets = this.$options.argv._.slice(2) ?? [];
133+
const paths: string[] = [];
134+
135+
if (targets.length) {
136+
for (const target of targets) {
137+
try {
138+
paths.push(...(await this.resolveGradleDependencies(target)));
139+
} catch (err) {
140+
this.$logger.trace(
141+
`Failed to resolve gradle dependencies for target "${target}"`,
142+
err
143+
);
144+
}
145+
}
146+
}
147+
148+
if (!paths.length && !(this.$options.jar || this.$options.aar)) {
54149
this.$logger.warn(
55150
[
56151
"No .jar or .aar file specified. Please specify at least one of the following:",
@@ -78,7 +173,7 @@ export class TypingsCommand implements ICommand {
78173
this.$hostInfo.isWindows ? "ns.cmd" : "ns",
79174
["prepare", "android"],
80175
"exit",
81-
{ stdio: "inherit" }
176+
{ stdio: "inherit", shell: this.$hostInfo.isWindows }
82177
);
83178
}
84179

@@ -97,6 +192,7 @@ export class TypingsCommand implements ICommand {
97192
const inputs: string[] = [
98193
...asArray(this.$options.jar),
99194
...asArray(this.$options.aar),
195+
...paths,
100196
];
101197

102198
await this.$childProcess.spawnFromEvent(

lib/common/mobile/android/android-virtual-device-service.ts

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ import {
2222
import { injector } from "../../yok";
2323

2424
export class AndroidVirtualDeviceService
25-
implements Mobile.IAndroidVirtualDeviceService {
25+
implements Mobile.IAndroidVirtualDeviceService
26+
{
2627
private androidHome: string;
2728
private mapEmulatorIdToImageIdentifier: IStringDictionary = {};
2829

@@ -211,7 +212,8 @@ export class AndroidVirtualDeviceService
211212
let result: ISpawnResult = null;
212213
let devices: Mobile.IDeviceInfo[] = [];
213214
let errors: string[] = [];
214-
const canExecuteAvdManagerCommand = await this.canExecuteAvdManagerCommand();
215+
const canExecuteAvdManagerCommand =
216+
await this.canExecuteAvdManagerCommand();
215217
if (!canExecuteAvdManagerCommand) {
216218
errors = [
217219
"Unable to execute avdmanager, ensure JAVA_HOME is set and points to correct directory",
@@ -221,7 +223,8 @@ export class AndroidVirtualDeviceService
221223
if (canExecuteAvdManagerCommand) {
222224
result = await this.$childProcess.trySpawnFromCloseEvent(
223225
this.pathToAvdManagerExecutable,
224-
["list", "avds"]
226+
["list", "avds"],
227+
{ shell: this.$hostInfo.isWindows }
225228
);
226229
} else if (
227230
this.pathToAndroidExecutable &&
@@ -403,9 +406,8 @@ export class AndroidVirtualDeviceService
403406
private getAvdManagerDeviceInfo(
404407
output: string
405408
): Mobile.IAvdManagerDeviceInfo {
406-
const avdManagerDeviceInfo: Mobile.IAvdManagerDeviceInfo = Object.create(
407-
null
408-
);
409+
const avdManagerDeviceInfo: Mobile.IAvdManagerDeviceInfo =
410+
Object.create(null);
409411

410412
// Split by `\n`, not EOL as the avdmanager and android executables print results with `\n` only even on Windows
411413
_.reduce(
@@ -437,9 +439,8 @@ export class AndroidVirtualDeviceService
437439
avdFilePath,
438440
AndroidVirtualDevice.CONFIG_INI_FILE_NAME
439441
);
440-
const configIniFileInfo = this.$androidIniFileParser.parseIniFile(
441-
configIniFilePath
442-
);
442+
const configIniFileInfo =
443+
this.$androidIniFileParser.parseIniFile(configIniFilePath);
443444

444445
const iniFilePath = this.getIniFilePath(configIniFileInfo, avdFilePath);
445446
const iniFileInfo = this.$androidIniFileParser.parseIniFile(iniFilePath);

lib/common/mobile/application-manager-base.ts

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ import * as _ from "lodash";
66

77
export abstract class ApplicationManagerBase
88
extends EventEmitter
9-
implements Mobile.IDeviceApplicationManager {
9+
implements Mobile.IDeviceApplicationManager
10+
{
1011
private lastInstalledAppIdentifiers: string[];
1112
private lastAvailableDebuggableApps: Mobile.IDeviceApplicationInformation[];
1213
private lastAvailableDebuggableAppViews: IDictionary<
@@ -36,7 +37,7 @@ export abstract class ApplicationManagerBase
3637
appIdentifier
3738
);
3839

39-
if (isApplicationInstalled) {
40+
if (isApplicationInstalled && buildData?.clean) {
4041
await this.uninstallApplication(appIdentifier);
4142
}
4243

@@ -65,7 +66,8 @@ export abstract class ApplicationManagerBase
6566
// use locking, so the next executions will not get into the body, while the first one is still working.
6667
// In case we do not break the next executions, we'll report each app as newly installed several times.
6768
try {
68-
const currentlyInstalledAppIdentifiers = await this.getInstalledApplications();
69+
const currentlyInstalledAppIdentifiers =
70+
await this.getInstalledApplications();
6971
const previouslyInstalledAppIdentifiers =
7072
this.lastInstalledAppIdentifiers || [];
7173

@@ -122,9 +124,7 @@ export abstract class ApplicationManagerBase
122124
appIdentifier?: string,
123125
buildData?: IBuildData
124126
): Promise<void>;
125-
public abstract uninstallApplication(
126-
appIdentifier: string
127-
): Promise<void>;
127+
public abstract uninstallApplication(appIdentifier: string): Promise<void>;
128128
public abstract startApplication(
129129
appData: Mobile.IApplicationData
130130
): Promise<void>;
@@ -190,9 +190,8 @@ export abstract class ApplicationManagerBase
190190
_.each(
191191
currentlyAvailableAppViews,
192192
(currentlyAvailableViews, appIdentifier) => {
193-
const previouslyAvailableViews = this.lastAvailableDebuggableAppViews[
194-
appIdentifier
195-
];
193+
const previouslyAvailableViews =
194+
this.lastAvailableDebuggableAppViews[appIdentifier];
196195

197196
const newAvailableViews = _.differenceBy(
198197
currentlyAvailableViews,
@@ -229,9 +228,8 @@ export abstract class ApplicationManagerBase
229228
}
230229
});
231230

232-
this.lastAvailableDebuggableAppViews[
233-
appIdentifier
234-
] = currentlyAvailableViews;
231+
this.lastAvailableDebuggableAppViews[appIdentifier] =
232+
currentlyAvailableViews;
235233
}
236234
);
237235
}

lib/common/test/unit-tests/mobile/application-manager-base.ts

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -321,9 +321,8 @@ describe("ApplicationManagerBase", () => {
321321
currentlyAvailableAppsForDebugging,
322322
numberOfViewsPerApp
323323
);
324-
const currentDebuggableViews: IDictionary<
325-
Mobile.IDebugWebViewInfo[]
326-
> = {};
324+
const currentDebuggableViews: IDictionary<Mobile.IDebugWebViewInfo[]> =
325+
{};
327326
applicationManager.on(
328327
"debuggableViewFound",
329328
(appIdentifier: string, d: Mobile.IDebugWebViewInfo) => {
@@ -368,9 +367,8 @@ describe("ApplicationManagerBase", () => {
368367
const expectedResults = _.cloneDeep(
369368
currentlyAvailableAppWebViewsForDebugging
370369
);
371-
const currentDebuggableViews: IDictionary<
372-
Mobile.IDebugWebViewInfo[]
373-
> = {};
370+
const currentDebuggableViews: IDictionary<Mobile.IDebugWebViewInfo[]> =
371+
{};
374372

375373
applicationManager
376374
.checkForApplicationUpdates()
@@ -819,9 +817,8 @@ describe("ApplicationManagerBase", () => {
819817
removedApps = removedApps.concat(currentlyRemovedApps);
820818

821819
const currentlyAddedApps = [`app${index}`];
822-
currentlyInstalledApps = currentlyInstalledApps.concat(
823-
currentlyAddedApps
824-
);
820+
currentlyInstalledApps =
821+
currentlyInstalledApps.concat(currentlyAddedApps);
825822
installedApps = installedApps.concat(currentlyAddedApps);
826823

827824
await testInstalledAppsResults();
@@ -1004,7 +1001,11 @@ describe("ApplicationManagerBase", () => {
10041001
applicationManager.isApplicationInstalled = (appIdentifier: string) =>
10051002
Promise.resolve(true);
10061003

1007-
await applicationManager.reinstallApplication("appId", "packageFilePath");
1004+
await applicationManager.reinstallApplication(
1005+
"appId",
1006+
"packageFilePath",
1007+
{ clean: true } as any
1008+
);
10081009
assert.deepStrictEqual(uninstallApplicationAppIdParam, "appId");
10091010
});
10101011

@@ -1047,7 +1048,11 @@ describe("ApplicationManagerBase", () => {
10471048
return Promise.resolve();
10481049
};
10491050

1050-
await applicationManager.reinstallApplication("appId", "packageFilePath");
1051+
await applicationManager.reinstallApplication(
1052+
"appId",
1053+
"packageFilePath",
1054+
{ clean: true } as any
1055+
);
10511056

10521057
assert.isTrue(
10531058
isUninstallApplicationCalled,

lib/services/android-plugin-build-service.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -797,6 +797,7 @@ export class AndroidPluginBuildService implements IAndroidPluginBuildService {
797797
await this.$childProcess.spawnFromEvent(gradlew, localArgs, "close", {
798798
cwd: pluginBuildSettings.pluginDir,
799799
stdio: "inherit",
800+
shell: this.$hostInfo.isWindows,
800801
});
801802
} catch (err) {
802803
this.$errors.fail(

0 commit comments

Comments
 (0)