diff --git a/lib/declarations.ts b/lib/declarations.ts index 7616b92968..583c4e6a27 100644 --- a/lib/declarations.ts +++ b/lib/declarations.ts @@ -11,13 +11,12 @@ interface INodePackageManager { interface INpmInstallationManager { getCacheRootPath(): string; - addToCache(packageName: string, version: string): IFuture; + addToCache(packageName: string, version: string): IFuture; cacheUnpack(packageName: string, version: string, unpackTarget?: string): IFuture; install(packageName: string, options?: INpmInstallOptions): IFuture; getLatestVersion(packageName: string): IFuture; getLatestCompatibleVersion(packageName: string): IFuture; getCachedPackagePath(packageName: string, version: string): string; - addCleanCopyToCache(packageName: string, version: string): IFuture; } interface INpmInstallOptions { diff --git a/lib/npm-installation-manager.ts b/lib/npm-installation-manager.ts index 101f0b46b2..1440d88033 100644 --- a/lib/npm-installation-manager.ts +++ b/lib/npm-installation-manager.ts @@ -42,19 +42,26 @@ export class NpmInstallationManager implements INpmInstallationManager { return path.join(this.getCacheRootPath(), packageName, version, "package"); } - public addToCache(packageName: string, version: string): IFuture { + public addToCache(packageName: string, version: string): IFuture { return (() => { let cachedPackagePath = this.getCachedPackagePath(packageName, version); + let cachedPackageData: any; if(!this.$fs.exists(cachedPackagePath).wait() || !this.$fs.exists(path.join(cachedPackagePath, "framework")).wait()) { - this.addToCacheCore(packageName, version).wait(); + cachedPackageData = this.addToCacheCore(packageName, version).wait(); } - if(!this.isShasumOfPackageCorrect(packageName, version).wait()) { + // In case the version is tag (for example `next`), we need the real version number from the cache. + // In these cases the cachePackageData is populated when data is added to the cache. + // Also whenever the version is tag, we always get inside the above `if` and the cachedPackageData is populated. + let realVersion = (cachedPackageData && cachedPackageData.version) || version; + if(!this.isShasumOfPackageCorrect(packageName, realVersion).wait()) { // In some cases the package is not fully downloaded and there are missing directories // Try removing the old package and add the real one to cache again - this.addCleanCopyToCache(packageName, version).wait(); + cachedPackageData = this.addCleanCopyToCache(packageName, version).wait(); } - }).future()(); + + return cachedPackageData; + }).future()(); } public cacheUnpack(packageName: string, version: string, unpackTarget?: string): IFuture { @@ -125,26 +132,29 @@ export class NpmInstallationManager implements INpmInstallationManager { }).future()(); } - public addCleanCopyToCache(packageName: string, version: string): IFuture { + private addCleanCopyToCache(packageName: string, version: string): IFuture { return (() => { let packagePath = path.join(this.getCacheRootPath(), packageName, version); this.$logger.trace(`Deleting: ${packagePath}.`); this.$fs.deleteDirectory(packagePath).wait(); - this.addToCacheCore(packageName, version).wait(); - if(!this.isShasumOfPackageCorrect(packageName, version).wait()) { - this.$errors.failWithoutHelp(`Unable to add package ${packageName} with version ${version} to npm cache. Try cleaning your cache and execute the command again.`); + let cachedPackageData = this.addToCacheCore(packageName, version).wait(); + if(!this.isShasumOfPackageCorrect(packageName, cachedPackageData.version).wait()) { + this.$errors.failWithoutHelp(`Unable to add package ${packageName} with version ${cachedPackageData.version} to npm cache. Try cleaning your cache and execute the command again.`); } - }).future()(); + + return cachedPackageData; + }).future()(); } - private addToCacheCore(packageName: string, version: string): IFuture { + private addToCacheCore(packageName: string, version: string): IFuture { return (() => { - this.$npm.cache(packageName, version).wait(); - let packagePath = path.join(this.getCacheRootPath(), packageName, version, "package"); + let cachedPackageData = this.$npm.cache(packageName, version).wait(); + let packagePath = path.join(this.getCacheRootPath(), packageName, cachedPackageData.version, "package"); if(!this.isPackageUnpacked(packagePath, packageName).wait()) { - this.cacheUnpack(packageName, version).wait(); + this.cacheUnpack(packageName, cachedPackageData.version).wait(); } - }).future()(); + return cachedPackageData; + }).future()(); } private isShasumOfPackageCorrect(packageName: string, version: string): IFuture { @@ -185,9 +195,9 @@ export class NpmInstallationManager implements INpmInstallationManager { return path.join(pathToNodeModules, folders[0]); } else { version = version || this.getLatestCompatibleVersion(packageName).wait(); - let packagePath = this.getCachedPackagePath(packageName, version); - this.addToCache(packageName, version).wait(); - return packagePath; + let cachedData = this.addToCache(packageName, version).wait(); + let packageVersion = (cachedData && cachedData.version) || version; + return this.getCachedPackagePath(packageName, packageVersion); } }).future()(); } diff --git a/lib/services/platform-service.ts b/lib/services/platform-service.ts index abdbcdafcc..1f89838719 100644 --- a/lib/services/platform-service.ts +++ b/lib/services/platform-service.ts @@ -549,7 +549,8 @@ export class PlatformService implements IPlatformService { let currentVersion = data && data.version ? data.version : "0.2.0"; let newVersion = version || this.$npmInstallationManager.getLatestVersion(platformData.frameworkPackageName).wait(); - this.ensurePackageIsCached(platformData.frameworkPackageName, newVersion).wait(); + let cachedPackageData = this.$npmInstallationManager.addToCache(platformData.frameworkPackageName, newVersion).wait(); + newVersion = (cachedPackageData && cachedPackageData.version) || newVersion; let canUpdate = platformData.platformProjectService.canUpdatePlatform(currentVersion, newVersion).wait(); if(canUpdate) { @@ -638,18 +639,6 @@ export class PlatformService implements IPlatformService { }).future()(); } - private ensurePackageIsCached(packageName: string, version: string): IFuture { - return (() => { - this.$npmInstallationManager.addToCache(packageName, version).wait(); - let cachedPackagePath = this.$npmInstallationManager.getCachedPackagePath(packageName, version); - if(!this.$fs.exists(path.join(cachedPackagePath, constants.PROJECT_FRAMEWORK_FOLDER_NAME)).wait()) { - // In some cases the package is not fully downloaded and the framework directory is missing - // Try removing the old package and add the real one to cache again - this.$npmInstallationManager.addCleanCopyToCache(packageName, version).wait(); - } - }).future()(); - } - private mapFrameworkFiles(npmCacheDirectoryPath: string, files: string[]): string[] { return _.map(files, file => file.substr(npmCacheDirectoryPath.length + constants.PROJECT_FRAMEWORK_FOLDER_NAME.length + 1)); } diff --git a/test/stubs.ts b/test/stubs.ts index d6bcbd1b73..9f221fa06c 100644 --- a/test/stubs.ts +++ b/test/stubs.ts @@ -212,10 +212,6 @@ export class NpmInstallationManagerStub implements INpmInstallationManager { return undefined; } - addCleanCopyToCache(packageName: string, version: string): IFuture { - return undefined; - } - cacheUnpack(packageName: string, version: string): IFuture { return undefined; }