mirror of
https://github.com/actions/setup-python.git
synced 2025-06-04 18:42:08 +08:00
Enhance reading from .python-version (#787)
* Enhance reading from .python-version * Fix typos * Fix lint * Add built files * Don't use EOL versions in `utils.test.ts` * Fix Prettier * Don't use unreleased versions in `utils.test.ts` * Update versions in `utils.test.ts` again
This commit is contained in:
parent
a26af69be9
commit
5db1cf9a59
@ -10,7 +10,7 @@ import {
|
|||||||
validatePythonVersionFormatForPyPy,
|
validatePythonVersionFormatForPyPy,
|
||||||
isCacheFeatureAvailable,
|
isCacheFeatureAvailable,
|
||||||
getVersionInputFromFile,
|
getVersionInputFromFile,
|
||||||
getVersionInputFromPlainFile,
|
getVersionsInputFromPlainFile,
|
||||||
getVersionInputFromTomlFile,
|
getVersionInputFromTomlFile,
|
||||||
getNextPageUrl,
|
getNextPageUrl,
|
||||||
isGhes,
|
isGhes,
|
||||||
@ -24,10 +24,10 @@ jest.mock('@actions/core');
|
|||||||
|
|
||||||
describe('validatePythonVersionFormatForPyPy', () => {
|
describe('validatePythonVersionFormatForPyPy', () => {
|
||||||
it.each([
|
it.each([
|
||||||
['3.6', true],
|
['3.12', true],
|
||||||
['3.7', true],
|
['3.13', true],
|
||||||
['3.6.x', false],
|
['3.12.x', false],
|
||||||
['3.7.x', false],
|
['3.13.x', false],
|
||||||
['3.x', false],
|
['3.x', false],
|
||||||
['3', false]
|
['3', false]
|
||||||
])('%s -> %s', (input, expected) => {
|
])('%s -> %s', (input, expected) => {
|
||||||
@ -95,24 +95,52 @@ const tempDir = path.join(
|
|||||||
);
|
);
|
||||||
|
|
||||||
describe('Version from file test', () => {
|
describe('Version from file test', () => {
|
||||||
it.each([getVersionInputFromPlainFile, getVersionInputFromFile])(
|
it.each([getVersionsInputFromPlainFile, getVersionInputFromFile])(
|
||||||
'Version from plain file test',
|
'Version from plain file test',
|
||||||
async _fn => {
|
async _fn => {
|
||||||
await io.mkdirP(tempDir);
|
await io.mkdirP(tempDir);
|
||||||
const pythonVersionFileName = 'python-version.file';
|
const pythonVersionFileName = 'python-version.file';
|
||||||
const pythonVersionFilePath = path.join(tempDir, pythonVersionFileName);
|
const pythonVersionFilePath = path.join(tempDir, pythonVersionFileName);
|
||||||
const pythonVersionFileContent = '3.7';
|
const pythonVersionFileContent = '3.13';
|
||||||
fs.writeFileSync(pythonVersionFilePath, pythonVersionFileContent);
|
fs.writeFileSync(pythonVersionFilePath, pythonVersionFileContent);
|
||||||
expect(_fn(pythonVersionFilePath)).toEqual([pythonVersionFileContent]);
|
expect(_fn(pythonVersionFilePath)).toEqual([pythonVersionFileContent]);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
it.each([getVersionsInputFromPlainFile, getVersionInputFromFile])(
|
||||||
|
'Versions from multiline plain file test',
|
||||||
|
async _fn => {
|
||||||
|
await io.mkdirP(tempDir);
|
||||||
|
const pythonVersionFileName = 'python-version.file';
|
||||||
|
const pythonVersionFilePath = path.join(tempDir, pythonVersionFileName);
|
||||||
|
const pythonVersionFileContent = '3.13\r\n3.12';
|
||||||
|
fs.writeFileSync(pythonVersionFilePath, pythonVersionFileContent);
|
||||||
|
expect(_fn(pythonVersionFilePath)).toEqual(['3.13', '3.12']);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
it.each([getVersionsInputFromPlainFile, getVersionInputFromFile])(
|
||||||
|
'Version from complex plain file test',
|
||||||
|
async _fn => {
|
||||||
|
await io.mkdirP(tempDir);
|
||||||
|
const pythonVersionFileName = 'python-version.file';
|
||||||
|
const pythonVersionFilePath = path.join(tempDir, pythonVersionFileName);
|
||||||
|
const pythonVersionFileContent =
|
||||||
|
'3.13/envs/virtualenv\r# 3.12\n3.11\r\n3.10\r\n 3.9 \r\n';
|
||||||
|
fs.writeFileSync(pythonVersionFilePath, pythonVersionFileContent);
|
||||||
|
expect(_fn(pythonVersionFilePath)).toEqual([
|
||||||
|
'3.13',
|
||||||
|
'3.11',
|
||||||
|
'3.10',
|
||||||
|
'3.9'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
);
|
||||||
it.each([getVersionInputFromTomlFile, getVersionInputFromFile])(
|
it.each([getVersionInputFromTomlFile, getVersionInputFromFile])(
|
||||||
'Version from standard pyproject.toml test',
|
'Version from standard pyproject.toml test',
|
||||||
async _fn => {
|
async _fn => {
|
||||||
await io.mkdirP(tempDir);
|
await io.mkdirP(tempDir);
|
||||||
const pythonVersionFileName = 'pyproject.toml';
|
const pythonVersionFileName = 'pyproject.toml';
|
||||||
const pythonVersionFilePath = path.join(tempDir, pythonVersionFileName);
|
const pythonVersionFilePath = path.join(tempDir, pythonVersionFileName);
|
||||||
const pythonVersion = '>=3.7.0';
|
const pythonVersion = '>=3.13.0';
|
||||||
const pythonVersionFileContent = `[project]\nrequires-python = "${pythonVersion}"`;
|
const pythonVersionFileContent = `[project]\nrequires-python = "${pythonVersion}"`;
|
||||||
fs.writeFileSync(pythonVersionFilePath, pythonVersionFileContent);
|
fs.writeFileSync(pythonVersionFilePath, pythonVersionFileContent);
|
||||||
expect(_fn(pythonVersionFilePath)).toEqual([pythonVersion]);
|
expect(_fn(pythonVersionFilePath)).toEqual([pythonVersion]);
|
||||||
@ -124,7 +152,7 @@ describe('Version from file test', () => {
|
|||||||
await io.mkdirP(tempDir);
|
await io.mkdirP(tempDir);
|
||||||
const pythonVersionFileName = 'pyproject.toml';
|
const pythonVersionFileName = 'pyproject.toml';
|
||||||
const pythonVersionFilePath = path.join(tempDir, pythonVersionFileName);
|
const pythonVersionFilePath = path.join(tempDir, pythonVersionFileName);
|
||||||
const pythonVersion = '>=3.7.0';
|
const pythonVersion = '>=3.13.0';
|
||||||
const pythonVersionFileContent = `[tool.poetry.dependencies]\npython = "${pythonVersion}"`;
|
const pythonVersionFileContent = `[tool.poetry.dependencies]\npython = "${pythonVersion}"`;
|
||||||
fs.writeFileSync(pythonVersionFilePath, pythonVersionFileContent);
|
fs.writeFileSync(pythonVersionFilePath, pythonVersionFileContent);
|
||||||
expect(_fn(pythonVersionFilePath)).toEqual([pythonVersion]);
|
expect(_fn(pythonVersionFilePath)).toEqual([pythonVersion]);
|
||||||
@ -145,9 +173,9 @@ describe('Version from file test', () => {
|
|||||||
async _fn => {
|
async _fn => {
|
||||||
const toolVersionFileName = '.tool-versions';
|
const toolVersionFileName = '.tool-versions';
|
||||||
const toolVersionFilePath = path.join(tempDir, toolVersionFileName);
|
const toolVersionFilePath = path.join(tempDir, toolVersionFileName);
|
||||||
const toolVersionContent = 'python 3.9.10\nnodejs 16';
|
const toolVersionContent = 'python 3.13.2\nnodejs 16';
|
||||||
fs.writeFileSync(toolVersionFilePath, toolVersionContent);
|
fs.writeFileSync(toolVersionFilePath, toolVersionContent);
|
||||||
expect(_fn(toolVersionFilePath)).toEqual(['3.9.10']);
|
expect(_fn(toolVersionFilePath)).toEqual(['3.13.2']);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -156,9 +184,9 @@ describe('Version from file test', () => {
|
|||||||
async _fn => {
|
async _fn => {
|
||||||
const toolVersionFileName = '.tool-versions';
|
const toolVersionFileName = '.tool-versions';
|
||||||
const toolVersionFilePath = path.join(tempDir, toolVersionFileName);
|
const toolVersionFilePath = path.join(tempDir, toolVersionFileName);
|
||||||
const toolVersionContent = '# python 3.8\npython 3.9';
|
const toolVersionContent = '# python 3.13\npython 3.12';
|
||||||
fs.writeFileSync(toolVersionFilePath, toolVersionContent);
|
fs.writeFileSync(toolVersionFilePath, toolVersionContent);
|
||||||
expect(_fn(toolVersionFilePath)).toEqual(['3.9']);
|
expect(_fn(toolVersionFilePath)).toEqual(['3.12']);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -167,9 +195,9 @@ describe('Version from file test', () => {
|
|||||||
async _fn => {
|
async _fn => {
|
||||||
const toolVersionFileName = '.tool-versions';
|
const toolVersionFileName = '.tool-versions';
|
||||||
const toolVersionFilePath = path.join(tempDir, toolVersionFileName);
|
const toolVersionFilePath = path.join(tempDir, toolVersionFileName);
|
||||||
const toolVersionContent = ' python 3.10 ';
|
const toolVersionContent = ' python 3.13 ';
|
||||||
fs.writeFileSync(toolVersionFilePath, toolVersionContent);
|
fs.writeFileSync(toolVersionFilePath, toolVersionContent);
|
||||||
expect(_fn(toolVersionFilePath)).toEqual(['3.10']);
|
expect(_fn(toolVersionFilePath)).toEqual(['3.13']);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -178,9 +206,9 @@ describe('Version from file test', () => {
|
|||||||
async _fn => {
|
async _fn => {
|
||||||
const toolVersionFileName = '.tool-versions';
|
const toolVersionFileName = '.tool-versions';
|
||||||
const toolVersionFilePath = path.join(tempDir, toolVersionFileName);
|
const toolVersionFilePath = path.join(tempDir, toolVersionFileName);
|
||||||
const toolVersionContent = 'python v3.9.10';
|
const toolVersionContent = 'python v3.13.2';
|
||||||
fs.writeFileSync(toolVersionFilePath, toolVersionContent);
|
fs.writeFileSync(toolVersionFilePath, toolVersionContent);
|
||||||
expect(_fn(toolVersionFilePath)).toEqual(['3.9.10']);
|
expect(_fn(toolVersionFilePath)).toEqual(['3.13.2']);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -189,9 +217,9 @@ describe('Version from file test', () => {
|
|||||||
async _fn => {
|
async _fn => {
|
||||||
const toolVersionFileName = '.tool-versions';
|
const toolVersionFileName = '.tool-versions';
|
||||||
const toolVersionFilePath = path.join(tempDir, toolVersionFileName);
|
const toolVersionFilePath = path.join(tempDir, toolVersionFileName);
|
||||||
const toolVersionContent = 'python pypy3.10-7.3.14';
|
const toolVersionContent = 'python pypy3.10-7.3.19';
|
||||||
fs.writeFileSync(toolVersionFilePath, toolVersionContent);
|
fs.writeFileSync(toolVersionFilePath, toolVersionContent);
|
||||||
expect(_fn(toolVersionFilePath)).toEqual(['pypy3.10-7.3.14']);
|
expect(_fn(toolVersionFilePath)).toEqual(['pypy3.10-7.3.19']);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
37
dist/setup/index.js
vendored
37
dist/setup/index.js
vendored
@ -96929,7 +96929,7 @@ function cacheDependencies(cache, pythonVersion) {
|
|||||||
}
|
}
|
||||||
function resolveVersionInputFromDefaultFile() {
|
function resolveVersionInputFromDefaultFile() {
|
||||||
const couples = [
|
const couples = [
|
||||||
['.python-version', utils_1.getVersionInputFromPlainFile]
|
['.python-version', utils_1.getVersionsInputFromPlainFile]
|
||||||
];
|
];
|
||||||
for (const [versionFile, _fn] of couples) {
|
for (const [versionFile, _fn] of couples) {
|
||||||
(0, utils_1.logWarning)(`Neither 'python-version' nor 'python-version-file' inputs were supplied. Attempting to find '${versionFile}' file.`);
|
(0, utils_1.logWarning)(`Neither 'python-version' nor 'python-version-file' inputs were supplied. Attempting to find '${versionFile}' file.`);
|
||||||
@ -97066,7 +97066,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.getDownloadFileName = exports.getNextPageUrl = exports.getBinaryDirectory = exports.getVersionInputFromFile = exports.getVersionInputFromToolVersions = exports.getVersionInputFromPlainFile = exports.getVersionInputFromTomlFile = exports.getOSInfo = exports.getLinuxInfo = exports.logWarning = exports.isCacheFeatureAvailable = exports.isGhes = exports.validatePythonVersionFormatForPyPy = exports.writeExactPyPyVersionFile = exports.readExactPyPyVersionFile = exports.getPyPyVersionFromPath = exports.isNightlyKeyword = exports.validateVersion = exports.createSymlinkInFolder = exports.WINDOWS_PLATFORMS = exports.WINDOWS_ARCHS = exports.IS_MAC = exports.IS_LINUX = exports.IS_WINDOWS = void 0;
|
exports.getDownloadFileName = exports.getNextPageUrl = exports.getBinaryDirectory = exports.getVersionInputFromFile = exports.getVersionInputFromToolVersions = exports.getVersionsInputFromPlainFile = exports.getVersionInputFromTomlFile = exports.getOSInfo = exports.getLinuxInfo = exports.logWarning = exports.isCacheFeatureAvailable = exports.isGhes = exports.validatePythonVersionFormatForPyPy = exports.writeExactPyPyVersionFile = exports.readExactPyPyVersionFile = exports.getPyPyVersionFromPath = exports.isNightlyKeyword = exports.validateVersion = exports.createSymlinkInFolder = exports.WINDOWS_PLATFORMS = exports.WINDOWS_ARCHS = exports.IS_MAC = exports.IS_LINUX = exports.IS_WINDOWS = void 0;
|
||||||
/* eslint no-unsafe-finally: "off" */
|
/* eslint no-unsafe-finally: "off" */
|
||||||
const cache = __importStar(__nccwpck_require__(5116));
|
const cache = __importStar(__nccwpck_require__(5116));
|
||||||
const core = __importStar(__nccwpck_require__(7484));
|
const core = __importStar(__nccwpck_require__(7484));
|
||||||
@ -97247,7 +97247,7 @@ function extractValue(obj, keys) {
|
|||||||
* If none is present, returns an empty list.
|
* If none is present, returns an empty list.
|
||||||
*/
|
*/
|
||||||
function getVersionInputFromTomlFile(versionFile) {
|
function getVersionInputFromTomlFile(versionFile) {
|
||||||
core.debug(`Trying to resolve version form ${versionFile}`);
|
core.debug(`Trying to resolve version from ${versionFile}`);
|
||||||
let pyprojectFile = fs_1.default.readFileSync(versionFile, 'utf8');
|
let pyprojectFile = fs_1.default.readFileSync(versionFile, 'utf8');
|
||||||
// Normalize the line endings in the pyprojectFile
|
// Normalize the line endings in the pyprojectFile
|
||||||
pyprojectFile = pyprojectFile.replace(/\r\n/g, '\n');
|
pyprojectFile = pyprojectFile.replace(/\r\n/g, '\n');
|
||||||
@ -97280,15 +97280,30 @@ function getVersionInputFromTomlFile(versionFile) {
|
|||||||
}
|
}
|
||||||
exports.getVersionInputFromTomlFile = getVersionInputFromTomlFile;
|
exports.getVersionInputFromTomlFile = getVersionInputFromTomlFile;
|
||||||
/**
|
/**
|
||||||
* Python version extracted from a plain text file.
|
* Python versions extracted from a plain text file.
|
||||||
|
* - Resolves multiple versions from multiple lines.
|
||||||
|
* - Handles pyenv-virtualenv pointers (e.g. `3.10/envs/virtualenv`).
|
||||||
|
* - Ignores empty lines and lines starting with `#`
|
||||||
|
* - Trims whitespace.
|
||||||
*/
|
*/
|
||||||
function getVersionInputFromPlainFile(versionFile) {
|
function getVersionsInputFromPlainFile(versionFile) {
|
||||||
core.debug(`Trying to resolve version form ${versionFile}`);
|
core.debug(`Trying to resolve versions from ${versionFile}`);
|
||||||
const version = fs_1.default.readFileSync(versionFile, 'utf8').trim();
|
const content = fs_1.default.readFileSync(versionFile, 'utf8').trim();
|
||||||
core.info(`Resolved ${versionFile} as ${version}`);
|
const lines = content.split(/\r\n|\r|\n/);
|
||||||
return [version];
|
const versions = lines
|
||||||
|
.map(line => {
|
||||||
|
if (line.startsWith('#') || line.trim() === '') {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
let version = line.trim();
|
||||||
|
version = version.split('/')[0];
|
||||||
|
return version;
|
||||||
|
})
|
||||||
|
.filter(version => version !== undefined);
|
||||||
|
core.info(`Resolved ${versionFile} as ${versions.join(', ')}`);
|
||||||
|
return versions;
|
||||||
}
|
}
|
||||||
exports.getVersionInputFromPlainFile = getVersionInputFromPlainFile;
|
exports.getVersionsInputFromPlainFile = getVersionsInputFromPlainFile;
|
||||||
/**
|
/**
|
||||||
* Python version extracted from a .tool-versions file.
|
* Python version extracted from a .tool-versions file.
|
||||||
*/
|
*/
|
||||||
@ -97331,7 +97346,7 @@ function getVersionInputFromFile(versionFile) {
|
|||||||
return getVersionInputFromToolVersions(versionFile);
|
return getVersionInputFromToolVersions(versionFile);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return getVersionInputFromPlainFile(versionFile);
|
return getVersionsInputFromPlainFile(versionFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exports.getVersionInputFromFile = getVersionInputFromFile;
|
exports.getVersionInputFromFile = getVersionInputFromFile;
|
||||||
|
@ -11,7 +11,7 @@ import {
|
|||||||
logWarning,
|
logWarning,
|
||||||
IS_MAC,
|
IS_MAC,
|
||||||
getVersionInputFromFile,
|
getVersionInputFromFile,
|
||||||
getVersionInputFromPlainFile
|
getVersionsInputFromPlainFile
|
||||||
} from './utils';
|
} from './utils';
|
||||||
|
|
||||||
function isPyPyVersion(versionSpec: string) {
|
function isPyPyVersion(versionSpec: string) {
|
||||||
@ -35,7 +35,7 @@ async function cacheDependencies(cache: string, pythonVersion: string) {
|
|||||||
|
|
||||||
function resolveVersionInputFromDefaultFile(): string[] {
|
function resolveVersionInputFromDefaultFile(): string[] {
|
||||||
const couples: [string, (versionFile: string) => string[]][] = [
|
const couples: [string, (versionFile: string) => string[]][] = [
|
||||||
['.python-version', getVersionInputFromPlainFile]
|
['.python-version', getVersionsInputFromPlainFile]
|
||||||
];
|
];
|
||||||
for (const [versionFile, _fn] of couples) {
|
for (const [versionFile, _fn] of couples) {
|
||||||
logWarning(
|
logWarning(
|
||||||
|
31
src/utils.ts
31
src/utils.ts
@ -228,7 +228,7 @@ function extractValue(obj: any, keys: string[]): string | undefined {
|
|||||||
* If none is present, returns an empty list.
|
* If none is present, returns an empty list.
|
||||||
*/
|
*/
|
||||||
export function getVersionInputFromTomlFile(versionFile: string): string[] {
|
export function getVersionInputFromTomlFile(versionFile: string): string[] {
|
||||||
core.debug(`Trying to resolve version form ${versionFile}`);
|
core.debug(`Trying to resolve version from ${versionFile}`);
|
||||||
|
|
||||||
let pyprojectFile = fs.readFileSync(versionFile, 'utf8');
|
let pyprojectFile = fs.readFileSync(versionFile, 'utf8');
|
||||||
// Normalize the line endings in the pyprojectFile
|
// Normalize the line endings in the pyprojectFile
|
||||||
@ -269,13 +269,28 @@ export function getVersionInputFromTomlFile(versionFile: string): string[] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Python version extracted from a plain text file.
|
* Python versions extracted from a plain text file.
|
||||||
|
* - Resolves multiple versions from multiple lines.
|
||||||
|
* - Handles pyenv-virtualenv pointers (e.g. `3.10/envs/virtualenv`).
|
||||||
|
* - Ignores empty lines and lines starting with `#`
|
||||||
|
* - Trims whitespace.
|
||||||
*/
|
*/
|
||||||
export function getVersionInputFromPlainFile(versionFile: string): string[] {
|
export function getVersionsInputFromPlainFile(versionFile: string): string[] {
|
||||||
core.debug(`Trying to resolve version form ${versionFile}`);
|
core.debug(`Trying to resolve versions from ${versionFile}`);
|
||||||
const version = fs.readFileSync(versionFile, 'utf8').trim();
|
const content = fs.readFileSync(versionFile, 'utf8').trim();
|
||||||
core.info(`Resolved ${versionFile} as ${version}`);
|
const lines = content.split(/\r\n|\r|\n/);
|
||||||
return [version];
|
const versions = lines
|
||||||
|
.map(line => {
|
||||||
|
if (line.startsWith('#') || line.trim() === '') {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
let version: string = line.trim();
|
||||||
|
version = version.split('/')[0];
|
||||||
|
return version;
|
||||||
|
})
|
||||||
|
.filter(version => version !== undefined) as string[];
|
||||||
|
core.info(`Resolved ${versionFile} as ${versions.join(', ')}`);
|
||||||
|
return versions;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -319,7 +334,7 @@ export function getVersionInputFromFile(versionFile: string): string[] {
|
|||||||
} else if (versionFile.match('.tool-versions')) {
|
} else if (versionFile.match('.tool-versions')) {
|
||||||
return getVersionInputFromToolVersions(versionFile);
|
return getVersionInputFromToolVersions(versionFile);
|
||||||
} else {
|
} else {
|
||||||
return getVersionInputFromPlainFile(versionFile);
|
return getVersionsInputFromPlainFile(versionFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user