@@ -32,6 +32,8 @@ export default class PlatformIOCoreStage extends BaseStage {
3232 constructor ( ) {
3333 super ( ...arguments ) ;
3434 tmp . setGracefulCleanup ( ) ;
35+
36+ this . _skipPipUpgrading = false ;
3537 }
3638
3739 get name ( ) {
@@ -79,10 +81,11 @@ export default class PlatformIOCoreStage extends BaseStage {
7981 path . join ( core . getCacheDir ( ) , path . basename ( installerUrl ) )
8082 ) ;
8183 const targetDir = path . join ( core . getHomeDir ( ) , 'python37' ) ;
82- const pythonPath = path . join ( targetDir , 'python.exe' ) ;
84+ let pythonPath = path . join ( targetDir , 'python.exe' ) ;
8385
8486 if ( ! fs . isFileSync ( pythonPath ) ) {
85- await this . installPythonFromWindowsInstaller ( installer , targetDir ) ;
87+ pythonPath = await this . installPythonFromWindowsInstaller ( installer , targetDir ) ;
88+ this . _skipPipUpgrading = true ;
8689 }
8790
8891 // append temporary to system environment
@@ -95,53 +98,56 @@ export default class PlatformIOCoreStage extends BaseStage {
9598 return pythonPath ;
9699 }
97100
98- async installPythonFromWindowsInstaller ( installer , targetDir ) {
101+ installPythonFromWindowsInstaller ( installer , targetDir ) {
99102 if ( fs . isDirectorySync ( targetDir ) ) {
100103 try {
101104 fs . removeSync ( targetDir ) ;
102105 } catch ( err ) {
103106 console . warn ( err ) ;
104107 }
105108 }
106- misc . runCommand (
107- installer ,
108- [
109- '/quiet' ,
110- '/log' ,
111- path . join ( core . getCacheDir ( ) , 'python-installer.log' ) ,
112- 'SimpleInstall=1' ,
113- 'InstallAllUsers=0' ,
114- 'InstallLauncherAllUsers=0' ,
115- 'Shortcuts=0' ,
116- 'Include_lib=1' ,
117- 'Include_pip=1' ,
118- 'Include_doc=0' ,
119- 'Include_launcher=0' ,
120- 'Include_test=0' ,
121- 'Include_tcltk=0' ,
122- `DefaultJustForMeTargetDir=${ targetDir } `
123- ] ,
124- {
125- spawnOptions : {
126- shell : true
109+ const logPath = path . join ( core . getCacheDir ( ) , 'python-installer.log' ) ;
110+ return new Promise ( ( resolve , reject ) => {
111+ misc . runCommand (
112+ installer ,
113+ [
114+ '/quiet' ,
115+ '/log' ,
116+ logPath ,
117+ 'SimpleInstall=1' ,
118+ 'InstallAllUsers=0' ,
119+ 'InstallLauncherAllUsers=0' ,
120+ 'Shortcuts=0' ,
121+ 'Include_lib=1' ,
122+ 'Include_pip=1' ,
123+ 'Include_doc=0' ,
124+ 'Include_launcher=0' ,
125+ 'Include_test=0' ,
126+ 'Include_tcltk=0' ,
127+ `TargetDir=${ targetDir } ` ,
128+ `DefaultAllUsersTargetDir=${ targetDir } ` ,
129+ `DefaultJustForMeTargetDir=${ targetDir } `
130+ ] ,
131+ code => {
132+ if ( code === 0 && fs . isFileSync ( path . join ( targetDir , 'python.exe' ) ) ) {
133+ return resolve ( path . join ( targetDir , 'python.exe' ) ) ;
134+ }
135+ if ( fs . isFileSync ( logPath ) ) {
136+ console . error ( fs . readFileSync ( logPath ) . toString ( ) ) ;
137+ }
138+ return reject (
139+ new Error (
140+ 'Could not install Python 3 automatically. Please install it manually from https://python.org'
141+ )
142+ ) ;
143+ } ,
144+ {
145+ spawnOptions : {
146+ shell : true
147+ }
127148 }
128- }
129- ) ;
130-
131- const timeout = 5 * 60 ;
132- const delay = 5 ;
133- let elapsed = 0 ;
134- const pipPath = path . join ( targetDir , 'Scripts' , 'pip.exe' ) ;
135- while ( elapsed < timeout ) {
136- await misc . sleep ( delay * 1000 ) ;
137- elapsed += delay ;
138- if ( fs . isFileSync ( pipPath ) ) {
139- return true ;
140- }
141- }
142- throw new Error (
143- 'Could not install Python 3 automatically. Please install it manually from https://python.org'
144- ) ;
149+ ) ;
150+ } ) ;
145151 }
146152
147153 cleanVirtualEnvDir ( ) {
@@ -301,6 +307,9 @@ export default class PlatformIOCoreStage extends BaseStage {
301307 }
302308
303309 async upgradePIP ( pythonExecutable ) {
310+ if ( this . _skipPipUpgrading ) {
311+ return ;
312+ }
304313 // we use manual downloading to resolve SSL issue with old `pip`
305314 const pipArchive = await helpers . download (
306315 PlatformIOCoreStage . pipUrl ,
0 commit comments