nativescript 9.0.0-alpha.9 → 9.0.0-dev.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.
Files changed (89) hide show
  1. package/config/config.json +1 -1
  2. package/config/test-deps-versions-generated.json +3 -3
  3. package/docs/build-jekyll-md.sh +1 -1
  4. package/docs/man_pages/config/config-get.md +36 -0
  5. package/docs/man_pages/config/config-set.md +40 -0
  6. package/docs/man_pages/config/config.md +39 -0
  7. package/docs/man_pages/project/hooks/hooks.md +35 -0
  8. package/docs/man_pages/start.md +1 -0
  9. package/lib/.d.ts +4 -0
  10. package/lib/bootstrap.js +2 -0
  11. package/lib/commands/build.js +22 -3
  12. package/lib/commands/clean.js +3 -2
  13. package/lib/commands/config.js +9 -3
  14. package/lib/commands/hooks/common.js +79 -0
  15. package/lib/commands/hooks/hooks-lock.js +100 -0
  16. package/lib/commands/hooks/hooks.js +71 -0
  17. package/lib/commands/plugin/build-plugin.js +6 -2
  18. package/lib/commands/typings.js +1 -1
  19. package/lib/common/declarations.d.ts +5 -0
  20. package/lib/common/definitions/extensibility.d.ts +2 -2
  21. package/lib/common/definitions/mobile.d.ts +78 -72
  22. package/lib/common/file-system.js +1 -1
  23. package/lib/common/logger/logger.js +1 -1
  24. package/lib/common/mobile/android/android-device.js +8 -2
  25. package/lib/common/mobile/mobile-core/devices-service.js +1 -1
  26. package/lib/common/plist-parser.js +3 -3
  27. package/lib/common/project-helper.js +15 -2
  28. package/lib/common/services/hooks-service.js +1 -1
  29. package/lib/config.js +2 -38
  30. package/lib/constants.js +3 -2
  31. package/lib/controllers/build-controller.js +1 -1
  32. package/lib/controllers/deploy-controller.js +5 -2
  33. package/lib/controllers/migrate-controller.js +6 -5
  34. package/lib/controllers/platform-controller.js +3 -1
  35. package/lib/controllers/prepare-controller.js +54 -13
  36. package/lib/controllers/run-controller.js +12 -13
  37. package/lib/controllers/update-controller.js +2 -2
  38. package/lib/data/build-data.js +2 -0
  39. package/lib/declarations.d.ts +3 -1
  40. package/lib/definitions/android-plugin-migrator.d.ts +3 -2
  41. package/lib/definitions/build.d.ts +4 -2
  42. package/lib/definitions/hooks.d.ts +1 -0
  43. package/lib/definitions/ios-debugger-port-service.d.ts +1 -1
  44. package/lib/definitions/livesync.d.ts +1 -1
  45. package/lib/definitions/project.d.ts +14 -0
  46. package/lib/definitions/run.d.ts +2 -4
  47. package/lib/helpers/deploy-command-helper.js +1 -0
  48. package/lib/nativescript-cli.js +28 -0
  49. package/lib/options.js +9 -2
  50. package/lib/project-data.js +8 -2
  51. package/lib/services/analytics/analytics-broker-process.js +1 -1
  52. package/lib/services/analytics/analytics-service.js +1 -1
  53. package/lib/services/android/gradle-build-args-service.js +21 -7
  54. package/lib/services/android/gradle-build-service.js +15 -1
  55. package/lib/services/android-plugin-build-service.js +58 -44
  56. package/lib/services/android-project-service.js +63 -4
  57. package/lib/services/build-artifacts-service.js +24 -9
  58. package/lib/services/bundler/bundler-compiler-service.js +77 -104
  59. package/lib/services/cocoapods-service.js +10 -4
  60. package/lib/services/device/device-install-app-service.js +27 -5
  61. package/lib/services/extensibility-service.js +1 -1
  62. package/lib/services/ios/xcodebuild-args-service.js +7 -5
  63. package/lib/services/ios-project-service.js +5 -2
  64. package/lib/services/plugins-service.js +3 -2
  65. package/lib/services/project-data-service.js +16 -18
  66. package/lib/services/timeline-profiler-service.js +21 -13
  67. package/lib/services/versions-service.js +2 -1
  68. package/package.json +16 -13
  69. package/vendor/aab-tool/README.txt +1 -1
  70. package/vendor/aab-tool/bundletool.jar +0 -0
  71. package/vendor/gradle-app/app/build.gradle +1292 -0
  72. package/vendor/gradle-app/app/gradle-helpers/AnalyticsCollector.gradle +48 -0
  73. package/vendor/gradle-app/app/gradle-helpers/BuildToolTask.gradle +50 -0
  74. package/vendor/gradle-app/app/gradle-helpers/CustomExecutionLogger.gradle +52 -0
  75. package/vendor/gradle-app/app/gradle.properties +45 -0
  76. package/vendor/gradle-app/build.gradle +170 -0
  77. package/vendor/gradle-app/settings.gradle +78 -0
  78. package/vendor/gradle-plugin/build.gradle +214 -91
  79. package/vendor/gradle-plugin/gradle.properties +2 -18
  80. package/vendor/gradle-plugin/settings.gradle +23 -11
  81. package/lib/common/resources/platform-tools/android/darwin/NOTICE.txt +0 -3407
  82. package/lib/common/resources/platform-tools/android/darwin/adb +0 -0
  83. package/lib/common/resources/platform-tools/android/linux/NOTICE.txt +0 -4451
  84. package/lib/common/resources/platform-tools/android/linux/adb +0 -0
  85. package/lib/common/resources/platform-tools/android/win32/AdbWinApi.dll +0 -0
  86. package/lib/common/resources/platform-tools/android/win32/AdbWinUsbApi.dll +0 -0
  87. package/lib/common/resources/platform-tools/android/win32/NOTICE.txt +0 -4451
  88. package/lib/common/resources/platform-tools/android/win32/adb.exe +0 -0
  89. package/lib/common/resources/platform-tools/android/win32/fastboot.exe +0 -0
@@ -75,14 +75,14 @@ class ProjectData {
75
75
  nsConfig && nsConfig.projectName
76
76
  ? nsConfig.projectName
77
77
  : this.$projectHelper.sanitizeName(path.basename(projectDir));
78
- this.platformsDir = path.join(projectDir, constants.PLATFORMS_DIR_NAME);
78
+ this.nsConfig = nsConfig;
79
+ this.platformsDir = path.join(projectDir, this.getBuildRelativeDirectoryPath());
79
80
  this.projectFilePath = projectFilePath;
80
81
  this.projectIdentifiers = this.initializeProjectIdentifiers(nsConfig);
81
82
  this.packageJsonData = packageJsonData;
82
83
  this.dependencies = packageJsonData.dependencies;
83
84
  this.devDependencies = packageJsonData.devDependencies;
84
85
  this.projectType = this.getProjectType();
85
- this.nsConfig = nsConfig;
86
86
  this.ignoredDependencies = nsConfig === null || nsConfig === void 0 ? void 0 : nsConfig.ignoredNativeDependencies;
87
87
  this.appDirectoryPath = this.getAppDirectoryPath();
88
88
  this.appResourcesDirectoryPath = this.getAppResourcesDirectoryPath();
@@ -136,6 +136,12 @@ class ProjectData {
136
136
  const appRelativePath = this.getAppDirectoryRelativePath();
137
137
  return this.resolveToProjectDir(appRelativePath, projectDir);
138
138
  }
139
+ getBuildRelativeDirectoryPath() {
140
+ if (this.nsConfig && this.nsConfig[constants.CONFIG_NS_BUILD_ENTRY]) {
141
+ return this.nsConfig[constants.CONFIG_NS_BUILD_ENTRY];
142
+ }
143
+ return constants.PLATFORMS_DIR_NAME;
144
+ }
139
145
  getAppDirectoryRelativePath() {
140
146
  if (this.nsConfig && this.nsConfig[constants.CONFIG_NS_APP_ENTRY]) {
141
147
  return this.nsConfig[constants.CONFIG_NS_APP_ENTRY];
@@ -44,7 +44,7 @@ process.on("message", async (data) => {
44
44
  analyticsLoggingService.logData({
45
45
  message: `analytics-broker-process will send ${"ProcessFinishedTasks"} message`,
46
46
  });
47
- process.send("ProcessFinishedTasks", () => {
47
+ process.send("ProcessFinishedTasks", null, null, () => {
48
48
  analyticsLoggingService.logData({
49
49
  message: `analytics-broker-process sent ${"ProcessFinishedTasks"} message and will exit gracefully now`,
50
50
  });
@@ -38,7 +38,7 @@ class AnalyticsService {
38
38
  if ((await this.isNotConfirmed(this.$staticConfig.TRACK_FEATURE_USAGE_SETTING_NAME)) &&
39
39
  (0, helpers_1.isInteractive)()) {
40
40
  const message = `Do you want to help us improve ${this.$analyticsSettingsService.getClientName()} by automatically sending anonymous usage statistics? We will not use this information to identify or contact you.`;
41
- trackFeatureUsage = await this.$prompter.confirm(message, () => true);
41
+ trackFeatureUsage = await this.$prompter.confirm(message, () => false);
42
42
  await this.setStatus(this.$staticConfig.TRACK_FEATURE_USAGE_SETTING_NAME, trackFeatureUsage);
43
43
  await this.trackAcceptFeatureUsage({
44
44
  acceptTrackFeatureUsage: trackFeatureUsage,
@@ -5,7 +5,8 @@ const path = require("path");
5
5
  const constants_1 = require("../../common/constants");
6
6
  const yok_1 = require("../../common/yok");
7
7
  class GradleBuildArgsService {
8
- constructor($hooksService, $analyticsService, $staticConfig, $projectData, $logger) {
8
+ constructor($androidToolsInfo, $hooksService, $analyticsService, $staticConfig, $projectData, $logger) {
9
+ this.$androidToolsInfo = $androidToolsInfo;
9
10
  this.$hooksService = $hooksService;
10
11
  this.$analyticsService = $analyticsService;
11
12
  this.$staticConfig = $staticConfig;
@@ -30,10 +31,18 @@ class GradleBuildArgsService {
30
31
  }
31
32
  getBaseTaskArgs(buildData) {
32
33
  const args = this.getBuildLoggingArgs();
34
+ const toolsInfo = this.$androidToolsInfo.getToolsInfo({
35
+ projectDir: buildData.projectDir,
36
+ });
33
37
  this.$projectData.initializeProjectData(buildData.projectDir);
34
- args.push(`-PappPath=${this.$projectData.getAppDirectoryPath()}`, `-PappResourcesPath=${this.$projectData.getAppResourcesDirectoryPath()}`);
35
- if (buildData.gradleArgs) {
36
- args.push(buildData.gradleArgs);
38
+ args.push(`--stacktrace`, `-PcompileSdk=${toolsInfo.compileSdkVersion}`, `-PtargetSdk=${toolsInfo.targetSdkVersion}`, `-PbuildToolsVersion=${toolsInfo.buildToolsVersion}`, `-PgenerateTypings=${toolsInfo.generateTypings}`, `-PprojectRoot=${this.$projectData.projectDir}`, `-DprojectRoot=${this.$projectData.projectDir}`, `-PappPath=${this.$projectData.getAppDirectoryPath()}`, `-PappBuildPath=${this.$projectData.getBuildRelativeDirectoryPath()}`, `-DappBuildPath=${this.$projectData.getBuildRelativeDirectoryPath()}`, `-PappPath=${this.$projectData.getAppDirectoryPath()}`, `-PappResourcesPath=${this.$projectData.getAppResourcesDirectoryPath()}`);
39
+ const gradleArgs = (this.$projectData.nsConfig.android.gradleArgs || []).concat(buildData.gradleArgs || []);
40
+ if (gradleArgs) {
41
+ const additionalArgs = [];
42
+ gradleArgs.forEach((arg) => {
43
+ additionalArgs.push(...arg.split(" ").map((a) => a.trim()));
44
+ });
45
+ args.push(...additionalArgs);
37
46
  }
38
47
  if (buildData.release) {
39
48
  args.push("-Prelease", `-PksPath=${path.resolve(buildData.keyStorePath)}`, `-Palias=${buildData.keyStoreAlias}`, `-Ppassword=${buildData.keyStoreAliasPassword}`, `-PksPassword=${buildData.keyStorePassword}`);
@@ -44,15 +53,20 @@ class GradleBuildArgsService {
44
53
  const args = [];
45
54
  const logLevel = this.$logger.getLevel();
46
55
  if (logLevel === "TRACE") {
47
- args.push("--stacktrace", "--debug");
56
+ args.push("--debug");
48
57
  }
49
58
  else if (logLevel === "INFO") {
50
- args.push("--quiet");
59
+ args.push("--info");
51
60
  }
52
61
  return args;
53
62
  }
54
63
  getBuildTaskName(buildData) {
55
- const baseTaskName = buildData.androidBundle ? "bundle" : "assemble";
64
+ let baseTaskName = buildData.androidBundle ? "bundle" : "assemble";
65
+ if (buildData.gradleFlavor) {
66
+ baseTaskName +=
67
+ buildData.gradleFlavor[0].toUpperCase() +
68
+ buildData.gradleFlavor.slice(1);
69
+ }
56
70
  const buildTaskName = buildData.release
57
71
  ? `${baseTaskName}${constants_1.Configurations.Release}`
58
72
  : `${baseTaskName}${constants_1.Configurations.Debug}`;
@@ -6,14 +6,28 @@ const constants = require("../../constants");
6
6
  const events_1 = require("events");
7
7
  const yok_1 = require("../../common/yok");
8
8
  class GradleBuildService extends events_1.EventEmitter {
9
- constructor($childProcess, $gradleBuildArgsService, $gradleCommandService) {
9
+ constructor($childProcess, $gradleBuildArgsService, $gradleCommandService, $devicesService) {
10
10
  super();
11
11
  this.$childProcess = $childProcess;
12
12
  this.$gradleBuildArgsService = $gradleBuildArgsService;
13
13
  this.$gradleCommandService = $gradleCommandService;
14
+ this.$devicesService = $devicesService;
14
15
  }
15
16
  async buildProject(projectRoot, buildData) {
16
17
  const buildTaskArgs = await this.$gradleBuildArgsService.getBuildTaskArgs(buildData);
18
+ if (buildData.buildFilterDevicesArch) {
19
+ let devices = this.$devicesService.getDevicesForPlatform(buildData.platform);
20
+ if (buildData.emulator) {
21
+ devices = devices.filter((d) => d.isEmulator);
22
+ }
23
+ const abis = devices
24
+ .map((d) => d.deviceInfo.abis.filter((a) => !!a && a.length)[0])
25
+ .filter((a) => !!a);
26
+ if (abis.length > 0 &&
27
+ buildTaskArgs.findIndex((b) => b.startsWith("-PabiFilters")) === -1) {
28
+ buildTaskArgs.push(`-PabiFilters=${abis.join(",")}`);
29
+ }
30
+ }
17
31
  const spawnOptions = {
18
32
  emitOptions: { eventName: constants.BUILD_OUTPUT_EVENT_NAME },
19
33
  throwError: true,
@@ -19,9 +19,10 @@ class AndroidPluginBuildService {
19
19
  get $platformsDataService() {
20
20
  return this.$injector.resolve("platformsDataService");
21
21
  }
22
- constructor($fs, $childProcess, $hostInfo, $options, $logger, $packageManager, $projectData, $projectDataService, $devicePlatformsConstants, $errors, $filesHashService, $hooksService, $injector, $watchIgnoreListService) {
22
+ constructor($fs, $childProcess, $androidToolsInfo, $hostInfo, $options, $logger, $packageManager, $projectData, $projectDataService, $devicePlatformsConstants, $errors, $filesHashService, $hooksService, $injector, $watchIgnoreListService) {
23
23
  this.$fs = $fs;
24
24
  this.$childProcess = $childProcess;
25
+ this.$androidToolsInfo = $androidToolsInfo;
25
26
  this.$hostInfo = $hostInfo;
26
27
  this.$options = $options;
27
28
  this.$logger = $logger;
@@ -89,22 +90,6 @@ class AndroidPluginBuildService {
89
90
  }));
90
91
  return promise;
91
92
  }
92
- getIncludeGradleCompileDependenciesScope(includeGradleFileContent) {
93
- const indexOfDependenciesScope = includeGradleFileContent.indexOf("dependencies");
94
- const result = [];
95
- if (indexOfDependenciesScope === -1) {
96
- return result;
97
- }
98
- const indexOfRepositoriesScope = includeGradleFileContent.indexOf("repositories");
99
- let repositoriesScope = "";
100
- if (indexOfRepositoriesScope >= 0) {
101
- repositoriesScope = this.getScope("repositories", includeGradleFileContent);
102
- result.push(repositoriesScope);
103
- }
104
- const dependenciesScope = this.getScope("dependencies", includeGradleFileContent);
105
- result.push(dependenciesScope);
106
- return result;
107
- }
108
93
  getScope(scopeName, content) {
109
94
  const indexOfScopeName = content.indexOf(scopeName);
110
95
  const openingBracket = "{";
@@ -136,7 +121,7 @@ class AndroidPluginBuildService {
136
121
  this.validateOptions(options);
137
122
  const manifestFilePath = this.getManifest(options.platformsAndroidDirPath);
138
123
  const androidSourceDirectories = this.getAndroidSourceDirectories(options.platformsAndroidDirPath);
139
- const shortPluginName = (0, helpers_1.getShortPluginName)(options.pluginName);
124
+ const shortPluginName = (0, helpers_1.getShortPluginName)(options.pluginName + (options.aarSuffix || ''));
140
125
  const pluginTempDir = path.join(options.tempPluginDirPath, shortPluginName);
141
126
  const pluginSourceFileHashesInfo = await this.getSourceFilesHashes(options.platformsAndroidDirPath, shortPluginName);
142
127
  const shouldBuildAar = await this.shouldBuildAar({
@@ -153,9 +138,10 @@ class AndroidPluginBuildService {
153
138
  await this.updateManifest(manifestFilePath, pluginTempMainSrcDir, shortPluginName);
154
139
  this.copySourceSetDirectories(androidSourceDirectories, pluginTempMainSrcDir);
155
140
  await this.setupGradle(pluginTempDir, options.platformsAndroidDirPath, options.projectDir, options.pluginName);
141
+ const gradleArgs = (this.$projectData.nsConfig.android.gradleArgs || []).concat(options.gradleArgs || []);
156
142
  await this.buildPlugin({
157
143
  gradlePath: options.gradlePath,
158
- gradleArgs: options.gradleArgs,
144
+ gradleArgs,
159
145
  pluginDir: pluginTempDir,
160
146
  pluginName: options.pluginName,
161
147
  projectDir: options.projectDir,
@@ -228,16 +214,37 @@ class AndroidPluginBuildService {
228
214
  this.$fs.copyFile(path.join(dir, "*"), destination);
229
215
  }
230
216
  }
217
+ extractNamespaceFromManifest(manifestPath) {
218
+ const fileContent = this.$fs.readText(manifestPath);
219
+ const contentRegex = new RegExp('package="(.*?)"');
220
+ const match = fileContent.match(contentRegex);
221
+ let namespace;
222
+ if (match) {
223
+ namespace = match[1];
224
+ const replacedFileContent = fileContent.replace(contentRegex, "");
225
+ this.$fs.writeFile(manifestPath, replacedFileContent);
226
+ }
227
+ return namespace;
228
+ }
231
229
  async setupGradle(pluginTempDir, platformsAndroidDirPath, projectDir, pluginName) {
232
230
  const gradleTemplatePath = path.resolve(path.join(__dirname, "../../vendor/gradle-plugin"));
233
231
  const allGradleTemplateFiles = path.join(gradleTemplatePath, "*");
234
232
  const buildGradlePath = path.join(pluginTempDir, "build.gradle");
235
233
  const settingsGradlePath = path.join(pluginTempDir, "settings.gradle");
236
234
  this.$fs.copyFile(allGradleTemplateFiles, pluginTempDir);
237
- this.addCompileDependencies(platformsAndroidDirPath, buildGradlePath);
238
235
  const runtimeGradleVersions = await this.getRuntimeGradleVersions(projectDir);
239
- this.replaceGradleVersion(pluginTempDir, runtimeGradleVersions.gradleVersion);
236
+ let gradleVersion = runtimeGradleVersions.gradleVersion;
237
+ if (this.$projectData.nsConfig.android.gradleVersion) {
238
+ gradleVersion = this.$projectData.nsConfig.android.gradleVersion;
239
+ }
240
+ this.replaceGradleVersion(pluginTempDir, gradleVersion);
240
241
  this.replaceGradleAndroidPluginVersion(buildGradlePath, runtimeGradleVersions.gradleAndroidPluginVersion);
242
+ const manifestFilePath = this.getManifest(path.join(pluginTempDir, "src", "main"));
243
+ let pluginNamespace = this.extractNamespaceFromManifest(manifestFilePath);
244
+ if (!pluginNamespace) {
245
+ pluginNamespace = pluginName.replace(/@/g, "").replace(/[/-]/g, ".");
246
+ }
247
+ this.replaceFileContent(buildGradlePath, "{{pluginNamespace}}", pluginNamespace);
241
248
  this.replaceFileContent(buildGradlePath, "{{pluginName}}", pluginName);
242
249
  this.replaceFileContent(settingsGradlePath, "{{pluginName}}", pluginName);
243
250
  const shortPluginName = (0, helpers_1.getShortPluginName)(pluginName);
@@ -269,24 +276,27 @@ class AndroidPluginBuildService {
269
276
  return runtimeGradleVersions || {};
270
277
  }
271
278
  async getLatestRuntimeVersion() {
272
- var _a;
279
+ var _a, _b;
273
280
  let runtimeVersion = null;
281
+ const packageName = ((_a = this.$projectData.nsConfig.android) === null || _a === void 0 ? void 0 : _a.runtimePackageName) || constants_1.SCOPED_ANDROID_RUNTIME_NAME;
274
282
  try {
275
- let result = await this.$packageManager.view(constants_1.SCOPED_ANDROID_RUNTIME_NAME, {
283
+ let result = await this.$packageManager.view(packageName, {
276
284
  "dist-tags": true,
277
285
  });
278
- result = (_a = result === null || result === void 0 ? void 0 : result["dist-tags"]) !== null && _a !== void 0 ? _a : result;
286
+ result = (_b = result === null || result === void 0 ? void 0 : result["dist-tags"]) !== null && _b !== void 0 ? _b : result;
279
287
  runtimeVersion = result.latest;
280
288
  }
281
289
  catch (err) {
282
290
  this.$logger.trace(`Error while getting latest android runtime version from view command: ${err}`);
283
- const registryData = await this.$packageManager.getRegistryPackageData(constants_1.SCOPED_ANDROID_RUNTIME_NAME);
291
+ const registryData = await this.$packageManager.getRegistryPackageData(packageName);
284
292
  runtimeVersion = registryData["dist-tags"].latest;
285
293
  }
286
294
  return runtimeVersion;
287
295
  }
288
296
  getLocalGradleVersions() {
289
- const installedRuntimePackageJSONPath = (0, resolve_package_path_1.resolvePackageJSONPath)(constants_1.SCOPED_ANDROID_RUNTIME_NAME, {
297
+ var _a;
298
+ const packageName = ((_a = this.$projectData.nsConfig.android) === null || _a === void 0 ? void 0 : _a.runtimePackageName) || constants_1.SCOPED_ANDROID_RUNTIME_NAME;
299
+ const installedRuntimePackageJSONPath = (0, resolve_package_path_1.resolvePackageJSONPath)(packageName, {
290
300
  paths: [this.$projectData.projectDir],
291
301
  });
292
302
  if (!installedRuntimePackageJSONPath) {
@@ -313,18 +323,19 @@ class AndroidPluginBuildService {
313
323
  return null;
314
324
  }
315
325
  async getGradleVersions(runtimeVersion) {
316
- var _a, _b;
326
+ var _a, _b, _c;
317
327
  let runtimeGradleVersions = null;
318
328
  const localVersionInfo = this.getLocalGradleVersions();
319
329
  if (localVersionInfo) {
320
330
  return localVersionInfo;
321
331
  }
332
+ const packageName = ((_a = this.$projectData.nsConfig.android) === null || _a === void 0 ? void 0 : _a.runtimePackageName) || constants_1.SCOPED_ANDROID_RUNTIME_NAME;
322
333
  try {
323
- let output = await this.$packageManager.view(`${constants_1.SCOPED_ANDROID_RUNTIME_NAME}@${runtimeVersion}`, { version_info: true });
324
- output = (_a = output === null || output === void 0 ? void 0 : output["version_info"]) !== null && _a !== void 0 ? _a : output;
334
+ let output = await this.$packageManager.view(`${packageName}@${runtimeVersion}`, { version_info: true });
335
+ output = (_b = output === null || output === void 0 ? void 0 : output["version_info"]) !== null && _b !== void 0 ? _b : output;
325
336
  if (!output) {
326
- output = await this.$packageManager.view(`${constants_1.SCOPED_ANDROID_RUNTIME_NAME}@${runtimeVersion}`, { gradle: true });
327
- output = (_b = output === null || output === void 0 ? void 0 : output["gradle"]) !== null && _b !== void 0 ? _b : output;
337
+ output = await this.$packageManager.view(`${packageName}@${runtimeVersion}`, { gradle: true });
338
+ output = (_c = output === null || output === void 0 ? void 0 : output["gradle"]) !== null && _c !== void 0 ? _c : output;
328
339
  const { version, android } = output;
329
340
  output = {
330
341
  gradle: version,
@@ -335,7 +346,7 @@ class AndroidPluginBuildService {
335
346
  }
336
347
  catch (err) {
337
348
  this.$logger.trace(`Error while getting gradle data for android runtime from view command: ${err}`);
338
- const registryData = await this.$packageManager.getRegistryPackageData(constants_1.SCOPED_ANDROID_RUNTIME_NAME);
349
+ const registryData = await this.$packageManager.getRegistryPackageData(packageName);
339
350
  runtimeGradleVersions = registryData.versions[runtimeVersion];
340
351
  }
341
352
  const result = this.getGradleVersionsCore(runtimeGradleVersions);
@@ -370,16 +381,6 @@ class AndroidPluginBuildService {
370
381
  const replacedFileContent = fileContent.replace(contentRegex, replacement);
371
382
  this.$fs.writeFile(filePath, replacedFileContent);
372
383
  }
373
- addCompileDependencies(platformsAndroidDirPath, buildGradlePath) {
374
- const includeGradlePath = path.join(platformsAndroidDirPath, constants_1.INCLUDE_GRADLE_NAME);
375
- if (this.$fs.exists(includeGradlePath)) {
376
- const includeGradleContent = this.$fs.readText(includeGradlePath);
377
- const compileDependencies = this.getIncludeGradleCompileDependenciesScope(includeGradleContent);
378
- if (compileDependencies.length) {
379
- this.$fs.appendFile(buildGradlePath, "\n" + compileDependencies.join("\n"));
380
- }
381
- }
382
- }
383
384
  copyAar(shortPluginName, pluginTempDir, aarOutputDir) {
384
385
  const finalAarName = `${shortPluginName}-release.aar`;
385
386
  const pathToBuiltAar = path.join(pluginTempDir, "build", "outputs", "aar", finalAarName);
@@ -428,19 +429,32 @@ class AndroidPluginBuildService {
428
429
  async buildPlugin(pluginBuildSettings) {
429
430
  var _a;
430
431
  const gradlew = (_a = pluginBuildSettings.gradlePath) !== null && _a !== void 0 ? _a : (this.$hostInfo.isWindows ? "gradlew.bat" : "./gradlew");
432
+ const toolsInfo = this.$androidToolsInfo.getToolsInfo({
433
+ projectDir: this.$projectData.projectDir,
434
+ });
431
435
  const localArgs = [
432
436
  "-p",
433
437
  pluginBuildSettings.pluginDir,
434
438
  "assembleRelease",
435
439
  `-PtempBuild=true`,
440
+ `-PcompileSdk=${toolsInfo.compileSdkVersion}`,
441
+ `-PbuildToolsVersion=${toolsInfo.buildToolsVersion}`,
442
+ `-PprojectRoot=${this.$projectData.projectDir}`,
443
+ `-DprojectRoot=${this.$projectData.projectDir}`,
436
444
  `-PappPath=${this.$projectData.getAppDirectoryPath()}`,
445
+ `-PappBuildPath=${this.$projectData.getBuildRelativeDirectoryPath()}`,
446
+ `-DappBuildPath=${this.$projectData.getBuildRelativeDirectoryPath()}`,
437
447
  `-PappResourcesPath=${this.$projectData.getAppResourcesDirectoryPath()}`,
438
448
  ];
439
449
  if (pluginBuildSettings.gradleArgs) {
440
- localArgs.push(pluginBuildSettings.gradleArgs);
450
+ const additionalArgs = [];
451
+ pluginBuildSettings.gradleArgs.forEach((arg) => {
452
+ additionalArgs.push(...arg.split(" -P").map((a, i) => (i === 0 ? a : `-P${a}`)));
453
+ });
454
+ localArgs.push(...additionalArgs);
441
455
  }
442
456
  if (this.$logger.getLevel() === "INFO") {
443
- localArgs.push("--quiet");
457
+ localArgs.push("--info");
444
458
  }
445
459
  const opts = {
446
460
  cwd: pluginBuildSettings.pluginDir,
@@ -38,7 +38,7 @@ function topologicalSortNativeDependencies(dependencies, start = [], depth = 0,
38
38
  return sortedDeps;
39
39
  }
40
40
  class AndroidProjectService extends projectServiceBaseLib.PlatformProjectServiceBase {
41
- constructor($androidToolsInfo, $errors, $fs, $logger, $projectDataService, $options, $injector, $devicePlatformsConstants, $androidPluginBuildService, $platformEnvironmentRequirements, $androidResourcesMigrationService, $filesHashService, $gradleCommandService, $gradleBuildService, $analyticsService) {
41
+ constructor($androidToolsInfo, $errors, $fs, $logger, $projectDataService, $options, $injector, $devicePlatformsConstants, $androidPluginBuildService, $platformEnvironmentRequirements, $androidResourcesMigrationService, $liveSyncProcessDataService, $devicesService, $filesHashService, $gradleCommandService, $gradleBuildService, $analyticsService) {
42
42
  super($fs, $projectDataService);
43
43
  this.$androidToolsInfo = $androidToolsInfo;
44
44
  this.$errors = $errors;
@@ -49,6 +49,8 @@ class AndroidProjectService extends projectServiceBaseLib.PlatformProjectService
49
49
  this.$androidPluginBuildService = $androidPluginBuildService;
50
50
  this.$platformEnvironmentRequirements = $platformEnvironmentRequirements;
51
51
  this.$androidResourcesMigrationService = $androidResourcesMigrationService;
52
+ this.$liveSyncProcessDataService = $liveSyncProcessDataService;
53
+ this.$devicesService = $devicesService;
52
54
  this.$filesHashService = $filesHashService;
53
55
  this.$gradleCommandService = $gradleCommandService;
54
56
  this.$gradleBuildService = $gradleBuildService;
@@ -176,6 +178,11 @@ class AndroidProjectService extends projectServiceBaseLib.PlatformProjectService
176
178
  const targetSdkVersion = androidToolsInfo && androidToolsInfo.targetSdkVersion;
177
179
  this.$logger.trace(`Using Android SDK '${targetSdkVersion}'.`);
178
180
  this.copy(this.getPlatformData(projectData).projectRoot, frameworkDir, "*", "-R");
181
+ if (this.$options.overrideRuntimeGradleFiles !== false) {
182
+ const gradleTemplatePath = path.resolve(path.join(__dirname, "../../vendor/gradle-app"));
183
+ const allGradleTemplateFiles = path.join(gradleTemplatePath, "*");
184
+ this.$fs.copyFile(allGradleTemplateFiles, path.join(this.getPlatformData(projectData).projectRoot));
185
+ }
179
186
  this.cleanResValues(targetSdkVersion, projectData);
180
187
  }
181
188
  getResDestinationDir(projectData) {
@@ -220,7 +227,14 @@ class AndroidProjectService extends projectServiceBaseLib.PlatformProjectService
220
227
  shell.sed("-i", /__NAME__/, projectData.projectName, stringsFilePath);
221
228
  shell.sed("-i", /__TITLE_ACTIVITY__/, projectData.projectName, stringsFilePath);
222
229
  const gradleSettingsFilePath = path.join(this.getPlatformData(projectData).projectRoot, "settings.gradle");
230
+ const relativePath = path.relative(this.getPlatformData(projectData).projectRoot, projectData.projectDir);
231
+ shell.sed("-i", /def USER_PROJECT_ROOT = \"\$rootDir\/..\/..\/\"/, `def USER_PROJECT_ROOT = "$rootDir/${relativePath}"`, gradleSettingsFilePath);
223
232
  shell.sed("-i", /__PROJECT_NAME__/, this.getProjectNameFromId(projectData), gradleSettingsFilePath);
233
+ const gradleVersion = projectData.nsConfig.android.gradleVersion;
234
+ if (gradleVersion) {
235
+ const gradleWrapperFilePath = path.join(this.getPlatformData(projectData).projectRoot, "gradle", "wrapper", "gradle-wrapper.properties");
236
+ shell.sed("-i", /gradle-([0-9.]+)-bin.zip/, `gradle-${gradleVersion}-bin.zip`, gradleWrapperFilePath);
237
+ }
224
238
  try {
225
239
  const appGradleContent = this.$fs.readText(projectData.appGradlePath);
226
240
  if (appGradleContent.indexOf(constants.PACKAGE_PLACEHOLDER_NAME) !== -1) {
@@ -234,6 +248,11 @@ class AndroidProjectService extends projectServiceBaseLib.PlatformProjectService
234
248
  interpolateConfigurationFile(projectData) {
235
249
  const manifestPath = this.getPlatformData(projectData).configurationFilePath;
236
250
  shell.sed("-i", /__PACKAGE__/, projectData.projectIdentifiers.android, manifestPath);
251
+ const buildAppGradlePath = path.join(this.getPlatformData(projectData).projectRoot, "app", "build.gradle");
252
+ const buildGradlePath = path.join(this.getPlatformData(projectData).projectRoot, "build.gradle");
253
+ shell.sed("-i", /__PACKAGE__/, projectData.projectIdentifiers.android, buildAppGradlePath);
254
+ const relativePath = path.relative(this.getPlatformData(projectData).projectRoot, projectData.projectDir);
255
+ shell.sed("-i", /project.ext.USER_PROJECT_ROOT = \"\$rootDir\/..\/..\"/, `project.ext.USER_PROJECT_ROOT = "$rootDir/${relativePath}"`, buildGradlePath);
237
256
  }
238
257
  getProjectNameFromId(projectData) {
239
258
  let id;
@@ -302,7 +321,18 @@ class AndroidProjectService extends projectServiceBaseLib.PlatformProjectService
302
321
  this.$fs.ensureDirectoryExists(platformsAppResourcesPath);
303
322
  const appResourcesDirStructureHasMigrated = this.$androidResourcesMigrationService.hasMigrated(projectAppResourcesPath);
304
323
  if (appResourcesDirStructureHasMigrated) {
305
- this.$fs.copyFile(path.join(projectAppResourcesPath, platformData.normalizedPlatformName, constants.SRC_DIR, "*"), platformsAppResourcesPath);
324
+ const resourcesPath = path.join(projectAppResourcesPath, platformData.normalizedPlatformName);
325
+ this.$fs.copyFile(path.join(resourcesPath, constants.SRC_DIR, "*"), platformsAppResourcesPath);
326
+ const destinationFolder = this.getPlatformData(projectData).projectRoot;
327
+ const contents = this.$fs.readDirectory(resourcesPath);
328
+ _.each(contents, (fileName) => {
329
+ const filePath = path.join(resourcesPath, fileName);
330
+ const fsStat = this.$fs.getFsStats(filePath);
331
+ if (fsStat.isDirectory() && fileName !== constants.SRC_DIR) {
332
+ console.log("copying folder", filePath);
333
+ this.$fs.copyFile(filePath, destinationFolder);
334
+ }
335
+ });
306
336
  }
307
337
  else {
308
338
  this.$fs.copyFile(path.join(projectAppResourcesPath, platformData.normalizedPlatformName, "*"), platformsAppResourcesPath);
@@ -317,14 +347,17 @@ class AndroidProjectService extends projectServiceBaseLib.PlatformProjectService
317
347
  async preparePluginNativeCode(pluginData, projectData) {
318
348
  const pluginPlatformsFolderPath = this.getPluginPlatformsFolderPath(pluginData, AndroidProjectService.ANDROID_PLATFORM_NAME);
319
349
  if (this.$fs.exists(pluginPlatformsFolderPath)) {
350
+ const gradleArgs = (projectData.nsConfig.android.gradleArgs || []).concat(this.$options.gradleArgs || []);
351
+ const pluginOptions = (projectData.nsConfig.android.plugins || {})[pluginData.name] || {};
320
352
  const options = {
321
353
  gradlePath: this.$options.gradlePath,
322
- gradleArgs: this.$options.gradleArgs,
354
+ gradleArgs,
323
355
  projectDir: projectData.projectDir,
324
356
  pluginName: pluginData.name,
325
357
  platformsAndroidDirPath: pluginPlatformsFolderPath,
326
358
  aarOutputDir: pluginPlatformsFolderPath,
327
359
  tempPluginDirPath: path.join(projectData.platformsDir, "tempPlugin"),
360
+ ...pluginOptions
328
361
  };
329
362
  if (await this.$androidPluginBuildService.buildAar(options)) {
330
363
  this.$logger.info(`Built aar for ${options.pluginName}`);
@@ -404,7 +437,33 @@ class AndroidProjectService extends projectServiceBaseLib.PlatformProjectService
404
437
  const deviceRootPath = `${constants_1.LiveSyncPaths.ANDROID_TMP_DIR_NAME}/${projectData.projectIdentifiers.android}`;
405
438
  await adb.executeShellCommand(["rm", "-rf", deviceRootPath]);
406
439
  }
407
- async checkForChanges() {
440
+ async checkForChanges(changesInfo, prepareData, projectData) {
441
+ const deviceDescriptors = this.$liveSyncProcessDataService.getDeviceDescriptors(projectData.projectDir);
442
+ const platformData = this.getPlatformData(projectData);
443
+ deviceDescriptors.forEach((deviceDescriptor) => {
444
+ const buildData = deviceDescriptor.buildData;
445
+ if (buildData.buildFilterDevicesArch) {
446
+ const outputPath = platformData.getBuildOutputPath(deviceDescriptor.buildData);
447
+ const apkOutputPath = path.join(outputPath, prepareData.release ? "release" : "debug");
448
+ if (!this.$fs.exists(apkOutputPath)) {
449
+ return;
450
+ }
451
+ const directoryContent = this.$fs.readDirectory(apkOutputPath);
452
+ if (!directoryContent.find(f => f.indexOf("universal") !== -1)) {
453
+ const device = this.$devicesService
454
+ .getDevicesForPlatform(deviceDescriptor.buildData.platform)
455
+ .filter((d) => d.deviceInfo.identifier === deviceDescriptor.identifier)[0];
456
+ const abis = device.deviceInfo.abis.filter((a) => !!a && a.length)[0];
457
+ const regexp = new RegExp(`${abis}.*\.apk`);
458
+ const files = _.filter(directoryContent, (entry) => {
459
+ return regexp.test(entry);
460
+ });
461
+ if (files.length === 0) {
462
+ changesInfo.nativeChanged = true;
463
+ }
464
+ }
465
+ }
466
+ });
408
467
  }
409
468
  getDeploymentTarget(projectData) {
410
469
  return;
@@ -39,23 +39,38 @@ class BuildArtifactsService {
39
39
  }
40
40
  return [];
41
41
  }
42
- copyLatestAppPackage(targetPath, platformData, buildOutputOptions) {
42
+ copyAppPackages(targetPath, platformData, buildOutputOptions) {
43
43
  targetPath = path.resolve(targetPath);
44
44
  const outputPath = buildOutputOptions.outputPath ||
45
45
  platformData.getBuildOutputPath(buildOutputOptions);
46
- const applicationPackage = this.getLatestApplicationPackage(outputPath, platformData.getValidBuildOutputData(buildOutputOptions));
47
- const packageFile = applicationPackage.packageName;
46
+ const applicationPackages = this.getAllAppPackages(outputPath, platformData.getValidBuildOutputData(buildOutputOptions));
48
47
  this.$fs.ensureDirectoryExists(path.dirname(targetPath));
48
+ let filterRegex;
49
+ let targetIsDirectory = false;
49
50
  if (this.$fs.exists(targetPath) &&
50
51
  this.$fs.getFsStats(targetPath).isDirectory()) {
51
- const sourceFileName = path.basename(packageFile);
52
- this.$logger.trace(`Specified target path: '${targetPath}' is directory. Same filename will be used: '${sourceFileName}'.`);
53
- targetPath = path.join(targetPath, sourceFileName);
52
+ targetIsDirectory = true;
53
+ }
54
+ else if (targetPath.match(/\.(ipa|aab|apk)/)) {
55
+ if (applicationPackages.length > 1) {
56
+ filterRegex = new RegExp("universal");
57
+ this.$logger.trace(`Multiple packages were built but only the universal one will be copied if existing'.`);
58
+ }
54
59
  }
55
- this.$fs.copyFile(packageFile, targetPath);
56
- this.$logger.info(`Copied file '${packageFile}' to '${targetPath}'.`);
60
+ else {
61
+ targetIsDirectory = true;
62
+ }
63
+ applicationPackages.forEach((pack) => {
64
+ const targetFilePath = targetIsDirectory
65
+ ? path.join(targetPath, path.basename(pack.packageName))
66
+ : targetPath;
67
+ if (!filterRegex || filterRegex.test(pack.packageName)) {
68
+ this.$fs.copyFile(pack.packageName, targetFilePath);
69
+ this.$logger.info(`Copied file '${pack.packageName}' to '${targetFilePath}'.`);
70
+ }
71
+ });
57
72
  }
58
- getLatestApplicationPackage(buildOutputPath, validBuildOutputData) {
73
+ getLatestApplicationPackage(buildOutputPath, validBuildOutputData, abis) {
59
74
  let packages = this.getAllAppPackages(buildOutputPath, validBuildOutputData);
60
75
  const packageExtName = path.extname(validBuildOutputData.packageNames[0]);
61
76
  if (packages.length === 0) {