Skip to content

Commit bd8c4a0

Browse files
authored
feat(android): ability to embed into host Kotlin projects (#5776)
1 parent 98c7066 commit bd8c4a0

17 files changed

+201
-77
lines changed

lib/controllers/prepare-controller.ts

+11-7
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import {
2222
TrackActionNames,
2323
WEBPACK_COMPILATION_COMPLETE,
2424
} from "../constants";
25-
import { IWatchIgnoreListService } from "../declarations";
25+
import { IOptions, IWatchIgnoreListService } from "../declarations";
2626
import {
2727
INodeModulesDependenciesBuilder,
2828
IPlatformController,
@@ -59,6 +59,7 @@ export class PrepareController extends EventEmitter {
5959
public $hooksService: IHooksService,
6060
private $fs: IFileSystem,
6161
private $logger: ILogger,
62+
private $options: IOptions,
6263
private $mobileHelper: Mobile.IMobileHelper,
6364
private $nodeModulesDependenciesBuilder: INodeModulesDependenciesBuilder,
6465
private $platformsDataService: IPlatformsDataService,
@@ -134,10 +135,13 @@ export class PrepareController extends EventEmitter {
134135
projectData: IProjectData
135136
): Promise<IPrepareResultData> {
136137
await this.$projectService.ensureAppResourcesExist(projectData.projectDir);
137-
await this.$platformController.addPlatformIfNeeded(
138-
prepareData,
139-
projectData
140-
);
138+
if (!this.$options.nativeHost) {
139+
await this.$platformController.addPlatformIfNeeded(
140+
prepareData,
141+
projectData
142+
);
143+
}
144+
141145
await this.trackRuntimeVersion(prepareData.platform, projectData);
142146

143147
this.$logger.info("Preparing project...");
@@ -479,9 +483,9 @@ export class PrepareController extends EventEmitter {
479483
console.log("!!!!! VM: proj root: " + platformData.projectRoot);
480484
packagePath = path.join(
481485
platformData.projectRoot,
482-
"app",
486+
this.$options.nativeHostModule,
483487
"src",
484-
"main",
488+
this.$options.nativeHost ? "nativescript" : "main",
485489
"assets",
486490
"app",
487491
"package.json"

lib/declarations.d.ts

+7-5
Original file line numberDiff line numberDiff line change
@@ -578,16 +578,18 @@ interface IAndroidBundleOptions {
578578
aab: boolean;
579579
}
580580

581-
interface IAndroidOptions {
582-
gradlePath: string;
583-
gradleArgs: string;
581+
interface IEmbedOptions {
584582
nativeHost: string;
583+
nativeHostModule: string;
585584
}
586585

587-
interface IIOSOptions {
588-
nativeHost: string;
586+
interface IAndroidOptions extends IEmbedOptions {
587+
gradlePath: string;
588+
gradleArgs: string;
589589
}
590590

591+
interface IIOSOptions extends IEmbedOptions {}
592+
591593
interface ITypingsOptions {
592594
jar: string;
593595
aar: string;

lib/helpers/platform-command-helper.ts

+12
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ export class PlatformCommandHelper implements IPlatformCommandHelper {
3939
frameworkPath: string,
4040
nativeHost?: string
4141
): Promise<void> {
42+
if (this.$options.nativeHost) {
43+
this.$logger.info("Ignoring platform add becuase of --android-host flag");
44+
return;
45+
}
46+
4247
const platformsDir = projectData.platformsDir;
4348
this.$fs.ensureDirectoryExists(platformsDir);
4449

@@ -86,6 +91,13 @@ export class PlatformCommandHelper implements IPlatformCommandHelper {
8691
platforms: string[],
8792
projectData: IProjectData
8893
): Promise<void> {
94+
if (this.$options.nativeHost) {
95+
this.$logger.info(
96+
"Ignoring platform remove becuase of --android-host flag"
97+
);
98+
return;
99+
}
100+
89101
for (const platform of platforms) {
90102
this.$platformValidationService.validatePlatformInstalled(
91103
platform,

lib/options.ts

+6
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
ISettingsService,
1111
} from "./common/declarations";
1212
import { injector } from "./common/yok";
13+
import { APP_FOLDER_NAME } from "./constants";
1314
export class Options {
1415
private static DASHED_OPTION_REGEX = /(.+?)([A-Z])(.*)/;
1516
private static NONDASHED_OPTION_REGEX = /(.+?)[-]([a-zA-Z])(.*)/;
@@ -228,6 +229,11 @@ export class Options {
228229
gradlePath: { type: OptionType.String, hasSensitiveValue: false },
229230
gradleArgs: { type: OptionType.String, hasSensitiveValue: false },
230231
nativeHost: { type: OptionType.String, hasSensitiveValue: false },
232+
nativeHostModule: {
233+
type: OptionType.String,
234+
hasSensitiveValue: false,
235+
default: APP_FOLDER_NAME,
236+
},
231237
aab: { type: OptionType.Boolean, hasSensitiveValue: false },
232238
performance: { type: OptionType.Object, hasSensitiveValue: true },
233239
appleApplicationSpecificPassword: {

lib/providers/project-files-provider.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ export class ProjectFilesProvider extends ProjectFilesProviderBase {
5454
);
5555
mappedFilePath = path.join(
5656
platformData.appDestinationDirectoryPath,
57-
constants.APP_FOLDER_NAME,
57+
this.$options.nativeHostModule,
5858
relativePath
5959
);
6060
}

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

+26-5
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
INodePackageManager,
1616
IAndroidToolsInfo,
1717
IWatchIgnoreListService,
18+
IOptions,
1819
} from "../declarations";
1920
import { IPlatformsDataService } from "../definitions/platform";
2021
import { IProjectData, IProjectDataService } from "../definitions/project";
@@ -37,6 +38,7 @@ import { IInjector } from "../common/definitions/yok";
3738
import { injector } from "../common/yok";
3839
import * as _ from "lodash";
3940
import { resolvePackageJSONPath } from "@rigor789/resolve-package-path";
41+
import { cwd } from "process";
4042

4143
export class AndroidPluginBuildService implements IAndroidPluginBuildService {
4244
private get $platformsDataService(): IPlatformsDataService {
@@ -47,6 +49,7 @@ export class AndroidPluginBuildService implements IAndroidPluginBuildService {
4749
private $fs: IFileSystem,
4850
private $childProcess: IChildProcess,
4951
private $hostInfo: IHostInfo,
52+
private $options: IOptions,
5053
private $androidToolsInfo: IAndroidToolsInfo,
5154
private $logger: ILogger,
5255
private $packageManager: INodePackageManager,
@@ -803,6 +806,7 @@ export class AndroidPluginBuildService implements IAndroidPluginBuildService {
803806
`-PappPath=${this.$projectData.getAppDirectoryPath()}`,
804807
`-PappResourcesPath=${this.$projectData.getAppResourcesDirectoryPath()}`,
805808
];
809+
806810
if (pluginBuildSettings.gradleArgs) {
807811
localArgs.push(pluginBuildSettings.gradleArgs);
808812
}
@@ -811,12 +815,29 @@ export class AndroidPluginBuildService implements IAndroidPluginBuildService {
811815
localArgs.push("--quiet");
812816
}
813817

818+
const opts: any = {
819+
cwd: pluginBuildSettings.pluginDir,
820+
stdio: "inherit",
821+
shell: this.$hostInfo.isWindows,
822+
};
823+
824+
if (this.$options.nativeHost) {
825+
opts.env = {
826+
USER_PROJECT_PLATFORMS_ANDROID: path.resolve(
827+
cwd(),
828+
this.$options.nativeHost
829+
), // TODO: couldn't `nativeHost` have an absolute path already?
830+
...process.env, // TODO: any other way to pass automatically the current process.env?
831+
};
832+
}
833+
814834
try {
815-
await this.$childProcess.spawnFromEvent(gradlew, localArgs, "close", {
816-
cwd: pluginBuildSettings.pluginDir,
817-
stdio: "inherit",
818-
shell: this.$hostInfo.isWindows,
819-
});
835+
await this.$childProcess.spawnFromEvent(
836+
gradlew,
837+
localArgs,
838+
"close",
839+
opts
840+
);
820841
} catch (err) {
821842
this.$errors.fail(
822843
`Failed to build plugin ${pluginBuildSettings.pluginName} : \n${err}`

lib/services/android-project-service.ts

+11-11
Original file line numberDiff line numberDiff line change
@@ -173,21 +173,21 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
173173

174174
const appDestinationDirectoryArr = [
175175
projectRoot,
176-
constants.APP_FOLDER_NAME,
176+
this.$options.nativeHostModule,
177177
constants.SRC_DIR,
178178
constants.MAIN_DIR,
179179
constants.ASSETS_DIR,
180180
];
181181
const configurationsDirectoryArr = [
182182
projectRoot,
183-
constants.APP_FOLDER_NAME,
183+
this.$options.nativeHostModule,
184184
constants.SRC_DIR,
185185
constants.MAIN_DIR,
186186
constants.MANIFEST_FILE_NAME,
187187
];
188188
const deviceBuildOutputArr = [
189189
projectRoot,
190-
constants.APP_FOLDER_NAME,
190+
this.$options.nativeHostModule,
191191
constants.BUILD_DIR,
192192
constants.OUTPUTS_DIR,
193193
constants.APK_DIR,
@@ -210,7 +210,7 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
210210
if (buildOptions.androidBundle) {
211211
return path.join(
212212
projectRoot,
213-
constants.APP_FOLDER_NAME,
213+
this.$options.nativeHostModule,
214214
constants.BUILD_DIR,
215215
constants.OUTPUTS_DIR,
216216
constants.BUNDLE_DIR
@@ -229,8 +229,8 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
229229
if (buildOptions.androidBundle) {
230230
return {
231231
packageNames: [
232-
`${constants.APP_FOLDER_NAME}${constants.AAB_EXTENSION_NAME}`,
233-
`${constants.APP_FOLDER_NAME}-${buildMode}${constants.AAB_EXTENSION_NAME}`,
232+
`${this.$options.nativeHostModule}${constants.AAB_EXTENSION_NAME}`,
233+
`${this.$options.nativeHostModule}-${buildMode}${constants.AAB_EXTENSION_NAME}`,
234234
],
235235
};
236236
}
@@ -240,11 +240,11 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
240240
`${packageName}-${buildMode}${constants.APK_EXTENSION_NAME}`,
241241
`${projectData.projectName}-${buildMode}${constants.APK_EXTENSION_NAME}`,
242242
`${projectData.projectName}${constants.APK_EXTENSION_NAME}`,
243-
`${constants.APP_FOLDER_NAME}-${buildMode}${constants.APK_EXTENSION_NAME}`,
243+
`${this.$options.nativeHostModule}-${buildMode}${constants.APK_EXTENSION_NAME}`,
244244
],
245245
regexes: [
246246
new RegExp(
247-
`(${packageName}|${constants.APP_FOLDER_NAME})-.*-(${Configurations.Debug}|${Configurations.Release})(-unsigned)?${constants.APK_EXTENSION_NAME}`,
247+
`(${packageName}|${this.$options.nativeHostModule})-.*-(${Configurations.Debug}|${Configurations.Release})(-unsigned)?${constants.APK_EXTENSION_NAME}`,
248248
"i"
249249
),
250250
],
@@ -570,7 +570,7 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
570570
return this.$fs.exists(
571571
path.join(
572572
this.getPlatformData(projectData).appDestinationDirectoryPath,
573-
constants.APP_FOLDER_NAME
573+
this.$options.nativeHostModule
574574
)
575575
);
576576
}
@@ -879,7 +879,7 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
879879
projectData: IProjectData
880880
): string {
881881
const resourcePath: string[] = [
882-
constants.APP_FOLDER_NAME,
882+
this.$options.nativeHostModule,
883883
constants.SRC_DIR,
884884
constants.MAIN_DIR,
885885
constants.RESOURCES_DIR,
@@ -895,7 +895,7 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
895895
projectData: IProjectData
896896
): string {
897897
const resourcePath: string[] = [
898-
constants.APP_FOLDER_NAME,
898+
this.$options.nativeHostModule,
899899
constants.SRC_DIR,
900900
];
901901

lib/services/files-hash-service.ts

+8-3
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
11
import { executeActionByChunks } from "../common/helpers";
22
import { DEFAULT_CHUNK_SIZE } from "../common/constants";
3-
import { APP_FOLDER_NAME, HASHES_FILE_NAME } from "../constants";
3+
import { HASHES_FILE_NAME } from "../constants";
44
import * as path from "path";
55
import * as _ from "lodash";
66
import { IFilesHashService } from "../definitions/files-hash-service";
77
import { IPlatformData } from "../definitions/platform";
88
import { IFileSystem, IStringDictionary } from "../common/declarations";
99
import { injector } from "../common/yok";
10+
import { IOptions } from "../declarations";
1011

1112
export class FilesHashService implements IFilesHashService {
12-
constructor(private $fs: IFileSystem, private $logger: ILogger) {}
13+
constructor(
14+
private $fs: IFileSystem,
15+
private $logger: ILogger,
16+
private $options: IOptions
17+
) {}
1318

1419
public async generateHashes(files: string[]): Promise<IStringDictionary> {
1520
const result: IStringDictionary = {};
@@ -37,7 +42,7 @@ export class FilesHashService implements IFilesHashService {
3742
): Promise<IStringDictionary> {
3843
const appFilesPath = path.join(
3944
platformData.appDestinationDirectoryPath,
40-
APP_FOLDER_NAME
45+
this.$options.nativeHostModule
4146
);
4247
const files = this.$fs.enumerateFilesInDirectorySync(appFilesPath);
4348
const hashes = await this.generateHashes(files);

lib/services/livesync/android-device-livesync-sockets-service.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { AndroidDeviceLiveSyncServiceBase } from "./android-device-livesync-service-base";
2-
import { APP_FOLDER_NAME } from "../../constants";
32
import { LiveSyncPaths } from "../../common/constants";
43
import { AndroidLivesyncTool } from "./android-livesync-tool";
54
import * as path from "path";
@@ -19,7 +18,8 @@ export class AndroidDeviceSocketsLiveSyncService
1918
extends AndroidDeviceLiveSyncServiceBase
2019
implements
2120
IAndroidNativeScriptDeviceLiveSyncService,
22-
INativeScriptDeviceLiveSyncService {
21+
INativeScriptDeviceLiveSyncService
22+
{
2323
private livesyncTool: IAndroidLivesyncTool;
2424
private static STATUS_UPDATE_INTERVAL = 10000;
2525
private static MINIMAL_VERSION_LONG_LIVING_CONNECTION = "0.2.0";
@@ -279,7 +279,7 @@ export class AndroidDeviceSocketsLiveSyncService
279279
);
280280
const projectFilesPath = path.join(
281281
platformData.appDestinationDirectoryPath,
282-
APP_FOLDER_NAME
282+
this.$options.nativeHostModule
283283
);
284284
if (!this.livesyncTool.hasConnection()) {
285285
await this.livesyncTool.connect({

lib/services/livesync/android-livesync-service.ts

+7-3
Original file line numberDiff line numberDiff line change
@@ -13,25 +13,29 @@ import {
1313
} from "../../common/declarations";
1414
import { IInjector } from "../../common/definitions/yok";
1515
import { injector } from "../../common/yok";
16+
import { IOptions } from "../../declarations";
1617

1718
export class AndroidLiveSyncService
1819
extends PlatformLiveSyncServiceBase
19-
implements IPlatformLiveSyncService {
20+
implements IPlatformLiveSyncService
21+
{
2022
private static MIN_SOCKETS_LIVESYNC_RUNTIME_VERSION = "4.2.0-2018-07-20-02";
2123
constructor(
2224
protected $platformsDataService: IPlatformsDataService,
2325
protected $projectFilesManager: IProjectFilesManager,
2426
private $injector: IInjector,
2527
$devicePathProvider: IDevicePathProvider,
2628
$fs: IFileSystem,
27-
$logger: ILogger
29+
$logger: ILogger,
30+
$options: IOptions
2831
) {
2932
super(
3033
$fs,
3134
$logger,
3235
$platformsDataService,
3336
$projectFilesManager,
34-
$devicePathProvider
37+
$devicePathProvider,
38+
$options
3539
);
3640
}
3741

0 commit comments

Comments
 (0)