Skip to content

Commit 15c9196

Browse files
author
Dimitar Tachev
authored
Merge pull request #5097 from NativeScript/release
chore: merge release into master
2 parents e75acf8 + 5115f07 commit 15c9196

File tree

7 files changed

+65
-35
lines changed

7 files changed

+65
-35
lines changed

lib/commands/build.ts

+3-7
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ANDROID_RELEASE_BUILD_ERROR_MESSAGE, AndroidAppBundleMessages, ANDROID_APP_BUNDLE_SIGNING_ERROR_MESSAGE } from "../constants";
1+
import { ANDROID_RELEASE_BUILD_ERROR_MESSAGE, AndroidAppBundleMessages } from "../constants";
22
import { ValidatePlatformCommandBase } from "./command-base";
33
import { hasValidAndroidSigning } from "../common/helpers";
44

@@ -124,12 +124,8 @@ export class BuildAndroidCommand extends BuildCommandBase implements ICommand {
124124
this.$androidBundleValidatorHelper.validateRuntimeVersion(this.$projectData);
125125
let canExecute = await super.canExecuteCommandBase(platform, { notConfiguredEnvOptions: { hideSyncToPreviewAppOption: true } });
126126
if (canExecute) {
127-
if ((this.$options.release || this.$options.aab) && !hasValidAndroidSigning(this.$options)) {
128-
if (this.$options.release) {
129-
this.$errors.failWithHelp(ANDROID_RELEASE_BUILD_ERROR_MESSAGE);
130-
} else {
131-
this.$errors.failWithHelp(ANDROID_APP_BUNDLE_SIGNING_ERROR_MESSAGE);
132-
}
127+
if (this.$options.release && !hasValidAndroidSigning(this.$options)) {
128+
this.$errors.failWithHelp(ANDROID_RELEASE_BUILD_ERROR_MESSAGE);
133129
}
134130

135131
canExecute = await super.validateArgs(args, platform);

lib/constants.ts

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ export const NATIVESCRIPT_KEY_NAME = "nativescript";
1010
export const NODE_MODULES_FOLDER_NAME = "node_modules";
1111
export const TNS_MODULES_FOLDER_NAME = "tns_modules";
1212
export const TNS_CORE_MODULES_NAME = "tns-core-modules";
13+
export const TNS_CORE_THEME_NAME = "nativescript-theme-core";
14+
export const SCOPED_TNS_CORE_THEME_NAME = "@nativescript/theme";
1315
export const WEBPACK_PLUGIN_NAME = "nativescript-dev-webpack";
1416
export const TNS_CORE_MODULES_WIDGETS_NAME = "tns-core-modules-widgets";
1517
export const TNS_ANDROID_RUNTIME_NAME = "tns-android";

lib/services/assets-generation/assets-generation-service.ts

+6
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,12 @@ export class AssetsGenerationService implements IAssetsGenerationService {
7171
const outputPath = assetItem.path;
7272
const width = assetItem.width * scale;
7373
const height = assetItem.height * scale;
74+
75+
if (!width || !height) {
76+
this.$logger.warn(`Image ${assetItem.filename} is skipped as its width and height are invalid.`);
77+
continue;
78+
}
79+
7480
let image: Jimp;
7581
switch (operation) {
7682
case Operations.OverlayWith:

lib/services/livesync/playground/preview-app-plugins-service.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import * as util from "util";
44
import { Device } from "nativescript-preview-sdk";
55
import { PluginComparisonMessages } from "./preview-app-constants";
66
import { NODE_MODULES_DIR_NAME } from "../../../common/constants";
7-
import { PLATFORMS_DIR_NAME, PACKAGE_JSON_FILE_NAME } from "../../../constants";
7+
import { PLATFORMS_DIR_NAME, PACKAGE_JSON_FILE_NAME, TNS_CORE_THEME_NAME, SCOPED_TNS_CORE_THEME_NAME } from "../../../constants";
88

99
export class PreviewAppPluginsService implements IPreviewAppPluginsService {
1010
constructor(private $errors: IErrors,
@@ -41,10 +41,11 @@ export class PreviewAppPluginsService implements IPreviewAppPluginsService {
4141

4242
public getExternalPlugins(device: Device): string[] {
4343
const devicePlugins = this.getDevicePlugins(device);
44+
const themeNamesArray = [TNS_CORE_THEME_NAME, SCOPED_TNS_CORE_THEME_NAME];
4445
const result = _.keys(devicePlugins)
4546
// The core theme links are custom and
4647
// should be handled by webpack during build.
47-
.filter(plugin => plugin !== "nativescript-theme-core");
48+
.filter(plugin => themeNamesArray.indexOf(plugin) === -1);
4849

4950
return result;
5051
}

lib/services/project-data-service.ts

+18-10
Original file line numberDiff line numberDiff line change
@@ -236,33 +236,36 @@ export class ProjectDataService implements IProjectDataService {
236236
private async getIOSAssetSubGroup(dirPath: string): Promise<IAssetSubGroup> {
237237
const pathToContentJson = path.join(dirPath, AssetConstants.iOSResourcesFileName);
238238
const content = this.$fs.exists(pathToContentJson) && <IAssetSubGroup>this.$fs.readJson(pathToContentJson) || { images: [] };
239+
const finalContent: IAssetSubGroup = { images: [] };
239240

240241
const imageDefinitions = this.getImageDefinitions().ios;
241242

242243
_.each(content && content.images, image => {
244+
let foundMatchingDefinition = false;
243245
// In some cases the image may not be available, it will just be described.
244246
// When this happens, the filename will be empty.
245247
// So we'll keep the path empty as well.
246248
if (image.filename) {
247249
image.path = path.join(dirPath, image.filename);
248250
}
249251

252+
if (image.size) {
253+
// size is basically <width>x<height>
254+
const [width, height] = image.size.toString().split(AssetConstants.sizeDelimiter);
255+
if (width && height) {
256+
image.width = +width;
257+
image.height = +height;
258+
}
259+
}
260+
250261
// Find the image size based on the hardcoded values in the image-definitions.json
251262
_.each(imageDefinitions, (assetSubGroup: IAssetItem[]) => {
252263
const assetItem = _.find(assetSubGroup, assetElement =>
253264
assetElement.filename === image.filename && path.basename(assetElement.directory) === path.basename(dirPath)
254265
);
255266

256-
if (image.size) {
257-
// size is basically <width>x<height>
258-
const [width, height] = image.size.toString().split(AssetConstants.sizeDelimiter);
259-
if (width && height) {
260-
image.width = +width;
261-
image.height = +height;
262-
}
263-
}
264-
265267
if (assetItem) {
268+
foundMatchingDefinition = true;
266269
if (!image.width || !image.height) {
267270
image.width = assetItem.width;
268271
image.height = assetItem.height;
@@ -273,13 +276,18 @@ export class ProjectDataService implements IProjectDataService {
273276
image.overlayImageScale = image.overlayImageScale || assetItem.overlayImageScale;
274277
image.scale = image.scale || assetItem.scale;
275278
image.rgba = assetItem.rgba;
279+
finalContent.images.push(image);
276280
// break each
277281
return false;
278282
}
279283
});
284+
285+
if (!foundMatchingDefinition && image.filename) {
286+
this.$logger.warn(`Didn't find a matching image definition for file ${path.join(path.basename(dirPath), image.filename)}. This file will be skipped from reources generation.`);
287+
}
280288
});
281289

282-
return content;
290+
return finalContent;
283291
}
284292

285293
private getAndroidAssetSubGroup(assetItems: IAssetItem[], realPaths: string[]): IAssetSubGroup {

lib/services/webpack/webpack-compiler-service.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { WEBPACK_COMPILATION_COMPLETE, WEBPACK_PLUGIN_NAME } from "../../constan
77

88
export class WebpackCompilerService extends EventEmitter implements IWebpackCompilerService {
99
private webpackProcesses: IDictionary<child_process.ChildProcess> = {};
10-
private expectedHash: string = null;
10+
private expectedHashes: IStringDictionary = {};
1111

1212
constructor(
1313
private $errors: IErrors,
@@ -42,14 +42,14 @@ export class WebpackCompilerService extends EventEmitter implements IWebpackComp
4242
if (message.emittedFiles) {
4343
if (isFirstWebpackWatchCompilation) {
4444
isFirstWebpackWatchCompilation = false;
45-
this.expectedHash = message.hash;
45+
this.expectedHashes[platformData.platformNameLowerCase] = message.hash;
4646
return;
4747
}
4848

4949
let result;
5050

5151
if (prepareData.hmr) {
52-
result = this.getUpdatedEmittedFiles(message.emittedFiles, message.chunkFiles, message.hash);
52+
result = this.getUpdatedEmittedFiles(message.emittedFiles, message.chunkFiles, message.hash, platformData.platformNameLowerCase);
5353
} else {
5454
result = { emittedFiles: message.emittedFiles, fallbackFiles: <string[]>[], hash: "" };
5555
}
@@ -248,7 +248,7 @@ export class WebpackCompilerService extends EventEmitter implements IWebpackComp
248248
return args;
249249
}
250250

251-
public getUpdatedEmittedFiles(allEmittedFiles: string[], chunkFiles: string[], nextHash: string) {
251+
public getUpdatedEmittedFiles(allEmittedFiles: string[], chunkFiles: string[], nextHash: string, platform: string) {
252252
const currentHash = this.getCurrentHotUpdateHash(allEmittedFiles);
253253

254254
// This logic is needed as there are already cases when webpack doesn't emit any files physically.
@@ -260,8 +260,8 @@ export class WebpackCompilerService extends EventEmitter implements IWebpackComp
260260
// if files will be emitted or not. This way, the first successful compilation after fixing the compilation error generates
261261
// a hash that is not the same as the one expected in the latest emitted hot-update.json file.
262262
// As a result, the hmr chain is broken and the changes are not applied.
263-
const isHashValid = nextHash ? this.expectedHash === currentHash : true;
264-
this.expectedHash = nextHash;
263+
const isHashValid = nextHash ? this.expectedHashes[platform] === currentHash : true;
264+
this.expectedHashes[platform] = nextHash;
265265

266266
const emittedHotUpdatesAndAssets = isHashValid ? _.difference(allEmittedFiles, chunkFiles) : allEmittedFiles;
267267

test/services/webpack/webpack-compiler-service.ts

+27-10
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import { Yok } from "../../../lib/common/yok";
22
import { WebpackCompilerService } from "../../../lib/services/webpack/webpack-compiler-service";
33
import { assert } from "chai";
44

5+
const iOSPlatformName = "ios";
6+
const androidPlatformName = "android";
57
const chunkFiles = ["bundle.js", "runtime.js", "vendor.js"];
68

79
function getAllEmittedFiles(hash: string) {
@@ -35,39 +37,54 @@ describe("WebpackCompilerService", () => {
3537
describe("getUpdatedEmittedFiles", () => {
3638
// backwards compatibility with old versions of nativescript-dev-webpack
3739
it("should return only hot updates when nextHash is not provided", async () => {
38-
const result = webpackCompilerService.getUpdatedEmittedFiles(getAllEmittedFiles("hash1"), chunkFiles, null);
40+
const result = webpackCompilerService.getUpdatedEmittedFiles(getAllEmittedFiles("hash1"), chunkFiles, null, iOSPlatformName);
3941
const expectedEmittedFiles = ['bundle.hash1.hot-update.js', 'hash1.hot-update.json'];
4042

4143
assert.deepEqual(result.emittedFiles, expectedEmittedFiles);
4244
});
4345
// 2 successful webpack compilations
4446
it("should return only hot updates when nextHash is provided", async () => {
45-
webpackCompilerService.getUpdatedEmittedFiles(getAllEmittedFiles("hash1"), chunkFiles, "hash2");
46-
const result = webpackCompilerService.getUpdatedEmittedFiles(getAllEmittedFiles("hash2"), chunkFiles, "hash3");
47+
webpackCompilerService.getUpdatedEmittedFiles(getAllEmittedFiles("hash1"), chunkFiles, "hash2", iOSPlatformName);
48+
const result = webpackCompilerService.getUpdatedEmittedFiles(getAllEmittedFiles("hash2"), chunkFiles, "hash3", iOSPlatformName);
4749

4850
assert.deepEqual(result.emittedFiles, ['bundle.hash2.hot-update.js', 'hash2.hot-update.json']);
4951
});
5052
// 1 successful webpack compilation, n compilations with no emitted files
5153
it("should return all files when there is a webpack compilation with no emitted files", () => {
52-
webpackCompilerService.getUpdatedEmittedFiles(getAllEmittedFiles("hash1"), chunkFiles, "hash2");
53-
const result = webpackCompilerService.getUpdatedEmittedFiles(getAllEmittedFiles("hash4"), chunkFiles, "hash5");
54+
webpackCompilerService.getUpdatedEmittedFiles(getAllEmittedFiles("hash1"), chunkFiles, "hash2", iOSPlatformName);
55+
const result = webpackCompilerService.getUpdatedEmittedFiles(getAllEmittedFiles("hash4"), chunkFiles, "hash5", iOSPlatformName);
5456

5557
assert.deepEqual(result.emittedFiles, ['bundle.js', 'runtime.js', 'bundle.hash4.hot-update.js', 'hash4.hot-update.json']);
5658
});
5759
// 1 successful webpack compilation, n compilations with no emitted files, 1 successful webpack compilation
5860
it("should return only hot updates after fixing the compilation error", () => {
59-
webpackCompilerService.getUpdatedEmittedFiles(getAllEmittedFiles("hash1"), chunkFiles, "hash2");
60-
webpackCompilerService.getUpdatedEmittedFiles(getAllEmittedFiles("hash5"), chunkFiles, "hash6");
61-
const result = webpackCompilerService.getUpdatedEmittedFiles(getAllEmittedFiles("hash6"), chunkFiles, "hash7");
61+
webpackCompilerService.getUpdatedEmittedFiles(getAllEmittedFiles("hash1"), chunkFiles, "hash2", iOSPlatformName);
62+
webpackCompilerService.getUpdatedEmittedFiles(getAllEmittedFiles("hash5"), chunkFiles, "hash6", iOSPlatformName);
63+
const result = webpackCompilerService.getUpdatedEmittedFiles(getAllEmittedFiles("hash6"), chunkFiles, "hash7", iOSPlatformName);
6264

6365
assert.deepEqual(result.emittedFiles, ['bundle.hash6.hot-update.js', 'hash6.hot-update.json']);
6466
});
6567
// 1 webpack compilation with no emitted files
6668
it("should return all files when first compilation on livesync change is not successful", () => {
67-
(<any>webpackCompilerService).expectedHash = "hash1";
68-
const result = webpackCompilerService.getUpdatedEmittedFiles(getAllEmittedFiles("hash1"), chunkFiles, "hash2");
69+
(<any>webpackCompilerService).expectedHashes = {
70+
"ios": "hash1"
71+
};
72+
const result = webpackCompilerService.getUpdatedEmittedFiles(getAllEmittedFiles("hash1"), chunkFiles, "hash2", iOSPlatformName);
6973

7074
assert.deepEqual(result.emittedFiles, ["bundle.hash1.hot-update.js", "hash1.hot-update.json"]);
7175
});
76+
it("should return correct hashes when there are more than one platform", () => {
77+
webpackCompilerService.getUpdatedEmittedFiles(getAllEmittedFiles("hash1"), chunkFiles, "hash2", iOSPlatformName);
78+
webpackCompilerService.getUpdatedEmittedFiles(getAllEmittedFiles("hash3"), chunkFiles, "hash4", androidPlatformName);
79+
80+
webpackCompilerService.getUpdatedEmittedFiles(getAllEmittedFiles("hash2"), chunkFiles, "hash5", iOSPlatformName);
81+
webpackCompilerService.getUpdatedEmittedFiles(getAllEmittedFiles("hash4"), chunkFiles, "hash6", androidPlatformName);
82+
83+
const iOSResult = webpackCompilerService.getUpdatedEmittedFiles(getAllEmittedFiles("hash5"), chunkFiles, "hash7", iOSPlatformName);
84+
assert.deepEqual(iOSResult.emittedFiles, ["bundle.hash5.hot-update.js", "hash5.hot-update.json"]);
85+
86+
const androidResult = webpackCompilerService.getUpdatedEmittedFiles(getAllEmittedFiles("hash6"), chunkFiles, "hash8", androidPlatformName);
87+
assert.deepEqual(androidResult.emittedFiles, ["bundle.hash6.hot-update.js", "hash6.hot-update.json"]);
88+
});
7289
});
7390
});

0 commit comments

Comments
 (0)