Skip to content

Commit 892e682

Browse files
committed
Merge branch 'master' of github.com:farfromrefug/nativescript-cli
2 parents 0b2d85c + 3ef5d47 commit 892e682

24 files changed

+520
-95
lines changed

.github/workflows/npm_release_cli.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@ jobs:
1616

1717
steps:
1818
- uses: actions/checkout@v2
19-
19+
20+
- uses: actions/setup-node@v3
21+
with:
22+
node-version: 18
2023

2124
- name: Setup
2225
run: npm i --ignore-scripts --legacy-peer-deps --no-package-lock

CHANGELOG.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,48 @@
1+
## [8.3.2](https://github.com/NativeScript/nativescript-cli/compare/v8.3.1...v8.3.2) (2022-07-31)
2+
3+
4+
### Bug Fixes
5+
6+
* **logger:** don't trim text if maxWidth is NaN or <10 ([5415582](https://github.com/NativeScript/nativescript-cli/commit/541558270d54be32f2d38f0848a958e0cbca2a0b))
7+
8+
9+
10+
## [8.3.1](https://github.com/NativeScript/nativescript-cli/compare/v8.3.0...v8.3.1) (2022-07-29)
11+
12+
13+
### Bug Fixes
14+
15+
* use correct path to emulator executable ([#5663](https://github.com/NativeScript/nativescript-cli/issues/5663)) ([d49b666](https://github.com/NativeScript/nativescript-cli/commit/d49b6664f216456f84bfbf3dc5f1b362588e1951))
16+
17+
18+
### Features
19+
20+
* **migrate:** update to 8.3 ([#5685](https://github.com/NativeScript/nativescript-cli/issues/5685)) ([50de194](https://github.com/NativeScript/nativescript-cli/commit/50de1946986b634bd3a9cf6d06d5f9b0c93a3caf))
21+
22+
23+
24+
# [8.3.0](https://github.com/NativeScript/nativescript-cli/compare/v8.2.3...v8.3.0) (2022-07-25)
25+
26+
27+
### Bug Fixes
28+
29+
* **ios-publish:** Update API calls to get applications ([#5678](https://github.com/NativeScript/nativescript-cli/issues/5678)) ([4abe2c9](https://github.com/NativeScript/nativescript-cli/commit/4abe2c901829b28f1e1fa26009996db96af06047))
30+
* **unit-test-runner:** node 18 binding family ([#5673](https://github.com/NativeScript/nativescript-cli/issues/5673)) ([1da28bc](https://github.com/NativeScript/nativescript-cli/commit/1da28bcb506650a0c43f468a43f4d577a7d9d3d4))
31+
* ios log filtering ([#5679](https://github.com/NativeScript/nativescript-cli/issues/5679)) ([8446000](https://github.com/NativeScript/nativescript-cli/commit/8446000ec7580fdc2aff4d7154edd174bf2d1d52))
32+
33+
34+
### Features
35+
36+
* bump @nativescript/doctor version ([893989b](https://github.com/NativeScript/nativescript-cli/commit/893989b250c6372937a67f4c55ac05e92c1f26a8))
37+
* cleaner log output ([#5680](https://github.com/NativeScript/nativescript-cli/issues/5680)) ([5330207](https://github.com/NativeScript/nativescript-cli/commit/53302079e30580242e7bf4f9cad88f9b37d1a789))
38+
* **doctor:** add android-33 to supported sdks ([b8f15a0](https://github.com/NativeScript/nativescript-cli/commit/b8f15a06ffab855ed7f77b580b6421650bbed52a))
39+
* **migrate:** use Angular 14.1 ([#5681](https://github.com/NativeScript/nativescript-cli/issues/5681)) ([d5d4206](https://github.com/NativeScript/nativescript-cli/commit/d5d4206c4041e10e4abb0e11ae6f7a9c8c89412e))
40+
* add watchAction hooks ([#5661](https://github.com/NativeScript/nativescript-cli/issues/5661)) ([bb3a696](https://github.com/NativeScript/nativescript-cli/commit/bb3a6965792cc565ab6d516c30a640ac98313ee7))
41+
* alias --simulator to --emulator ([e9d9d5a](https://github.com/NativeScript/nativescript-cli/commit/e9d9d5a878c455d9a69cc1416fe21d07c1c5e5c4))
42+
* re-enable preview command ([#5676](https://github.com/NativeScript/nativescript-cli/issues/5676)) ([98124e7](https://github.com/NativeScript/nativescript-cli/commit/98124e70a8867ad6161a199ee11129ca6b269eb4))
43+
44+
45+
146
## [8.2.3](https://github.com/NativeScript/nativescript-cli/compare/v8.2.2...v8.2.3) (2022-03-23)
247

348

lib/bootstrap.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,10 @@ injector.require(
154154
"./services/android-device-debug-service"
155155
);
156156

157+
injector.require(
158+
"timelineProfilerService",
159+
"./services/timeline-profiler-service"
160+
);
157161
injector.require("userSettingsService", "./services/user-settings-service");
158162
injector.requirePublic(
159163
"analyticsSettingsService",

lib/commands/preview.ts

Lines changed: 79 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,90 @@
11
import { ICommandParameter, ICommand } from "../common/definitions/commands";
2-
import { IErrors } from "../common/declarations";
2+
import { IChildProcess, IErrors } from "../common/declarations";
33
import { injector } from "../common/yok";
4+
import { IOptions, IPackageManager } from "../declarations";
5+
import { IProjectData } from "../definitions/project";
6+
import path = require("path");
7+
import { resolvePackagePath } from "@rigor789/resolve-package-path";
8+
import { PackageManagers } from "../constants";
9+
10+
const PREVIEW_CLI_PACKAGE = "@nativescript/preview-cli";
411

512
export class PreviewCommand implements ICommand {
613
allowedParameters: ICommandParameter[] = [];
714

8-
constructor(private $errors: IErrors) {}
15+
constructor(
16+
private $logger: ILogger,
17+
private $errors: IErrors,
18+
private $projectData: IProjectData,
19+
private $packageManager: IPackageManager,
20+
private $childProcess: IChildProcess,
21+
private $options: IOptions
22+
) {}
23+
24+
private getPreviewCLIPath(): string {
25+
return resolvePackagePath(PREVIEW_CLI_PACKAGE, {
26+
paths: [this.$projectData.projectDir],
27+
});
28+
}
929

1030
async execute(args: string[]): Promise<void> {
11-
this.$errors.fail(
12-
`The Preview service has been disabled until further notice.\n\n` +
13-
`Configure local builds and use "ns run ${args.join(" ")}" instead.`
14-
);
31+
if (!this.$options.disableNpmInstall) {
32+
// ensure latest is installed
33+
await this.$packageManager.install(
34+
`${PREVIEW_CLI_PACKAGE}@latest`,
35+
this.$projectData.projectDir,
36+
{
37+
"save-dev": true,
38+
"save-exact": true,
39+
} as any
40+
);
41+
}
42+
43+
const previewCLIPath = this.getPreviewCLIPath();
44+
45+
if (!previewCLIPath) {
46+
const packageManagerName = await this.$packageManager.getPackageManagerName();
47+
let installCommand = "";
48+
49+
switch (packageManagerName) {
50+
case PackageManagers.npm:
51+
installCommand = "npm install --save-dev @nativescript/preview-cli";
52+
break;
53+
case PackageManagers.yarn:
54+
installCommand = "yarn add -D @nativescript/preview-cli";
55+
break;
56+
case PackageManagers.pnpm:
57+
installCommand = "pnpm install --save-dev @nativescript/preview-cli";
58+
break;
59+
}
60+
this.$logger.info(
61+
[
62+
`Uhh ohh, no Preview CLI found.`,
63+
"",
64+
`This should not happen under regular circumstances, but seems like it did somehow... :(`,
65+
`Good news though, you can install the Preview CLI by running`,
66+
"",
67+
" " + installCommand.green,
68+
"",
69+
"Once installed, run this command again and everything should work!",
70+
"If it still fails, you can invoke the preview-cli directly as a last resort with",
71+
"",
72+
" ./node_modules/.bin/preview-cli".cyan,
73+
"",
74+
"And if you are still having issues, try again - or reach out on Discord/open an issue on GitHub.",
75+
].join("\n")
76+
);
77+
78+
this.$errors.fail("Running preview failed.");
79+
}
80+
81+
const previewCLIBinPath = path.resolve(previewCLIPath, "./dist/index.js");
82+
83+
const commandIndex = process.argv.indexOf("preview");
84+
const commandArgs = process.argv.slice(commandIndex + 1);
85+
this.$childProcess.spawn(previewCLIBinPath, commandArgs, {
86+
stdio: "inherit",
87+
});
1588
}
1689

1790
async canExecute(args: string[]): Promise<boolean> {

lib/common/constants.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,7 @@ export class EmulatorDiscoveryNames {
6262
}
6363

6464
export const DEVICE_LOG_EVENT_NAME = "deviceLogData";
65-
export const IOS_LOG_PREDICATE =
66-
'senderImagePath contains "NativeScript" || eventMessage contains[c] "NativeScript"';
65+
export const IOS_LOG_PREDICATE = 'senderImagePath contains "NativeScript"';
6766
export const IOS_APP_CRASH_LOG_REG_EXP = /Fatal JavaScript exception \- application has been terminated/;
6867
export const FAIL_LIVESYNC_LOG_REGEX = /Failed to refresh the application with RefreshRequest./;
6968

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ export class AndroidVirtualDeviceService
331331
private getConfigurationError(): string {
332332
const pathToEmulatorExecutable = this.$hostInfo.isWindows
333333
? `${this.pathToEmulatorExecutable}.exe`
334-
: this.pathToAndroidExecutable;
334+
: this.pathToEmulatorExecutable;
335335
if (!this.$fs.exists(pathToEmulatorExecutable)) {
336336
return "Unable to find the path to emulator executable and will not be able to start the emulator. Searched paths: [$ANDROID_HOME/tools/emulator, $ANDROID_HOME/emulator/emulator]";
337337
}
Lines changed: 137 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,20 @@
11
import { DeviceLogProviderBase } from "./device-log-provider-base";
22
import { DEVICE_LOG_EVENT_NAME } from "../constants";
3-
import { LoggerConfigData } from "../../constants";
43
import { injector } from "../yok";
54

5+
import * as chalk from "chalk";
6+
import { LoggerConfigData } from "../../constants";
7+
import { IOptions } from "../../declarations";
8+
9+
import { ITimelineProfilerService } from "../../services/timeline-profiler-service";
10+
611
export class DeviceLogProvider extends DeviceLogProviderBase {
712
constructor(
813
protected $logFilter: Mobile.ILogFilter,
914
protected $logger: ILogger,
10-
protected $logSourceMapService: Mobile.ILogSourceMapService
15+
protected $logSourceMapService: Mobile.ILogSourceMapService,
16+
protected $timelineProfilerService: ITimelineProfilerService,
17+
protected $options: IOptions
1118
) {
1219
super($logFilter, $logger, $logSourceMapService);
1320
}
@@ -17,15 +24,18 @@ export class DeviceLogProvider extends DeviceLogProviderBase {
1724
platform: string,
1825
deviceIdentifier: string
1926
): void {
27+
// console.log(lineText)
2028
const loggingOptions = this.getDeviceLogOptionsForDevice(deviceIdentifier);
2129
let data = this.$logFilter.filterData(platform, lineText, loggingOptions);
2230
data = this.$logSourceMapService.replaceWithOriginalFileLocations(
2331
platform,
2432
data,
2533
loggingOptions
2634
);
35+
2736
if (data) {
28-
this.logDataCore(data);
37+
this.$timelineProfilerService.processLogData(data, deviceIdentifier);
38+
this.logDataCore(data, deviceIdentifier);
2939
this.emit(DEVICE_LOG_EVENT_NAME, lineText, deviceIdentifier, platform);
3040
}
3141
}
@@ -34,8 +44,130 @@ export class DeviceLogProvider extends DeviceLogProviderBase {
3444
this.$logFilter.loggingLevel = logLevel.toUpperCase();
3545
}
3646

37-
private logDataCore(data: string): void {
38-
this.$logger.info(data, { [LoggerConfigData.skipNewLine]: true });
47+
private consoleLogLevelRegex: RegExp = /^CONSOLE (LOG|INFO|WARN|ERROR|TRACE|INFO( .+)):\s/;
48+
private consoleLevelColor: Record<string, (line: string) => string> = {
49+
log: (line) => line,
50+
info: chalk.cyanBright,
51+
warn: chalk.yellowBright,
52+
error: chalk.redBright,
53+
trace: chalk.grey,
54+
time: chalk.greenBright,
55+
};
56+
57+
private deviceColorMap = new Map<string, typeof chalk.BackgroundColor>();
58+
59+
private colorPool: typeof chalk.BackgroundColor[] = [
60+
"bgGray",
61+
"bgMagentaBright",
62+
"bgBlueBright",
63+
"bgWhiteBright",
64+
"bgCyanBright",
65+
"bgYellowBright",
66+
"bgGreenBright",
67+
];
68+
private colorPoolIndex = 0;
69+
70+
private getDeviceColor(deviceIdentifier: string) {
71+
if (this.deviceColorMap.has(deviceIdentifier)) {
72+
return this.deviceColorMap.get(deviceIdentifier);
73+
}
74+
75+
const color = this.colorPool[this.colorPoolIndex];
76+
// wrap around if we have no more colors in the pool
77+
this.colorPoolIndex =
78+
this.colorPoolIndex === this.colorPool.length - 1
79+
? 0
80+
: this.colorPoolIndex + 1;
81+
82+
this.deviceColorMap.set(deviceIdentifier, color);
83+
84+
return color;
85+
}
86+
87+
private logDataCore(data: string, deviceIdentifier: string): void {
88+
// todo: use config to set logger - --env.classicLogs is temporary!
89+
if ("classicLogs" in (this.$options.env ?? {})) {
90+
// legacy logging
91+
this.$logger.info(data, { [LoggerConfigData.skipNewLine]: true });
92+
return;
93+
}
94+
95+
// todo: extract into an injectable printer/logger service
96+
let shouldPrepend = false;
97+
let splitIndexes: number[] = [];
98+
const lines = data
99+
.split(/\n(CONSOLE)/)
100+
.map((line, index, lines) => {
101+
if (line === "CONSOLE") {
102+
shouldPrepend = true;
103+
104+
if (lines[index - 1]) {
105+
splitIndexes.push(index - 1);
106+
}
107+
108+
return null;
109+
}
110+
111+
if (shouldPrepend) {
112+
shouldPrepend = false;
113+
return `CONSOLE${line}`;
114+
}
115+
116+
const suffix = line.endsWith("\n") ? "" : "\n";
117+
return line + suffix;
118+
})
119+
.map((line, index) => {
120+
if (splitIndexes.includes(index)) {
121+
return line + "\n";
122+
}
123+
return line;
124+
})
125+
.filter((line) => {
126+
return line !== null;
127+
});
128+
129+
if (!lines.length && data.length) {
130+
lines.push(data);
131+
}
132+
133+
for (const line of lines) {
134+
let [match, level, timeLabel] =
135+
this.consoleLogLevelRegex.exec(line) ?? [];
136+
137+
if (timeLabel) {
138+
level = "time";
139+
timeLabel = timeLabel.replace("INFO ", "").trim() + ": ";
140+
} else {
141+
level = level?.toLowerCase() ?? "log";
142+
}
143+
144+
const toLog = [timeLabel ?? "", match ? line.replace(match, "") : line]
145+
.join("")
146+
.trim();
147+
148+
toLog.split("\n").forEach((actualLine) => {
149+
this.printLine(
150+
chalk[this.getDeviceColor(deviceIdentifier)](" "),
151+
this.consoleLevelColor[level](actualLine)
152+
);
153+
});
154+
}
155+
}
156+
157+
private printLine(prefix: string, ...parts: string[]) {
158+
const maxWidth = process.stdout.columns - 2;
159+
const fullLine = parts.join(" ");
160+
161+
// console.log(prefix, fullLine);
162+
// return;
163+
if (!maxWidth || maxWidth < 10 || fullLine.length < maxWidth) {
164+
console.log(prefix, fullLine);
165+
} else {
166+
for (let i = 0; i < fullLine.length; i += maxWidth) {
167+
const part = fullLine.substring(i, i + maxWidth);
168+
console.log(prefix, part);
169+
}
170+
}
39171
}
40172
}
41173
injector.register("deviceLogProvider", DeviceLogProvider);

lib/common/mobile/emulator-helper.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import { injector } from "../yok";
55
export class EmulatorHelper implements Mobile.IEmulatorHelper {
66
// https://developer.android.com/guide/topics/manifest/uses-sdk-element
77
public mapAndroidApiLevelToVersion = {
8+
"android-33": "13.0.0",
9+
"android-32": "12.0.0",
810
"android-31": "12.0.0",
911
"android-30": "11.0.0",
1012
"android-29": "10.0.0",

lib/common/test/unit-tests/mobile/device-log-provider.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ const createTestInjector = (): IInjector => {
3131
testInjector.register("iOSLogFilter", IOSLogFilter);
3232
testInjector.register("logger", CommonLoggerStub);
3333
testInjector.register("logSourceMapService", LogSourceMapService);
34+
testInjector.register("options", {
35+
env: {
36+
classicLogs: true,
37+
},
38+
});
3439
testInjector.register("loggingLevels", LoggingLevels);
3540
testInjector.register("devicePlatformsConstants", DevicePlatformsConstants);
3641
testInjector.register("fs", FileSystem);

0 commit comments

Comments
 (0)