@@ -6,7 +6,7 @@ import semver = require("semver");
6
6
import npm = require( "npm" ) ;
7
7
import constants = require( "./constants" ) ;
8
8
9
- export class NpmInstallationManager {
9
+ export class NpmInstallationManager implements INpmInstallationManager {
10
10
private static NPM_LOAD_FAILED = "Failed to retrieve data from npm. Please try again a little bit later." ;
11
11
private versionsCache : IDictionary < string [ ] > ;
12
12
@@ -27,13 +27,18 @@ export class NpmInstallationManager {
27
27
public getCachedPackagePath ( packageName : string , version : string ) : string {
28
28
return path . join ( this . getCacheRootPath ( ) , packageName , version , "package" ) ;
29
29
}
30
-
30
+
31
31
public addToCache ( packageName : string , version : string ) : IFuture < void > {
32
32
return ( ( ) => {
33
- this . $npm . cache ( packageName , version ) . wait ( ) ;
34
- let packagePath = path . join ( this . getCacheRootPath ( ) , packageName , version , "package" ) ;
35
- if ( ! this . isPackageUnpacked ( packagePath ) . wait ( ) ) {
36
- this . cacheUnpack ( packageName , version ) . wait ( ) ;
33
+ let cachedPackagePath = this . getCachedPackagePath ( packageName , version ) ;
34
+ if ( ! this . $fs . exists ( cachedPackagePath ) . wait ( ) ) {
35
+ this . addToCacheCore ( packageName , version ) . wait ( ) ;
36
+ }
37
+
38
+ if ( ! this . isShasumOfPackageCorrect ( packageName , version ) . wait ( ) ) {
39
+ // In some cases the package is not fully downloaded and the framework directory is missing
40
+ // Try removing the old package and add the real one to cache again
41
+ this . addCleanCopyToCache ( packageName , version ) . wait ( ) ;
37
42
}
38
43
} ) . future < void > ( ) ( ) ;
39
44
}
@@ -73,6 +78,43 @@ export class NpmInstallationManager {
73
78
} ) . future < string > ( ) ( ) ;
74
79
}
75
80
81
+ public addCleanCopyToCache ( packageName : string , version : string ) : IFuture < void > {
82
+ return ( ( ) => {
83
+ let packagePath = path . join ( this . getCacheRootPath ( ) , packageName , version ) ;
84
+ this . $logger . trace ( `Deleting: ${ packagePath } .` ) ;
85
+ this . $fs . deleteDirectory ( packagePath ) . wait ( ) ;
86
+ this . addToCacheCore ( packageName , version ) . wait ( ) ;
87
+ if ( ! this . isShasumOfPackageCorrect ( packageName , version ) . wait ( ) ) {
88
+ this . $errors . failWithoutHelp ( `Unable to add package ${ packageName } with version ${ version } to npm cache. Try cleaning your cache and execute the command again.` )
89
+ }
90
+ } ) . future < void > ( ) ( ) ;
91
+ }
92
+
93
+ private addToCacheCore ( packageName : string , version : string ) : IFuture < void > {
94
+ return ( ( ) => {
95
+ this . $npm . cache ( packageName , version ) . wait ( ) ;
96
+ let packagePath = path . join ( this . getCacheRootPath ( ) , packageName , version , "package" ) ;
97
+ if ( ! this . isPackageUnpacked ( packagePath ) . wait ( ) ) {
98
+ this . cacheUnpack ( packageName , version ) . wait ( ) ;
99
+ }
100
+ } ) . future < void > ( ) ( ) ;
101
+ }
102
+
103
+ private isShasumOfPackageCorrect ( packageName : string , version : string ) : IFuture < boolean > {
104
+ return ( ( ) : boolean => {
105
+ let shasumProperty = "dist.shasum" ;
106
+ let cachedPackagePath = this . getCachedPackagePath ( packageName , version ) ;
107
+ let realShasum = this . $npm . view ( `${ packageName } @${ version } ` , shasumProperty ) . wait ( ) [ version ] [ shasumProperty ] ;
108
+ let packageTgz = cachedPackagePath + ".tgz" ;
109
+ let currentShasum = "" ;
110
+ if ( this . $fs . exists ( packageTgz ) . wait ( ) ) {
111
+ currentShasum = this . $fs . getFileShasum ( packageTgz ) . wait ( ) ;
112
+ }
113
+ this . $logger . trace ( `Checking shasum of package: ${ packageName } @${ version } : expected ${ realShasum } , actual ${ currentShasum } .` ) ;
114
+ return realShasum === currentShasum ;
115
+ } ) . future < boolean > ( ) ( ) ;
116
+ }
117
+
76
118
private installCore ( packageName : string , pathToSave : string , version : string ) : IFuture < string > {
77
119
return ( ( ) => {
78
120
if ( this . $options . frameworkPath ) {
0 commit comments