Skip to content

Commit a49f40e

Browse files
committed
Check compatible Python using installer script
1 parent c658323 commit a49f40e

File tree

4 files changed

+38
-51
lines changed

4 files changed

+38
-51
lines changed

src/core.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import * as proc from './proc';
1010

11+
import { findPythonExecutable } from './installer/get-python';
1112
import fs from 'fs';
1213
import path from 'path';
1314

@@ -107,9 +108,7 @@ export function getEnvBinDir() {
107108
}
108109

109110
export async function getCorePythonExe() {
110-
const result =
111-
getCoreState().python_exe ||
112-
(await proc.findPythonExecutable({ pioCoreSpec: '>=5' }));
111+
const result = getCoreState().python_exe || (await findPythonExecutable());
113112
if (!result) {
114113
throw new Error('PlatformIO Core is not installed');
115114
}

src/installer/get-python.js

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import * as core from '../core';
1010
import * as proc from '../proc';
1111

12+
import { callInstallerScript } from './get-platformio';
1213
import crypto from 'crypto';
1314
import fs from 'fs';
1415
import got from 'got';
@@ -19,6 +20,38 @@ import stream from 'stream';
1920
import tar from 'tar';
2021
import zlib from 'zlib';
2122

23+
export async function findPythonExecutable() {
24+
const exenames = proc.IS_WINDOWS ? ['python.exe'] : ['python3', 'python'];
25+
const envPath = process.env.PLATFORMIO_PATH || process.env.PATH;
26+
for (const location of envPath.split(path.delimiter)) {
27+
for (const exename of exenames) {
28+
const executable = path.normalize(path.join(location, exename)).replace(/"/g, '');
29+
try {
30+
if (
31+
fs.existsSync(executable) &&
32+
(await callInstallerScript(executable, ['check', 'python']))
33+
) {
34+
return executable;
35+
}
36+
} catch (err) {
37+
console.warn(executable, err);
38+
}
39+
}
40+
}
41+
return null;
42+
}
43+
44+
async function ensurePythonExeExists(pythonDir) {
45+
const binDir = proc.IS_WINDOWS ? pythonDir : path.join(pythonDir, 'bin');
46+
for (const name of ['python.exe', 'python3', 'python']) {
47+
try {
48+
await fs.promises.access(path.join(binDir, name));
49+
return true;
50+
} catch (err) {}
51+
}
52+
throw new Error('Python executable does not exist!');
53+
}
54+
2255
export async function installPortablePython(destinationDir) {
2356
const registryFile = await getRegistryFile();
2457
if (!registryFile) {
@@ -149,14 +182,3 @@ async function extractTarGz(source, destination) {
149182
.on('close', () => resolve(destination));
150183
});
151184
}
152-
153-
async function ensurePythonExeExists(pythonDir) {
154-
const binDir = proc.IS_WINDOWS ? pythonDir : path.join(pythonDir, 'bin');
155-
for (const name of ['python.exe', 'python3', 'python']) {
156-
try {
157-
await fs.promises.access(path.join(binDir, name));
158-
return true;
159-
} catch (err) {}
160-
}
161-
throw new Error('Python executable does not exist!');
162-
}

src/installer/stages/platformio-core.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ import * as core from '../../core';
1010
import * as home from '../../home';
1111
import * as misc from '../../misc';
1212
import * as proc from '../../proc';
13+
import { findPythonExecutable, installPortablePython } from '../get-python';
1314

1415
import BaseStage from './base';
1516
import { callInstallerScript } from '../get-platformio';
1617
import { promises as fs } from 'fs';
17-
import { installPortablePython } from '../get-python';
1818
import path from 'path';
1919
import tmp from 'tmp';
2020

@@ -170,11 +170,11 @@ export default class PlatformIOCoreStage extends BaseStage {
170170
this.configureBuiltInPython();
171171

172172
if (!prompt) {
173-
return await proc.findPythonExecutable();
173+
return await findPythonExecutable();
174174
}
175175

176176
do {
177-
const pythonExecutable = await proc.findPythonExecutable();
177+
const pythonExecutable = await findPythonExecutable();
178178
if (pythonExecutable) {
179179
return pythonExecutable;
180180
}

src/proc.js

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -192,40 +192,6 @@ export function getCommandOutput(cmd, args, options = {}) {
192192
});
193193
}
194194

195-
export async function findPythonExecutable(options = {}) {
196-
const exenames = IS_WINDOWS ? ['python.exe'] : ['python3', 'python'];
197-
const pythonAssertCode = [
198-
'import sys',
199-
'assert sys.version_info >= (3, 6)',
200-
'print(sys.executable)',
201-
];
202-
if (options.pioCoreSpec) {
203-
pythonAssertCode.push('import semantic_version');
204-
pythonAssertCode.push('from platformio import __version__');
205-
pythonAssertCode.push('from platformio.package.version import pepver_to_semver');
206-
pythonAssertCode.push(
207-
`assert pepver_to_semver(__version__) in semantic_version.Spec("${options.pioCoreSpec}")`
208-
);
209-
}
210-
const envPath = process.env.PLATFORMIO_PATH || process.env.PATH;
211-
for (const location of envPath.split(path.delimiter)) {
212-
for (const exename of exenames) {
213-
const executable = path.normalize(path.join(location, exename)).replace(/"/g, '');
214-
try {
215-
if (
216-
fs.existsSync(executable) &&
217-
(await getCommandOutput(executable, ['-c', pythonAssertCode.join(';')]))
218-
) {
219-
return executable;
220-
}
221-
} catch (err) {
222-
console.warn(executable, err);
223-
}
224-
}
225-
}
226-
return null;
227-
}
228-
229195
export function whereIsProgram(program) {
230196
const envPath = process.env.PLATFORMIO_PATH || process.env.PATH;
231197
for (const location of envPath.split(path.delimiter)) {

0 commit comments

Comments
 (0)