From ef1048b91ffdb08e2ce0bc17e8563bb8fcd514b1 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Fri, 25 Sep 2015 13:17:18 +0300 Subject: [PATCH] Add checks for all cached packages NPM Cache gets broken in some cases. Make sure to validate the sahsum of the cached package. Also validate specific directories in our `tns` related packages from npm, for example tns runtimes must have "framework" directory in the root of the unpacked dir. Fixes https://github.com/NativeScript/NativeScript/issues/763 --- lib/npm-installation-manager.ts | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/lib/npm-installation-manager.ts b/lib/npm-installation-manager.ts index e050a62091..45f19c0c4d 100644 --- a/lib/npm-installation-manager.ts +++ b/lib/npm-installation-manager.ts @@ -9,6 +9,11 @@ import * as constants from "./constants"; export class NpmInstallationManager implements INpmInstallationManager { private static NPM_LOAD_FAILED = "Failed to retrieve data from npm. Please try again a little bit later."; private versionsCache: IDictionary; + private packageSpecificDirectories: IStringDictionary = { + "tns-android": constants.PROJECT_FRAMEWORK_FOLDER_NAME, + "tns-ios": constants.PROJECT_FRAMEWORK_FOLDER_NAME, + "tns-template-hello-world": constants.APP_RESOURCES_FOLDER_NAME + }; constructor(private $npm: INodePackageManager, private $logger: ILogger, @@ -36,7 +41,7 @@ export class NpmInstallationManager implements INpmInstallationManager { } if(!this.isShasumOfPackageCorrect(packageName, version).wait()) { - // In some cases the package is not fully downloaded and the framework directory is missing + // 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(); } @@ -94,7 +99,7 @@ export class NpmInstallationManager implements INpmInstallationManager { return (() => { this.$npm.cache(packageName, version).wait(); let packagePath = path.join(this.getCacheRootPath(), packageName, version, "package"); - if(!this.isPackageUnpacked(packagePath).wait()) { + if(!this.isPackageUnpacked(packagePath, packageName).wait()) { this.cacheUnpack(packageName, version).wait(); } }).future()(); @@ -128,13 +133,7 @@ export class NpmInstallationManager implements INpmInstallationManager { } else { version = version || this.getLatestVersion(packageName).wait(); let packagePath = this.getCachedPackagePath(packageName, version); - if (!this.isPackageCached(packagePath).wait()) { - this.$npm.cache(packageName, version).wait(); - } - - if(!this.isPackageUnpacked(packagePath).wait()) { - this.cacheUnpack(packageName, version).wait(); - } + this.addToCache(packageName, version).wait(); return packagePath; } }).future()(); @@ -151,15 +150,17 @@ export class NpmInstallationManager implements INpmInstallationManager { return this.$npm.install(packageName, pathToSave); } - private isPackageCached(packagePath: string): IFuture { - return this.$fs.exists(packagePath); - } - - private isPackageUnpacked(packagePath: string): IFuture { + private isPackageUnpacked(packagePath: string, packageName: string): IFuture { return (() => { + let additionalDirectoryToCheck = this.packageSpecificDirectories[packageName]; return this.$fs.getFsStats(packagePath).wait().isDirectory() && - this.$fs.exists(path.join(packagePath, "framework")).wait() && - this.$fs.enumerateFilesInDirectorySync(path.join(packagePath, "framework")).length > 1; + (!additionalDirectoryToCheck || this.hasFilesInDirectory(path.join(packagePath, additionalDirectoryToCheck)).wait()); + }).future()(); + } + + private hasFilesInDirectory(directory: string): IFuture { + return ((): boolean => { + return this.$fs.exists(directory).wait() && this.$fs.enumerateFilesInDirectorySync(directory).length > 0; }).future()(); } }