33
44import Future = require( "fibers/future" ) ;
55import npm = require( "npm" ) ;
6- import path = require( "path" ) ;
7- import semver = require( "semver" ) ;
8- import shell = require( "shelljs" ) ;
9- import helpers = require( "./common/helpers" ) ;
10- import constants = require( "./constants" ) ;
116
127export class NodePackageManager implements INodePackageManager {
13- private static NPM_LOAD_FAILED = "Failed to retrieve data from npm. Please try again a little bit later." ;
14- private static NPM_REGISTRY_URL = "http://registry.npmjs.org/" ;
15-
16- private versionsCache : IDictionary < string [ ] > ;
17-
188 constructor ( private $logger : ILogger ,
199 private $errors : IErrors ,
2010 private $fs : IFileSystem ,
2111 private $lockfile : ILockFile ,
22- private $options : IOptions ) {
23- this . versionsCache = { } ;
24- this . load ( ) . wait ( ) ;
25- }
12+ private $options : IOptions ) { }
2613
27- public getCacheRootPath ( ) : string {
14+ public getCache ( ) : string {
2815 return npm . cache ;
2916 }
30-
31- public addToCache ( packageName : string , version : string ) : IFuture < void > {
32- return ( ( ) => {
33- this . addToCacheCore ( packageName , version ) . wait ( ) ;
34-
35- var packagePath = path . join ( npm . cache , packageName , version , "package" ) ;
36- if ( ! this . isPackageUnpacked ( packagePath ) . wait ( ) ) {
37- this . cacheUnpack ( packageName , version ) . wait ( ) ;
38- }
39- } ) . future < void > ( ) ( ) ;
40- }
41-
17+
4218 public load ( config ?: any ) : IFuture < void > {
4319 var future = new Future < void > ( ) ;
4420 npm . load ( config , ( err ) => {
@@ -50,128 +26,51 @@ export class NodePackageManager implements INodePackageManager {
5026 } ) ;
5127 return future ;
5228 }
53-
54- public install ( packageName : string , opts ?: INpmInstallOptions ) : IFuture < string > {
55- return ( ( ) => {
56- this . $lockfile . lock ( ) . wait ( ) ;
57-
58- try {
59- var packageToInstall = packageName ;
60- var pathToSave = ( opts && opts . pathToSave ) || npm . cache ;
61- var version = ( opts && opts . version ) || null ;
62-
63- return this . installCore ( packageToInstall , pathToSave , version ) . wait ( ) ;
64- } catch ( error ) {
65- this . $logger . debug ( error ) ;
66- this . $errors . fail ( "%s. Error: %s" , NodePackageManager . NPM_LOAD_FAILED , error ) ;
67- } finally {
68- this . $lockfile . unlock ( ) . wait ( ) ;
69- }
70-
71- } ) . future < string > ( ) ( ) ;
29+
30+ public install ( packageName : string , pathToSave : string , config ?: any ) : IFuture < any > {
31+ return this . loadAndExecute ( "install" , [ pathToSave , packageName ] , { config : config } ) ;
7232 }
73-
74- public getLatestVersion ( packageName : string ) : IFuture < string > {
75- var future = new Future < string > ( ) ;
76-
77- npm . commands [ "view" ] ( [ packageName , "dist-tags" ] , [ false ] , ( err : any , data : any ) => { // [false] - silent
78- if ( err ) {
79- future . throw ( err ) ;
80- } else {
81- var latestVersion = _ . first ( _ . keys ( data ) ) ;
82- this . $logger . trace ( "Using version %s. " , latestVersion ) ;
83-
84- future . return ( latestVersion ) ;
85- }
86- } ) ;
87-
88- return future ;
33+
34+ public uninstall ( packageName : string , config ?: any ) : IFuture < any > {
35+ return this . loadAndExecute ( "uninstall" , [ [ packageName ] ] , { config : config } ) ;
8936 }
9037
91- public getCachedPackagePath ( packageName : string , version : string ) : string {
92- return path . join ( npm . cache , packageName , version , "package" ) ;
38+ public cache ( packageName : string , version : string , config ?: any ) : IFuture < ICacheData > {
39+ // function cache (pkg, ver, where, scrub, cb)
40+ return this . loadAndExecute ( "cache" , [ packageName , version , undefined , false ] , { subCommandName : "add" , config : config } ) ;
9341 }
94-
95- private installCore ( packageName : string , pathToSave : string , version : string ) : IFuture < string > {
96- return ( ( ) => {
97- if ( this . $options . frameworkPath ) {
98- if ( this . $fs . getFsStats ( this . $options . frameworkPath ) . wait ( ) . isFile ( ) ) {
99- this . npmInstall ( packageName , pathToSave , version ) . wait ( ) ;
100- var pathToNodeModules = path . join ( pathToSave , "node_modules" ) ;
101- var folders = this . $fs . readDirectory ( pathToNodeModules ) . wait ( ) ;
102- return path . join ( pathToNodeModules , folders [ 0 ] ) ;
103- }
104- return this . $options . frameworkPath ;
105- } else {
106- version = version || this . getLatestVersion ( packageName ) . wait ( ) ;
107- var packagePath = this . getCachedPackagePath ( packageName , version ) ;
108- if ( ! this . isPackageCached ( packagePath ) . wait ( ) ) {
109- this . addToCacheCore ( packageName , version ) . wait ( ) ;
110- }
111-
112- if ( ! this . isPackageUnpacked ( packagePath ) . wait ( ) ) {
113- this . cacheUnpack ( packageName , version ) . wait ( ) ;
114- }
115- return packagePath ;
116- }
117- } ) . future < string > ( ) ( ) ;
118- }
119-
120- private npmInstall ( packageName : string , pathToSave : string , version : string ) : IFuture < void > {
121- this . $logger . out ( "Installing " , packageName ) ;
122-
123- var incrementedVersion = semver . inc ( version , constants . ReleaseType . MINOR ) ;
124- if ( ! this . $options . frameworkPath && packageName . indexOf ( "@" ) < 0 ) {
125- packageName = packageName + "@<" + incrementedVersion ;
126- }
127-
128- var future = new Future < void > ( ) ;
129- npm . commands [ "install" ] ( pathToSave , packageName , ( err : Error , data : any ) => {
130- if ( err ) {
131- future . throw ( err ) ;
132- } else {
133- this . $logger . out ( "Installed " , packageName ) ;
134- future . return ( data ) ;
135- }
136- } ) ;
137- return future ;
42+
43+ public cacheUnpack ( packageName : string , version : string , unpackTarget ?: string ) : IFuture < void > {
44+ // function unpack (pkg, ver, unpackTarget, dMode, fMode, uid, gid, cb)
45+ return this . loadAndExecute ( "cache" , [ packageName , version , unpackTarget , null , null , null , null ] , { subCommandName : "unpack" } ) ;
13846 }
139-
140- private isPackageCached ( packagePath : string ) : IFuture < boolean > {
141- return this . $fs . exists ( packagePath ) ;
47+
48+ public view ( packageName : string , propertyName : string ) : IFuture < any > {
49+ return this . loadAndExecute ( "view" , [ [ packageName , propertyName ] , [ false ] ] ) ;
14250 }
143-
144- private isPackageUnpacked ( packagePath : string ) : IFuture < boolean > {
51+
52+ private loadAndExecute ( commandName : string , args : any [ ] , opts ?: { config ?: any , subCommandName ?: string } ) : IFuture < any > {
14553 return ( ( ) => {
146- return this . $fs . getFsStats ( packagePath ) . wait ( ) . isDirectory ( ) &&
147- this . $fs . enumerateFilesInDirectorySync ( packagePath ) . length > 1 ;
148- } ) . future < boolean > ( ) ( ) ;
149- }
150-
151- private addToCacheCore ( packageName : string , version : string ) : IFuture < void > {
152- var future = new Future < void > ( ) ;
153- // cache.add = function (pkg, ver, where, scrub, cb)
154- npm . commands [ "cache" ] . add ( packageName , version , undefined , false , ( err : Error , data : any ) => {
155- if ( err ) {
156- future . throw ( err ) ;
157- } else {
158- future . return ( ) ;
159- }
160- } ) ;
161- return future ;
54+ opts = opts || { } ;
55+ this . load ( opts . config ) . wait ( ) ;
56+ return this . executeCore ( commandName , args , opts . subCommandName ) . wait ( ) ;
57+ } ) . future < any > ( ) ( ) ;
16258 }
163-
164- public cacheUnpack ( packageName : string , version : string , unpackTarget ?: string ) : IFuture < void > {
165- var future = new Future < void > ( ) ;
166- unpackTarget = unpackTarget || path . join ( npm . cache , packageName , version , "package" ) ;
167- // function unpack (pkg, ver, unpackTarget, dMode, fMode, uid, gid, cb)
168- npm . commands [ "cache" ] . unpack ( packageName , version , unpackTarget , null , null , null , null , ( err : Error , data : any ) => {
59+
60+ private executeCore ( commandName : string , args : any [ ] , subCommandName ?: string ) : IFuture < any > {
61+ let future = new Future < any > ( ) ;
62+ let callback = ( err : Error , data : any ) => {
16963 if ( err ) {
17064 future . throw ( err ) ;
17165 } else {
172- future . return ( ) ;
66+ future . return ( data ) ;
17367 }
174- } ) ;
68+ }
69+ args . push ( callback ) ;
70+
71+ let command = subCommandName ? npm . commands [ commandName ] [ subCommandName ] : npm . commands [ commandName ] ;
72+ command . apply ( this , args ) ;
73+
17574 return future ;
17675 }
17776}
0 commit comments