11#!/usr/bin/env node
22const fs = require ( "fs" ) ;
3+ const https = require ( "https" ) ;
34const path = require ( "path" ) ;
45const execSync = require ( "child_process" ) . execSync ;
5- const fetch = require ( "node-fetch" ) ;
6- const Spinner = require ( "cli-spinner" ) . Spinner ;
7- const inquirer = require ( ' inquirer' ) ;
8- const findProcess = require ( ' find-process' ) ;
6+
7+ const getSpinner = ( ) => require ( "cli-spinner" ) . Spinner ;
8+ const getInquirer = ( ) => require ( " inquirer" ) ;
9+ const getFindProcess = ( ) => require ( " find-process" ) ;
910
1011const downloadPathTemplate =
1112 "https://github.com/devspace-sh/devspace/releases/download/v{{version}}/devspace-{{platform}}-{{arch}}" ;
@@ -80,43 +81,91 @@ const sanitizeVersion = function(version) {
8081
8182const getLatestVersion = function ( callback ) {
8283 const releasesURL = "https://github.com/devspace-sh/devspace/releases/latest" ;
84+ https . get ( releasesURL , { headers : requestHeaders } , function ( res ) {
85+ const redirectUrl = res . headers . location ;
86+ const matches = redirectUrl && / \/ t a g \/ ( .* ) $ / . exec ( redirectUrl ) ;
8387
84- fetch ( releasesURL , { headers : requestHeaders , redirect : false } )
85- . then ( function ( res ) {
86- if ( ! res . ok ) {
87- console . error (
88- "Error requesting URL " +
89- releasesURL +
90- " (Status Code: " +
91- res . status +
92- ")"
93- ) ;
94- process . exit ( 1 ) ;
95- }
88+ if ( ! matches || matches . length !== 2 ) {
89+ console . error ( "Error requesting URL " + releasesURL ) ;
90+ process . exit ( 1 ) ;
91+ }
9692
97- const redirectUrl = res . url
98- if ( redirectUrl == null ) {
99- throw new Error ( 'Error fetching latest version' )
100- }
93+ const latestVersion = matches [ 1 ] . replace ( 'v' , '' )
94+ if ( latestVersion ) {
95+ callback ( latestVersion ) ;
96+ } else {
97+ console . error ( "Unable to identify latest devspace version" ) ;
98+ process . exit ( 2 ) ;
99+ }
100+ } ) . on ( "error" , function ( err ) {
101+ console . error ( "Error requesting URL " + releasesURL ) ;
102+ console . error ( err )
103+ process . exit ( 1 ) ;
104+ } )
105+ } ;
101106
102- const matches = / \/ t a g \/ ( .* ) $ / . exec ( redirectUrl )
103- if ( ! matches || matches . length !== 2 ) {
104- throw new Error ( 'Error fetching latest version' )
105- }
107+ const createSpinner = function ( text ) {
108+ try {
109+ const Spinner = getSpinner ( ) ;
110+ const spinner = new Spinner ( "%s " + text ) ;
111+ spinner . setSpinnerString ( "|/-\\" ) ;
112+ return spinner ;
113+ } catch ( err ) {
114+ return {
115+ start : function ( ) {
116+ console . log ( text ) ;
117+ } ,
118+ stop : function ( ) { }
119+ } ;
120+ }
121+ } ;
106122
107- const latestVersion = matches [ 1 ] . replace ( 'v' , '' )
108- if ( latestVersion ) {
109- callback ( latestVersion ) ;
110- } else {
111- console . error ( "Unable to identify latest devspace version" ) ;
112- process . exit ( 2 ) ;
113- }
114- } )
115- . catch ( function ( err ) {
116- console . error ( "Error requesting URL " + releasesURL ) ;
117- console . error ( err )
118- process . exit ( 1 ) ;
119- } )
123+ const downloadFile = function ( downloadPath , destination , callback ) {
124+ let done = false ;
125+ const finish = function ( err , res ) {
126+ if ( done ) {
127+ return ;
128+ }
129+
130+ done = true ;
131+ callback ( err , res ) ;
132+ } ;
133+
134+ https . get ( downloadPath , { headers : requestHeaders } , function ( res ) {
135+ if (
136+ res . statusCode &&
137+ res . statusCode >= 300 &&
138+ res . statusCode < 400 &&
139+ res . headers . location
140+ ) {
141+ res . resume ( ) ;
142+ downloadFile ( res . headers . location , destination , callback ) ;
143+ return ;
144+ }
145+
146+ if ( res . statusCode !== 200 ) {
147+ finish ( null , res ) ;
148+ return ;
149+ }
150+
151+ const writeStream = fs . createWriteStream ( destination )
152+ . on ( "error" , function ( err ) {
153+ finish ( err ) ;
154+ } )
155+ . on ( "finish" , function ( ) {
156+ writeStream . close ( function ( ) {
157+ finish ( null , res ) ;
158+ } ) ;
159+ } ) ;
160+
161+ res . on ( "error" , function ( err ) {
162+ finish ( err ) ;
163+ } ) ;
164+
165+ res . pipe ( writeStream ) ;
166+ } ) . on ( "error" , function ( err ) {
167+ finish ( err ) ;
168+ } ) ;
120169} ;
121170
122171if ( action === "update-version" ) {
@@ -311,6 +360,7 @@ let continueProcess = function (askRemoveGlobalFolder) {
311360 removeScripts ( true ) ;
312361
313362 if ( askRemoveGlobalFolder && process . stdout . isTTY ) {
363+ const inquirer = getInquirer ( ) ;
314364 let removeGlobalFolder = function ( ) {
315365 try {
316366 let homedir = require ( 'os' ) . homedir ( ) ;
@@ -377,33 +427,34 @@ let continueProcess = function (askRemoveGlobalFolder) {
377427
378428 console . log ( "Download DevSpace CLI release: " + downloadPath + "\n" ) ;
379429
380- const spinner = new Spinner (
381- "%s Downloading DevSpace CLI... (this may take a minute)"
430+ const spinner = createSpinner (
431+ "Downloading DevSpace CLI... (this may take a minute)"
382432 ) ;
383- spinner . setSpinnerString ( "|/-\\" ) ;
384433 spinner . start ( ) ;
385434
386- let writeStream = fs
387- . createWriteStream ( binaryPath + downloadExtension )
388- . on ( "error" , function ( err ) {
389- spinner . stop ( true ) ;
390- console . error ( "Unable to write stream: " + err )
391- showRootError ( version ) ;
392- } ) ;
435+ downloadFile (
436+ downloadPath ,
437+ binaryPath + downloadExtension ,
438+ function ( err , res ) {
439+ if ( err ) {
440+ spinner . stop ( true ) ;
393441
394- fetch ( downloadPath , { headers : requestHeaders , encoding : null } )
395- . catch ( function ( err ) {
396- writeStream . end ( ) ;
397- spinner . stop ( true ) ;
398- console . error ( "Error requesting URL: " + downloadPath ) ;
399- process . exit ( 6 ) ;
400- } )
401- . then ( function ( res ) {
402- if ( ! res . ok ) {
403- writeStream . end ( ) ;
442+ if ( err . code === "EACCES" || err . code === "EPERM" ) {
443+ console . error ( "Unable to write stream: " + err )
444+ showRootError ( version ) ;
445+ return ;
446+ }
447+
448+ console . error ( "Error requesting URL: " + downloadPath ) ;
449+ console . error ( err ) ;
450+ process . exit ( 6 ) ;
451+ }
452+
453+ if ( ! res || res . statusCode !== 200 ) {
404454 spinner . stop ( true ) ;
405455
406- if ( res . status === 404 ) {
456+ if ( res && res . statusCode === 404 ) {
457+ res . resume ( ) ;
407458 console . error ( "Release version " + version + " not found.\n" ) ;
408459
409460 getLatestVersion ( function ( latestVersion ) {
@@ -418,46 +469,44 @@ let continueProcess = function (askRemoveGlobalFolder) {
418469 }
419470 } ) ;
420471 } else {
472+ if ( res ) {
473+ res . resume ( ) ;
474+ }
475+
421476 console . error (
422477 "Error requesting URL " +
423478 downloadPath +
424479 " (Status Code: " +
425- res . status +
480+ ( res && res . statusCode ) +
426481 ")"
427482 ) ;
428- console . error ( res . statusText ) ;
483+ console . error ( res && res . statusMessage ) ;
429484 process . exit ( 7 ) ;
430485 }
431- } else {
432- try {
433- res . body . pipe ( writeStream )
434- . on ( "close" , function ( ) {
435- writeStream . end ( ) ;
436- spinner . stop ( true ) ;
437-
438- try {
439- fs . chmodSync ( binaryPath + downloadExtension , "0755" ) ;
440- } catch ( e ) {
441- console . error ( "Unable to chmod: " + e )
442- showRootError ( version ) ;
443- }
444-
445- try {
446- fs . renameSync ( binaryPath + downloadExtension , binaryPath ) ;
447- } catch ( e ) {
448- console . log ( e ) ;
449- console . error ( "\nRenaming release binary failed. Please copy file manually:\n from: " + binaryPath + downloadExtension + "\n to: " + binaryPath + "\n" ) ;
450- process . exit ( 8 ) ;
451- }
452-
453- removeScripts ( true ) ;
454- } ) ;
455- } catch ( e ) {
456- console . error ( "Unable to write stream: " + e )
457- showRootError ( version ) ;
458- }
486+
487+ return ;
459488 }
460- } ) ;
489+
490+ spinner . stop ( true ) ;
491+
492+ try {
493+ fs . chmodSync ( binaryPath + downloadExtension , "0755" ) ;
494+ } catch ( e ) {
495+ console . error ( "Unable to chmod: " + e )
496+ showRootError ( version ) ;
497+ }
498+
499+ try {
500+ fs . renameSync ( binaryPath + downloadExtension , binaryPath ) ;
501+ } catch ( e ) {
502+ console . log ( e ) ;
503+ console . error ( "\nRenaming release binary failed. Please copy file manually:\n from: " + binaryPath + downloadExtension + "\n to: " + binaryPath + "\n" ) ;
504+ process . exit ( 8 ) ;
505+ }
506+
507+ removeScripts ( true ) ;
508+ }
509+ ) ;
461510 } ;
462511
463512 downloadRelease ( version ) ;
@@ -466,25 +515,30 @@ let continueProcess = function (askRemoveGlobalFolder) {
466515}
467516
468517if ( process . ppid > 1 ) {
469- findProcess ( 'pid' , process . ppid )
470- . then ( function ( list ) {
471- if ( list . length === 1 && list [ 0 ] . ppid > 1 ) {
472- findProcess ( 'pid' , list [ 0 ] . ppid )
473- . then ( function ( list ) {
474- if ( list . length === 1 && / ( ( n p m - c l i .j s ( " | ' ) \s + u p ( d a t e ) ? ) | ( y a r n .j s ( " | ' ) \s + ( g l o b a l \s + ) ? u p g r a d e ) ) \s + .* ( ( \/ ) | ( \\ ) | ( \s ) ) d e v s p a c e ( ( \/ ) | ( \\ ) | ( \s ) | $ ) / . test ( list [ 0 ] . cmd ) ) {
475- continueProcess ( false ) ;
476- } else {
518+ try {
519+ const findProcess = getFindProcess ( ) ;
520+ findProcess ( 'pid' , process . ppid )
521+ . then ( function ( list ) {
522+ if ( list . length === 1 && list [ 0 ] . ppid > 1 ) {
523+ findProcess ( 'pid' , list [ 0 ] . ppid )
524+ . then ( function ( list ) {
525+ if ( list . length === 1 && / ( ( n p m - c l i .j s ( " | ' ) \s + u p ( d a t e ) ? ) | ( y a r n .j s ( " | ' ) \s + ( g l o b a l \s + ) ? u p g r a d e ) ) \s + .* ( ( \/ ) | ( \\ ) | ( \s ) ) d e v s p a c e ( ( \/ ) | ( \\ ) | ( \s ) | $ ) / . test ( list [ 0 ] . cmd ) ) {
526+ continueProcess ( false ) ;
527+ } else {
528+ continueProcess ( true ) ;
529+ }
530+ } , function ( ) {
477531 continueProcess ( true ) ;
478- }
479- } , function ( ) {
480- continueProcess ( true ) ;
481- } )
482- } else {
532+ } )
533+ } else {
534+ continueProcess ( true ) ;
535+ }
536+ } , function ( ) {
483537 continueProcess ( true ) ;
484- }
485- } , function ( ) {
486- continueProcess ( true ) ;
487- } )
538+ } )
539+ } catch ( e ) {
540+ continueProcess ( true ) ;
541+ }
488542} else {
489543 continueProcess ( true ) ;
490544}
0 commit comments