11var os = require ( "os" ) ;
2- var fs = require ( "fs" ) ;
32var path = require ( "path" ) ;
43var zlib = require ( "zlib" ) ;
5- var exec = require ( "child_process" ) . exec ;
6- var Q = require ( "q" ) ;
7- var request = require ( "request" ) ;
84var tar = require ( "tar" ) ;
9- var which = require ( "which" ) ;
10- var rimraf = require ( "rimraf" ) ;
5+
6+ var Promise = require ( "nodegit-promise" ) ;
7+ var promisify = require ( "promisify-node" ) ;
8+ var request = require ( "request" ) ;
9+ var fse = promisify ( require ( "fs-extra" ) ) ;
10+ fse . ensureDir = promisify ( fse . ensureDir ) ;
11+
12+ var exec = promisify ( function ( command , opts , callback ) {
13+ return require ( "child_process" ) . exec ( command , opts , callback ) ;
14+ } ) ;
15+
1116var NODE_VERSION = Number ( process . version . match ( / ^ v ( \d + \. \d + ) / ) [ 1 ] ) ;
1217
1318// If the build only flag is set.
@@ -41,7 +46,7 @@ function systemPath(parts) {
4146}
4247
4348// Will be used near the end to configure `node-gyp`.
44- var python ;
49+ var pythonPath = '/usr/bin/ python' ;
4550
4651var local = path . join . bind ( path , __dirname ) ;
4752
@@ -66,197 +71,129 @@ if (NODE_VERSION === 0.1) {
6671 pkg . http_parser = pkg . http_parser [ "0.10" ] ;
6772}
6873
69- // Attempt to fallback on a prebuilt binary.
70- function fetchPrebuilt ( ) {
74+ fse . ensureDir ( path . resolve ( __dirname , paths . release ) )
75+ . then ( fetch )
76+ . then ( finish , compile )
77+ . done ( )
78+
79+ function fetch ( ) {
7180 if ( ! buildOnly ) {
7281 console . info ( "[nodegit] Fetching binary from S3." ) ;
7382
7483 // Using the node-pre-gyp module, attempt to fetch a compatible build.
75- return Q . nfcall ( exec , "node-pre-gyp install" ) ;
84+ return exec ( "node-pre-gyp install" ) ;
7685 }
7786
78- throw new Error ( "Build only " ) ;
87+ throw new Error ( "BUILD_ONLY is set to true, no fetching allowed. " ) ;
7988}
8089
81- // Attempt to fetch prebuilt binary.
82- Q . ninvoke ( fs , "mkdir" , paths . release ) . then ( fetchPrebuilt , fetchPrebuilt )
83-
84- . fail ( function ( ) {
90+ function compile ( ) {
8591 if ( ! buildOnly ) {
8692 console . info ( "[nodegit] Failed to install prebuilt, attempting compile." ) ;
8793 }
8894
89- // Ensure all dependencies are available.
90- return Q . allSettled ( [
91- // This will prioritize `python2` over `python`, because we always want to
92- // work with Python 2.* if it"s available.
93- Q . nfcall ( which , "python2" ) ,
94- Q . nfcall ( which , "python" )
95- ] )
96- } )
97-
98- // Determine if all the dependency requirements are met.
99- . then ( function ( results ) {
10095 console . info ( "[nodegit] Determining dependencies." ) ;
10196
102- // Assign to reusable variables.
103- python = results [ 0 ] . value || results [ 1 ] . value ;
104-
105- // Missing Python.
106- if ( ! python ) {
107- throw new Error ( "Python is required to build libgit2." ) ;
108- }
109-
110- // Now lets check the Python version to ensure it"s < 3.
111- return Q . nfcall ( exec , python + " --version" ) . then ( function ( version ) {
112- if ( version [ 1 ] . indexOf ( "Python 3" ) === 0 ) {
113- throw new Error ( "Incorrect version of Python, gyp requires < 3." ) ;
114- }
115- } ) ;
116- } )
117-
118- // Successfully found all dependencies. First step is to detect the vendor
119- // directory.
120- . then ( function ( ) {
121- console . info ( "[nodegit] Detecting vendor/libgit2." ) ;
122-
123- return Q . ninvoke ( fs , "stat" , paths . libgit2 ) . then ( function ( ) {
124- return Q . ninvoke ( fs , "stat" , paths . libgit2 + pkg . libgit2 . sha ) ;
125- } ) . fail ( function ( ) {
126- console . info ( "[nodegit] Removing outdated vendor/libgit2." ) ;
127-
128- // This directory is outdated, remove.
129- throw Q . ninvoke ( rimraf , null , paths . libgit2 ) ;
130- } ) ;
131- } )
132-
133- // If the directory already exists, no need to refetch.
134- . fail ( function ( ) {
135- // Otherwise fetch the libgit2 source from GitHub.
136- console . info ( "[nodegit] Fetching vendor/libgit2." ) ;
137-
138- var url = "https://github.com/libgit2/libgit2/tarball/" + pkg . libgit2 . sha ;
139-
140- var extract = tar . Extract ( {
141- path : paths . libgit2 ,
142- strip : true
143- } ) ;
144-
145- // First extract from Zlib and then extract from Tar.
146- var expand = request . get ( url ) . pipe ( zlib . createUnzip ( ) ) . pipe ( extract ) ;
147-
148- return Q . ninvoke ( expand , "on" , "end" ) . then ( function ( ) {
149- // Write out a sha file for testing in the future.
150- return Q . ninvoke ( fs , "writeFile" , paths . libgit2 + pkg . libgit2 . sha , "" ) ;
151- } ) ;
152- } )
153-
154- // Grab libssh2 if needed.
155- . then ( function ( ) {
156- console . info ( "[nodegit] Detecting vendor/libssh2." ) ;
157-
158- return Q . ninvoke ( fs , "stat" , paths . libssh2 ) . then ( function ( ) {
159- return Q . ninvoke ( fs , "stat" , paths . libssh2 + pkg . libssh2 . version ) ;
160- } ) . fail ( function ( ) {
161- console . info ( "[nodegit] Removing outdated vendor/libssh2." ) ;
162-
163- // This directory is outdated, remove.
164- throw Q . ninvoke ( rimraf , null , paths . libssh2 ) ;
165- } ) ;
166- } )
167-
168- // If the directory already exists, no need to refetch.
169- . fail ( function ( ) {
170- // Otherwise fetch the libssh2 source.
171- console . info ( "[nodegit] Fetching vendor/libssh2." ) ;
97+ return python ( )
98+ . then ( getVendorLib ( "libgit2" , "https://github.com/libgit2/libgit2/tarball/" + pkg . libgit2 . sha ) )
99+ . then ( getVendorLib ( "libssh2" , pkg . libssh2 . url ) )
100+ . then ( getVendorLib ( "http_parser" , pkg . http_parser . url ) )
101+ . then ( buildNative )
102+ . then ( finish , fail ) ;
172103
173- var url = pkg . libssh2 . url ;
174-
175- var extract = tar . Extract ( {
176- path : paths . libssh2 ,
177- strip : true
178- } ) ;
104+ }
179105
180- // First extract from Zlib and then extract from Tar.
181- var expand = request . get ( url ) . pipe ( zlib . createUnzip ( ) ) . pipe ( extract ) ;
106+ function python ( ) {
107+ return exec ( "which python2" )
108+ . then ( function ( which ) {
109+ return which ;
110+ } , function ( err ) {
111+ return null ;
112+ } )
113+ . then ( function ( path ) {
114+ return path || exec ( "which python" ) ;
115+ } )
116+ . then ( function ( which ) {
117+ return which ;
118+ } , function ( err ) {
119+ return null ;
120+ } )
121+ . then ( function ( path ) {
122+ pythonPath = path . trim ( ) ;
123+ if ( ! pythonPath ) {
124+ throw new Error ( "Python is required to build libgit2." ) ;
125+ }
126+ } )
127+ . then ( function ( ) {
128+ return exec ( pythonPath + " -V 2>&1" ) ;
129+ } )
130+ . then ( function ( version ) {
131+ if ( version [ 1 ] . indexOf ( "Python 3" ) === 0 ) {
132+ throw new Error ( "Incorrect version of Python, gyp requires < 3." ) ;
133+ }
134+ } ) ;
135+ }
182136
183- return Q . ninvoke ( expand , "on" , "end" ) . then ( function ( ) {
184- // Write out a sha file for testing in the future.
185- return Q . ninvoke ( fs , "writeFile" , paths . libssh2 + pkg . libssh2 . version , "" ) ;
186- } ) . then ( function ( ) {
187- // Only run the configuration script in a BSD-like environment.
188- if ( process . platform !== "win32" ) {
189- return Q . nfcall ( exec , "cd " + paths . libssh2 + " ; " + paths . libssh2 +
190- "configure" ) ;
137+ function getVendorLib ( name , url ) {
138+ return function ( ) {
139+ var version = pkg [ name ] . sha || pkg [ name ] . version ;
140+ console . info ( "[nodegit] Detecting vendor/" + name + "." ) ;
141+ if ( fse . existsSync ( paths [ name ] + version ) ) {
142+ console . info ( "[nodegit] vendor/" + name + " already exists." ) ;
143+ return new Promise ( function ( resolve , reject ) { resolve ( ) } ) ;
191144 }
192- } ) ;
193- } )
194-
195- // Grab http-parser if needed.
196- . then ( function ( ) {
197- console . info ( "[nodegit] Detecting vendor/http_parser." ) ;
198-
199- return Q . ninvoke ( fs , "stat" , paths . http_parser ) . then ( function ( ) {
200- return Q . ninvoke ( fs , "stat" , paths . http_parser + pkg . http_parser . version ) ;
201- } ) . fail ( function ( ) {
202- console . info ( "[nodegit] Removing outdated vendor/http_parser." ) ;
203-
204- // This directory is outdated, remove.
205- throw Q . ninvoke ( rimraf , null , paths . http_parser ) ;
206- } ) ;
207- } )
208-
209- // If the directory already exists, no need to refetch.
210- . fail ( function ( ) {
211- // Otherwise fetch the http_parser source.
212- console . info ( "[nodegit] Fetching vendor/http_parser." ) ;
213-
214- var url = pkg . http_parser . url ;
215-
216- var extract = tar . Extract ( {
217- path : paths . http_parser ,
218- strip : true
219- } ) ;
220-
221- // First extract from Zlib and then extract from Tar.
222- var expand = request . get ( url ) . pipe ( zlib . createUnzip ( ) ) . pipe ( extract ) ;
223-
224- return Q . ninvoke ( expand , "on" , "end" ) . then ( function ( ) {
225- // Write out a sha file for testing in the future.
226- return Q . ninvoke ( fs , "writeFile" , paths . http_parser +
227- pkg . http_parser . version , "" ) ;
228- } ) ;
229- } )
230-
231-
232- // Build the native module using node-gyp.
233- . then ( function ( ) {
234- console . info ( "[nodegit] Building native node module." ) ;
235- var pythonFlag = " --python \"" + python + "\"" ;
236-
237- return Q . nfcall ( exec , systemPath ( [
238- "." , "node_modules" , ".bin" , "node-gyp clean configure build" + pythonFlag
239- ] ) , {
240- cwd : "." ,
241- maxBuffer : Number . MAX_VALUE
242- } ) ;
243- } )
145+ else {
146+ console . info ( "[nodegit] Removing outdated vendor/" + name + "." ) ;
147+ return fse . remove ( paths [ name ] )
148+ . then ( function ( ) {
149+ return new Promise ( function ( resolve , reject ) {
150+
151+ console . info ( "[nodegit] Fetching vendor/" + name + "." ) ;
152+
153+ var extract = tar . Extract ( {
154+ path : paths [ name ] ,
155+ strip : true
156+ } ) ;
157+
158+ request . get ( url ) . pipe ( zlib . createUnzip ( ) ) . pipe ( extract )
159+ . on ( "error" , reject )
160+ . on ( "end" , resolve ) ;
161+ } ) ;
162+ } ) . then ( function ( ) {
163+ return fse . writeFile ( paths [ name ] + version , "" ) ;
164+ } ) . then ( function ( ) {
165+ if ( ( name == "libssh2" ) && ( process . platform !== "win32" ) ) {
166+
167+ return exec ( paths [ name ] + "configure" , { cwd : paths [ name ] } ) ;
168+ }
169+ } ) ;
170+ }
171+ }
172+ }
244173
245- // Display a warning message about failing to build native node module.
246- . fail ( function ( message ) {
247- console . info ( "[nodegit] Failed to build and install nodegit." ) ;
248- console . info ( message . message ) ;
249- console . info ( message . stack ) ;
250- } )
174+ function buildNative ( ) {
175+ return exec ( "cd " + __dirname ) . then ( function ( ) {
176+ console . info ( "[nodegit] Building native node module." ) ;
177+ var pythonFlag = " --python \"" + pythonPath + "\"" ;
178+ var cmd = path . resolve ( systemPath ( [
179+ "." , "node_modules" , ".bin" , "node-gyp clean configure build" + pythonFlag
180+ ] ) ) ;
181+ var opts = {
182+ cwd : __dirname ,
183+ maxBuffer : Number . MAX_VALUE
184+ } ;
185+ return exec ( cmd , opts ) ;
186+ } )
187+ }
251188
252- // Display a success message.
253- . then ( function ( ) {
189+ function finish ( ) {
254190 console . info ( "[nodegit] Completed installation successfully." ) ;
255- } )
191+ return Promise . resolve ( ) . done ( ) ;
192+ }
256193
257- // Display a warning message about failing to build native node module.
258- . fail ( function ( message ) {
259- console . info ( "[nodegit] Failed to build nodegit." ) ;
194+ function fail ( message ) {
195+ console . info ( "[nodegit] Failed to build and install nodegit." ) ;
260196 console . info ( message . message ) ;
261- console . info ( message . stack ) ;
262- } ) ;
197+ //console.info(message.stack);
198+ return Promise . resolve ( ) . done ( ) ;
199+ }
0 commit comments