Skip to content

Commit a638f7d

Browse files
authored
Stop copying android plugin code, stop writing configurations dir (#3032)
* Filter distinct dependencies, write dependencies.json to android instead of creating configurations No 'gradle clean' during prepare * remove dead android project service code * refactor method name * add runtime version checks when preparing android platform to determine which branch of logic is used modify test that verifies gradlew clean is executed on before prepare step make tslint happy
1 parent 476ec6c commit a638f7d

File tree

2 files changed

+91
-17
lines changed

2 files changed

+91
-17
lines changed

lib/services/android-project-service.ts

Lines changed: 79 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
4949

5050
if (projectData && projectData.platformsDir && this._platformsDirCache !== projectData.platformsDir) {
5151
this._platformsDirCache = projectData.platformsDir;
52-
const projectRoot = path.join(projectData.platformsDir, "android");
52+
const projectRoot = path.join(projectData.platformsDir, AndroidProjectService.ANDROID_PLATFORM_NAME);
5353
const packageName = this.getProjectNameFromId(projectData);
5454
this._platformData = {
5555
frameworkPackageName: "tns-android",
@@ -79,6 +79,14 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
7979
return this._platformData;
8080
}
8181

82+
// TODO: Remove prior to the 4.0 CLI release @Pip3r4o @PanayotCankov
83+
// Similar to the private method of the same name in platform-service.
84+
private getCurrentPlatformVersion(platformData: IPlatformData, projectData: IProjectData): string {
85+
const currentPlatformData: IDictionary<any> = this.$projectDataService.getNSValue(projectData.projectDir, platformData.frameworkPackageName);
86+
87+
return currentPlatformData && currentPlatformData[constants.VERSION_STRING];
88+
}
89+
8290
public validateOptions(): Promise<boolean> {
8391
return Promise.resolve(true);
8492
}
@@ -348,8 +356,12 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
348356
}
349357

350358
public async preparePluginNativeCode(pluginData: IPluginData, projectData: IProjectData): Promise<void> {
351-
const pluginPlatformsFolderPath = this.getPluginPlatformsFolderPath(pluginData, AndroidProjectService.ANDROID_PLATFORM_NAME);
352-
await this.processResourcesFromPlugin(pluginData, pluginPlatformsFolderPath, projectData);
359+
if (!this.shouldUseNewRuntimeGradleRoutine(projectData)) {
360+
const pluginPlatformsFolderPath = this.getPluginPlatformsFolderPath(pluginData, AndroidProjectService.ANDROID_PLATFORM_NAME);
361+
await this.processResourcesFromPlugin(pluginData, pluginPlatformsFolderPath, projectData);
362+
}
363+
364+
// Do nothing, the Android Gradle script will configure itself based on the input dependencies.json
353365
}
354366

355367
public async processConfigurationFilesFromAppResources(): Promise<void> {
@@ -389,9 +401,13 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
389401
public async removePluginNativeCode(pluginData: IPluginData, projectData: IProjectData): Promise<void> {
390402
try {
391403
// check whether the dependency that's being removed has native code
392-
const pluginConfigDir = path.join(this.getPlatformData(projectData).projectRoot, "configurations", pluginData.name);
393-
if (this.$fs.exists(pluginConfigDir)) {
394-
await this.cleanProject(this.getPlatformData(projectData).projectRoot, projectData);
404+
// TODO: Remove prior to the 4.0 CLI release @Pip3r4o @PanayotCankov
405+
// the updated gradle script will take care of cleaning the prepared android plugins
406+
if (!this.shouldUseNewRuntimeGradleRoutine(projectData)) {
407+
const pluginConfigDir = path.join(this.getPlatformData(projectData).projectRoot, "configurations", pluginData.name);
408+
if (this.$fs.exists(pluginConfigDir)) {
409+
await this.cleanProject(this.getPlatformData(projectData).projectRoot, projectData);
410+
}
395411
}
396412
} catch (e) {
397413
if (e.code === "ENOENT") {
@@ -407,23 +423,61 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
407423
}
408424

409425
public async beforePrepareAllPlugins(projectData: IProjectData, dependencies?: IDependencyData[]): Promise<void> {
426+
const shouldUseNewRoutine = this.shouldUseNewRuntimeGradleRoutine(projectData);
427+
410428
if (dependencies) {
411-
const platformDir = path.join(projectData.platformsDir, "android");
412-
const buildDir = path.join(platformDir, "build-tools");
413-
const checkV8dependants = path.join(buildDir, "check-v8-dependants.js");
414-
if (this.$fs.exists(checkV8dependants)) {
415-
const stringifiedDependencies = JSON.stringify(dependencies);
416-
try {
417-
await this.spawn('node', [checkV8dependants, stringifiedDependencies, projectData.platformsDir], { stdio: "inherit" });
418-
} catch (e) {
419-
this.$logger.info("Checking for dependants on v8 public API failed. This is likely caused because of cyclic production dependencies. Error code: " + e.code + "\nMore information: https://github.com/NativeScript/nativescript-cli/issues/2561");
429+
dependencies = this.filterUniqueDependencies(dependencies);
430+
if (shouldUseNewRoutine) {
431+
this.provideDependenciesJson(projectData, dependencies);
432+
} else {
433+
// TODO: Remove prior to the 4.0 CLI release @Pip3r4o @PanayotCankov
434+
435+
const platformDir = path.join(projectData.platformsDir, AndroidProjectService.ANDROID_PLATFORM_NAME);
436+
const buildDir = path.join(platformDir, "build-tools");
437+
const checkV8dependants = path.join(buildDir, "check-v8-dependants.js");
438+
if (this.$fs.exists(checkV8dependants)) {
439+
const stringifiedDependencies = JSON.stringify(dependencies);
440+
try {
441+
await this.spawn('node', [checkV8dependants, stringifiedDependencies, projectData.platformsDir], { stdio: "inherit" });
442+
} catch (e) {
443+
this.$logger.info("Checking for dependants on v8 public API failed. This is likely caused because of cyclic production dependencies. Error code: " + e.code + "\nMore information: https://github.com/NativeScript/nativescript-cli/issues/2561");
444+
}
420445
}
421446
}
422447
}
423448

424-
const projectRoot = this.getPlatformData(projectData).projectRoot;
449+
if (!shouldUseNewRoutine) {
450+
// TODO: Remove prior to the 4.0 CLI release @Pip3r4o @PanayotCankov
451+
const projectRoot = this.getPlatformData(projectData).projectRoot;
452+
await this.cleanProject(projectRoot, projectData);
453+
}
454+
}
425455

426-
await this.cleanProject(projectRoot, projectData);
456+
private filterUniqueDependencies(dependencies: IDependencyData[]): IDependencyData[] {
457+
const depsDictionary = dependencies.reduce((dict, dep) => {
458+
const collision = dict[dep.name];
459+
// in case there are multiple dependencies to the same module, the one declared in the package.json takes precedence
460+
if (!collision || collision.depth > dep.depth) {
461+
dict[dep.name] = dep;
462+
}
463+
return dict;
464+
}, <IDictionary<IDependencyData>>{});
465+
return _.values(depsDictionary);
466+
}
467+
468+
private provideDependenciesJson(projectData: IProjectData, dependencies: IDependencyData[]): void {
469+
const platformDir = path.join(projectData.platformsDir, AndroidProjectService.ANDROID_PLATFORM_NAME);
470+
const dependenciesJsonPath = path.join(platformDir, "dependencies.json");
471+
const nativeDependencies = dependencies
472+
.filter(AndroidProjectService.isNativeAndroidDependency)
473+
.map(({ name, directory }) => ({ name, directory: path.relative(platformDir, directory) }));
474+
const jsonContent = JSON.stringify(nativeDependencies, null, 4);
475+
476+
this.$fs.writeFile(dependenciesJsonPath, jsonContent);
477+
}
478+
479+
private static isNativeAndroidDependency({ nativescript }: IDependencyData): boolean {
480+
return nativescript && (nativescript.android || (nativescript.platforms && nativescript.platforms.android));
427481
}
428482

429483
public stopServices(projectRoot: string): Promise<ISpawnResult> {
@@ -530,6 +584,14 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
530584
spawnFromEventOptions);
531585
}
532586
}
587+
588+
// TODO: Remove prior to the 4.0 CLI release @Pip3r4o @PanayotCankov
589+
private shouldUseNewRuntimeGradleRoutine(projectData: IProjectData): boolean {
590+
const platformVersion = this.getCurrentPlatformVersion(this.getPlatformData(projectData), projectData);
591+
const newRuntimeGradleRoutineVersion = "3.3.0";
592+
593+
return semver.gte(platformVersion, newRuntimeGradleRoutineVersion);
594+
}
533595
}
534596

535597
$injector.register("androidProjectService", AndroidProjectService);

test/debug.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,8 +342,20 @@ describe("debug command tests", () => {
342342
});
343343

344344
it("Ensures that beforePrepareAllPlugins will call gradle with clean option when *NOT* livesyncing", async () => {
345+
const platformData = testInjector.resolve<IPlatformData>("platformsData");
346+
platformData.frameworkPackageName = "tns-android";
347+
348+
// only test that 'clean' is performed on android <=3.2. See https://github.com/NativeScript/nativescript-cli/pull/3032
349+
const projectDataService: IProjectDataService = testInjector.resolve("projectDataService");
350+
projectDataService.getNSValue = (projectDir: string, propertyName: string) => {
351+
return { version: "3.2.0" };
352+
};
353+
345354
const childProcess: stubs.ChildProcessStub = testInjector.resolve("childProcess");
346355
const androidProjectService: IPlatformProjectService = testInjector.resolve("androidProjectService");
356+
androidProjectService.getPlatformData = (projectData: IProjectData): IPlatformData => {
357+
return platformData;
358+
};
347359
const projectData: IProjectData = testInjector.resolve("projectData");
348360
const spawnFromEventCount = childProcess.spawnFromEventCount;
349361
await androidProjectService.beforePrepareAllPlugins(projectData);

0 commit comments

Comments
 (0)