Skip to content

Commit 7e50434

Browse files
Merge pull request #3735 from NativeScript/vladimirov/speed-up-add-platform
feat: Speed up adding native platform
2 parents cff6778 + 0a39153 commit 7e50434

File tree

6 files changed

+104
-120
lines changed

6 files changed

+104
-120
lines changed

lib/npm-installation-manager.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ export class NpmInstallationManager implements INpmInstallationManager {
66
constructor(private $npm: INodePackageManager,
77
private $childProcess: IChildProcess,
88
private $logger: ILogger,
9-
private $options: IOptions,
109
private $settingsService: ISettingsService,
1110
private $fs: IFileSystem,
1211
private $staticConfig: IStaticConfig,
@@ -39,9 +38,8 @@ export class NpmInstallationManager implements INpmInstallationManager {
3938
return maxSatisfying || latestVersion;
4039
}
4140

42-
public async install(packageName: string, projectDir: string, opts?: INpmInstallOptions): Promise<any> {
41+
public async install(packageToInstall: string, projectDir: string, opts?: INpmInstallOptions): Promise<any> {
4342
try {
44-
const packageToInstall = this.$options.frameworkPath || packageName;
4543
const pathToSave = projectDir;
4644
const version = (opts && opts.version) || null;
4745
const dependencyType = (opts && opts.dependencyType) || null;

lib/services/android-project-service.ts

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
144144
const targetSdkVersion = androidToolsInfo && androidToolsInfo.targetSdkVersion;
145145
this.$logger.trace(`Using Android SDK '${targetSdkVersion}'.`);
146146

147-
this.isAndroidStudioTemplate = this.isAndroidStudioCompatibleTemplate(projectData);
147+
this.isAndroidStudioTemplate = this.isAndroidStudioCompatibleTemplate(projectData, frameworkVersion);
148148
if (this.isAndroidStudioTemplate) {
149149
this.copy(this.getPlatformData(projectData).projectRoot, frameworkDir, "*", "-R");
150150
} else {
@@ -703,20 +703,12 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
703703
}
704704
}
705705

706-
private isAndroidStudioCompatibleTemplate(projectData: IProjectData): boolean {
706+
private isAndroidStudioCompatibleTemplate(projectData: IProjectData, frameworkVersion?: string): boolean {
707707
const currentPlatformData: IDictionary<any> = this.$projectDataService.getNSValue(projectData.projectDir, constants.TNS_ANDROID_RUNTIME_NAME);
708-
let platformVersion = currentPlatformData && currentPlatformData[constants.VERSION_STRING];
708+
const platformVersion = (currentPlatformData && currentPlatformData[constants.VERSION_STRING]) || frameworkVersion;
709709

710710
if (!platformVersion) {
711-
const tnsAndroidPackageJsonPath = path.join(projectData.projectDir, constants.NODE_MODULES_FOLDER_NAME, constants.TNS_ANDROID_RUNTIME_NAME, constants.PACKAGE_JSON_FILE_NAME);
712-
if (this.$fs.exists(tnsAndroidPackageJsonPath)) {
713-
const projectPackageJson: any = this.$fs.readJson(tnsAndroidPackageJsonPath);
714-
if (projectPackageJson && projectPackageJson.version) {
715-
platformVersion = projectPackageJson.version;
716-
}
717-
} else {
718-
return true;
719-
}
711+
return true;
720712
}
721713

722714
if (platformVersion === constants.PackageVersion.NEXT || platformVersion === constants.PackageVersion.LATEST || platformVersion === constants.PackageVersion.RC) {

lib/services/platform-service.ts

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,12 @@ export class PlatformService extends EventEmitter implements IPlatformService {
3636
private $mobileHelper: Mobile.IMobileHelper,
3737
private $hostInfo: IHostInfo,
3838
private $devicePathProvider: IDevicePathProvider,
39-
private $npm: INodePackageManager,
4039
private $devicePlatformsConstants: Mobile.IDevicePlatformsConstants,
4140
private $projectChangesService: IProjectChangesService,
4241
private $analyticsService: IAnalyticsService,
43-
private $terminalSpinnerService: ITerminalSpinnerService) {
42+
private $terminalSpinnerService: ITerminalSpinnerService,
43+
private $pacoteService: IPacoteService
44+
) {
4445
super();
4546
}
4647

@@ -92,10 +93,6 @@ export class PlatformService extends EventEmitter implements IPlatformService {
9293

9394
const platformData = this.$platformsData.getPlatformData(platform, projectData);
9495

95-
if (version === undefined) {
96-
version = this.getCurrentPlatformVersion(platform, projectData);
97-
}
98-
9996
// Log the values for project
10097
this.$logger.trace("Creating NativeScript project for the %s platform", platform);
10198
this.$logger.trace("Path: %s", platformData.projectRoot);
@@ -105,28 +102,28 @@ export class PlatformService extends EventEmitter implements IPlatformService {
105102
this.$logger.out("Copying template files...");
106103

107104
let packageToInstall = "";
108-
const npmOptions: IStringDictionary = {
109-
pathToSave: path.join(projectData.platformsDir, platform),
110-
dependencyType: "save"
111-
};
105+
if (frameworkPath) {
106+
packageToInstall = path.resolve(frameworkPath);
107+
} else {
108+
if (!version) {
109+
version = this.getCurrentPlatformVersion(platform, projectData) ||
110+
await this.$npmInstallationManager.getLatestCompatibleVersion(platformData.frameworkPackageName);
111+
}
112112

113-
if (!frameworkPath) {
114-
packageToInstall = platformData.frameworkPackageName;
115-
npmOptions["version"] = version;
113+
packageToInstall = `${platformData.frameworkPackageName}@${version}`;
116114
}
117115

118116
const spinner = this.$terminalSpinnerService.createSpinner();
119-
const projectDir = projectData.projectDir;
120117
const platformPath = path.join(projectData.platformsDir, platform);
121118

122119
try {
123120
spinner.start();
124-
const downloadedPackagePath = await this.$npmInstallationManager.install(packageToInstall, projectDir, npmOptions);
121+
const downloadedPackagePath = temp.mkdirSync("runtimeDir");
122+
temp.track();
123+
await this.$pacoteService.extractPackage(packageToInstall, downloadedPackagePath);
125124
let frameworkDir = path.join(downloadedPackagePath, constants.PROJECT_FRAMEWORK_FOLDER_NAME);
126125
frameworkDir = path.resolve(frameworkDir);
127-
128-
const coreModuleName = await this.addPlatformCore(platformData, frameworkDir, platformTemplate, projectData, config, nativePrepare);
129-
await this.$npm.uninstall(coreModuleName, { save: true }, projectData.projectDir);
126+
await this.addPlatformCore(platformData, frameworkDir, platformTemplate, projectData, config, nativePrepare);
130127
} catch (err) {
131128
this.$fs.deleteDirectory(platformPath);
132129
throw err;
@@ -135,7 +132,7 @@ export class PlatformService extends EventEmitter implements IPlatformService {
135132
}
136133

137134
this.$fs.ensureDirectoryExists(platformPath);
138-
this.$logger.out("Project successfully created.");
135+
this.$logger.out(`Platform ${platform} successfully added.`);
139136
}
140137

141138
private async addPlatformCore(platformData: IPlatformData, frameworkDir: string, platformTemplate: string, projectData: IProjectData, config: IPlatformOptions, nativePrepare?: INativePrepare): Promise<string> {
@@ -842,15 +839,15 @@ export class PlatformService extends EventEmitter implements IPlatformService {
842839
const data = this.$projectDataService.getNSValue(projectData.projectDir, platformData.frameworkPackageName);
843840
const currentVersion = data && data.version ? data.version : "0.2.0";
844841

842+
const installedModuleDir = temp.mkdirSync("runtime-to-update");
845843
let newVersion = version === constants.PackageVersion.NEXT ?
846844
await this.$npmInstallationManager.getNextVersion(platformData.frameworkPackageName) :
847845
version || await this.$npmInstallationManager.getLatestCompatibleVersion(platformData.frameworkPackageName);
848-
const installedModuleDir = await this.$npmInstallationManager.install(platformData.frameworkPackageName, projectData.projectDir, { version: newVersion, dependencyType: "save" });
846+
await this.$pacoteService.extractPackage(`${platformData.frameworkPackageName}@${newVersion}`, installedModuleDir);
849847
const cachedPackageData = this.$fs.readJson(path.join(installedModuleDir, "package.json"));
850848
newVersion = (cachedPackageData && cachedPackageData.version) || newVersion;
851849

852850
const canUpdate = platformData.platformProjectService.canUpdatePlatform(installedModuleDir, projectData);
853-
await this.$npm.uninstall(platformData.frameworkPackageName, { save: true }, projectData.projectDir);
854851
if (canUpdate) {
855852
if (!semver.valid(newVersion)) {
856853
this.$errors.fail("The version %s is not valid. The version should consists from 3 parts separated by dot.", newVersion);

test/npm-support.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@ function createTestInjector(): IInjector {
104104
getChanges: () => Promise.resolve({}),
105105
generateHashes: () => Promise.resolve()
106106
});
107+
testInjector.register("pacoteService", {
108+
extractPackage: async (packageName: string, destinationDirectory: string, options?: IPacoteExtractOptions): Promise<void> => undefined
109+
});
107110

108111
return testInjector;
109112
}

test/platform-commands.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,9 @@ function createTestInjector() {
168168
testInjector.register("platformEnvironmentRequirements", {
169169
checkEnvironmentRequirements: async (platform?: string, projectDir?: string, runtimeVersion?: string): Promise<boolean> => true
170170
});
171+
testInjector.register("pacoteService", {
172+
extractPackage: async (packageName: string, destinationDirectory: string, options?: IPacoteExtractOptions): Promise<void> => undefined
173+
});
171174

172175
return testInjector;
173176
}

0 commit comments

Comments
 (0)