Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 5db1cf9

Browse filesBrowse files
authored
Enhance reading from .python-version (actions#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
1 parent a26af69 commit 5db1cf9
Copy full SHA for 5db1cf9

File tree

Expand file treeCollapse file tree

4 files changed

+99
-41
lines changed
Filter options
Expand file treeCollapse file tree

4 files changed

+99
-41
lines changed

‎__tests__/utils.test.ts

Copy file name to clipboardExpand all lines: __tests__/utils.test.ts
+47-19Lines changed: 47 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
validatePythonVersionFormatForPyPy,
1111
isCacheFeatureAvailable,
1212
getVersionInputFromFile,
13-
getVersionInputFromPlainFile,
13+
getVersionsInputFromPlainFile,
1414
getVersionInputFromTomlFile,
1515
getNextPageUrl,
1616
isGhes,
@@ -24,10 +24,10 @@ jest.mock('@actions/core');
2424

2525
describe('validatePythonVersionFormatForPyPy', () => {
2626
it.each([
27-
['3.6', true],
28-
['3.7', true],
29-
['3.6.x', false],
30-
['3.7.x', false],
27+
['3.12', true],
28+
['3.13', true],
29+
['3.12.x', false],
30+
['3.13.x', false],
3131
['3.x', false],
3232
['3', false]
3333
])('%s -> %s', (input, expected) => {
@@ -95,24 +95,52 @@ const tempDir = path.join(
9595
);
9696

9797
describe('Version from file test', () => {
98-
it.each([getVersionInputFromPlainFile, getVersionInputFromFile])(
98+
it.each([getVersionsInputFromPlainFile, getVersionInputFromFile])(
9999
'Version from plain file test',
100100
async _fn => {
101101
await io.mkdirP(tempDir);
102102
const pythonVersionFileName = 'python-version.file';
103103
const pythonVersionFilePath = path.join(tempDir, pythonVersionFileName);
104-
const pythonVersionFileContent = '3.7';
104+
const pythonVersionFileContent = '3.13';
105105
fs.writeFileSync(pythonVersionFilePath, pythonVersionFileContent);
106106
expect(_fn(pythonVersionFilePath)).toEqual([pythonVersionFileContent]);
107107
}
108108
);
109+
it.each([getVersionsInputFromPlainFile, getVersionInputFromFile])(
110+
'Versions from multiline plain file test',
111+
async _fn => {
112+
await io.mkdirP(tempDir);
113+
const pythonVersionFileName = 'python-version.file';
114+
const pythonVersionFilePath = path.join(tempDir, pythonVersionFileName);
115+
const pythonVersionFileContent = '3.13\r\n3.12';
116+
fs.writeFileSync(pythonVersionFilePath, pythonVersionFileContent);
117+
expect(_fn(pythonVersionFilePath)).toEqual(['3.13', '3.12']);
118+
}
119+
);
120+
it.each([getVersionsInputFromPlainFile, getVersionInputFromFile])(
121+
'Version from complex plain file test',
122+
async _fn => {
123+
await io.mkdirP(tempDir);
124+
const pythonVersionFileName = 'python-version.file';
125+
const pythonVersionFilePath = path.join(tempDir, pythonVersionFileName);
126+
const pythonVersionFileContent =
127+
'3.13/envs/virtualenv\r# 3.12\n3.11\r\n3.10\r\n 3.9 \r\n';
128+
fs.writeFileSync(pythonVersionFilePath, pythonVersionFileContent);
129+
expect(_fn(pythonVersionFilePath)).toEqual([
130+
'3.13',
131+
'3.11',
132+
'3.10',
133+
'3.9'
134+
]);
135+
}
136+
);
109137
it.each([getVersionInputFromTomlFile, getVersionInputFromFile])(
110138
'Version from standard pyproject.toml test',
111139
async _fn => {
112140
await io.mkdirP(tempDir);
113141
const pythonVersionFileName = 'pyproject.toml';
114142
const pythonVersionFilePath = path.join(tempDir, pythonVersionFileName);
115-
const pythonVersion = '>=3.7.0';
143+
const pythonVersion = '>=3.13.0';
116144
const pythonVersionFileContent = `[project]\nrequires-python = "${pythonVersion}"`;
117145
fs.writeFileSync(pythonVersionFilePath, pythonVersionFileContent);
118146
expect(_fn(pythonVersionFilePath)).toEqual([pythonVersion]);
@@ -124,7 +152,7 @@ describe('Version from file test', () => {
124152
await io.mkdirP(tempDir);
125153
const pythonVersionFileName = 'pyproject.toml';
126154
const pythonVersionFilePath = path.join(tempDir, pythonVersionFileName);
127-
const pythonVersion = '>=3.7.0';
155+
const pythonVersion = '>=3.13.0';
128156
const pythonVersionFileContent = `[tool.poetry.dependencies]\npython = "${pythonVersion}"`;
129157
fs.writeFileSync(pythonVersionFilePath, pythonVersionFileContent);
130158
expect(_fn(pythonVersionFilePath)).toEqual([pythonVersion]);
@@ -145,9 +173,9 @@ describe('Version from file test', () => {
145173
async _fn => {
146174
const toolVersionFileName = '.tool-versions';
147175
const toolVersionFilePath = path.join(tempDir, toolVersionFileName);
148-
const toolVersionContent = 'python 3.9.10\nnodejs 16';
176+
const toolVersionContent = 'python 3.13.2\nnodejs 16';
149177
fs.writeFileSync(toolVersionFilePath, toolVersionContent);
150-
expect(_fn(toolVersionFilePath)).toEqual(['3.9.10']);
178+
expect(_fn(toolVersionFilePath)).toEqual(['3.13.2']);
151179
}
152180
);
153181

@@ -156,9 +184,9 @@ describe('Version from file test', () => {
156184
async _fn => {
157185
const toolVersionFileName = '.tool-versions';
158186
const toolVersionFilePath = path.join(tempDir, toolVersionFileName);
159-
const toolVersionContent = '# python 3.8\npython 3.9';
187+
const toolVersionContent = '# python 3.13\npython 3.12';
160188
fs.writeFileSync(toolVersionFilePath, toolVersionContent);
161-
expect(_fn(toolVersionFilePath)).toEqual(['3.9']);
189+
expect(_fn(toolVersionFilePath)).toEqual(['3.12']);
162190
}
163191
);
164192

@@ -167,9 +195,9 @@ describe('Version from file test', () => {
167195
async _fn => {
168196
const toolVersionFileName = '.tool-versions';
169197
const toolVersionFilePath = path.join(tempDir, toolVersionFileName);
170-
const toolVersionContent = ' python 3.10 ';
198+
const toolVersionContent = ' python 3.13 ';
171199
fs.writeFileSync(toolVersionFilePath, toolVersionContent);
172-
expect(_fn(toolVersionFilePath)).toEqual(['3.10']);
200+
expect(_fn(toolVersionFilePath)).toEqual(['3.13']);
173201
}
174202
);
175203

@@ -178,9 +206,9 @@ describe('Version from file test', () => {
178206
async _fn => {
179207
const toolVersionFileName = '.tool-versions';
180208
const toolVersionFilePath = path.join(tempDir, toolVersionFileName);
181-
const toolVersionContent = 'python v3.9.10';
209+
const toolVersionContent = 'python v3.13.2';
182210
fs.writeFileSync(toolVersionFilePath, toolVersionContent);
183-
expect(_fn(toolVersionFilePath)).toEqual(['3.9.10']);
211+
expect(_fn(toolVersionFilePath)).toEqual(['3.13.2']);
184212
}
185213
);
186214

@@ -189,9 +217,9 @@ describe('Version from file test', () => {
189217
async _fn => {
190218
const toolVersionFileName = '.tool-versions';
191219
const toolVersionFilePath = path.join(tempDir, toolVersionFileName);
192-
const toolVersionContent = 'python pypy3.10-7.3.14';
220+
const toolVersionContent = 'python pypy3.10-7.3.19';
193221
fs.writeFileSync(toolVersionFilePath, toolVersionContent);
194-
expect(_fn(toolVersionFilePath)).toEqual(['pypy3.10-7.3.14']);
222+
expect(_fn(toolVersionFilePath)).toEqual(['pypy3.10-7.3.19']);
195223
}
196224
);
197225

‎dist/setup/index.js

Copy file name to clipboardExpand all lines: dist/setup/index.js
+27-12Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -96929,7 +96929,7 @@ function cacheDependencies(cache, pythonVersion) {
9692996929
}
9693096930
function resolveVersionInputFromDefaultFile() {
9693196931
const couples = [
96932-
['.python-version', utils_1.getVersionInputFromPlainFile]
96932+
['.python-version', utils_1.getVersionsInputFromPlainFile]
9693396933
];
9693496934
for (const [versionFile, _fn] of couples) {
9693596935
(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) {
9706697066
return (mod && mod.__esModule) ? mod : { "default": mod };
9706797067
};
9706897068
Object.defineProperty(exports, "__esModule", ({ value: true }));
97069-
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;
97069+
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;
9707097070
/* eslint no-unsafe-finally: "off" */
9707197071
const cache = __importStar(__nccwpck_require__(5116));
9707297072
const core = __importStar(__nccwpck_require__(7484));
@@ -97247,7 +97247,7 @@ function extractValue(obj, keys) {
9724797247
* If none is present, returns an empty list.
9724897248
*/
9724997249
function getVersionInputFromTomlFile(versionFile) {
97250-
core.debug(`Trying to resolve version form ${versionFile}`);
97250+
core.debug(`Trying to resolve version from ${versionFile}`);
9725197251
let pyprojectFile = fs_1.default.readFileSync(versionFile, 'utf8');
9725297252
// Normalize the line endings in the pyprojectFile
9725397253
pyprojectFile = pyprojectFile.replace(/\r\n/g, '\n');
@@ -97280,15 +97280,30 @@ function getVersionInputFromTomlFile(versionFile) {
9728097280
}
9728197281
exports.getVersionInputFromTomlFile = getVersionInputFromTomlFile;
9728297282
/**
97283-
* Python version extracted from a plain text file.
97284-
*/
97285-
function getVersionInputFromPlainFile(versionFile) {
97286-
core.debug(`Trying to resolve version form ${versionFile}`);
97287-
const version = fs_1.default.readFileSync(versionFile, 'utf8').trim();
97288-
core.info(`Resolved ${versionFile} as ${version}`);
97289-
return [version];
97283+
* Python versions extracted from a plain text file.
97284+
* - Resolves multiple versions from multiple lines.
97285+
* - Handles pyenv-virtualenv pointers (e.g. `3.10/envs/virtualenv`).
97286+
* - Ignores empty lines and lines starting with `#`
97287+
* - Trims whitespace.
97288+
*/
97289+
function getVersionsInputFromPlainFile(versionFile) {
97290+
core.debug(`Trying to resolve versions from ${versionFile}`);
97291+
const content = fs_1.default.readFileSync(versionFile, 'utf8').trim();
97292+
const lines = content.split(/\r\n|\r|\n/);
97293+
const versions = lines
97294+
.map(line => {
97295+
if (line.startsWith('#') || line.trim() === '') {
97296+
return undefined;
97297+
}
97298+
let version = line.trim();
97299+
version = version.split('/')[0];
97300+
return version;
97301+
})
97302+
.filter(version => version !== undefined);
97303+
core.info(`Resolved ${versionFile} as ${versions.join(', ')}`);
97304+
return versions;
9729097305
}
97291-
exports.getVersionInputFromPlainFile = getVersionInputFromPlainFile;
97306+
exports.getVersionsInputFromPlainFile = getVersionsInputFromPlainFile;
9729297307
/**
9729397308
* Python version extracted from a .tool-versions file.
9729497309
*/
@@ -97331,7 +97346,7 @@ function getVersionInputFromFile(versionFile) {
9733197346
return getVersionInputFromToolVersions(versionFile);
9733297347
}
9733397348
else {
97334-
return getVersionInputFromPlainFile(versionFile);
97349+
return getVersionsInputFromPlainFile(versionFile);
9733597350
}
9733697351
}
9733797352
exports.getVersionInputFromFile = getVersionInputFromFile;

‎src/setup-python.ts

Copy file name to clipboardExpand all lines: src/setup-python.ts
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111
logWarning,
1212
IS_MAC,
1313
getVersionInputFromFile,
14-
getVersionInputFromPlainFile
14+
getVersionsInputFromPlainFile
1515
} from './utils';
1616

1717
function isPyPyVersion(versionSpec: string) {
@@ -35,7 +35,7 @@ async function cacheDependencies(cache: string, pythonVersion: string) {
3535

3636
function resolveVersionInputFromDefaultFile(): string[] {
3737
const couples: [string, (versionFile: string) => string[]][] = [
38-
['.python-version', getVersionInputFromPlainFile]
38+
['.python-version', getVersionsInputFromPlainFile]
3939
];
4040
for (const [versionFile, _fn] of couples) {
4141
logWarning(

‎src/utils.ts

Copy file name to clipboardExpand all lines: src/utils.ts
+23-8Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ function extractValue(obj: any, keys: string[]): string | undefined {
228228
* If none is present, returns an empty list.
229229
*/
230230
export function getVersionInputFromTomlFile(versionFile: string): string[] {
231-
core.debug(`Trying to resolve version form ${versionFile}`);
231+
core.debug(`Trying to resolve version from ${versionFile}`);
232232

233233
let pyprojectFile = fs.readFileSync(versionFile, 'utf8');
234234
// Normalize the line endings in the pyprojectFile
@@ -269,13 +269,28 @@ export function getVersionInputFromTomlFile(versionFile: string): string[] {
269269
}
270270

271271
/**
272-
* Python version extracted from a plain text file.
272+
* Python versions extracted from a plain text file.
273+
* - Resolves multiple versions from multiple lines.
274+
* - Handles pyenv-virtualenv pointers (e.g. `3.10/envs/virtualenv`).
275+
* - Ignores empty lines and lines starting with `#`
276+
* - Trims whitespace.
273277
*/
274-
export function getVersionInputFromPlainFile(versionFile: string): string[] {
275-
core.debug(`Trying to resolve version form ${versionFile}`);
276-
const version = fs.readFileSync(versionFile, 'utf8').trim();
277-
core.info(`Resolved ${versionFile} as ${version}`);
278-
return [version];
278+
export function getVersionsInputFromPlainFile(versionFile: string): string[] {
279+
core.debug(`Trying to resolve versions from ${versionFile}`);
280+
const content = fs.readFileSync(versionFile, 'utf8').trim();
281+
const lines = content.split(/\r\n|\r|\n/);
282+
const versions = lines
283+
.map(line => {
284+
if (line.startsWith('#') || line.trim() === '') {
285+
return undefined;
286+
}
287+
let version: string = line.trim();
288+
version = version.split('/')[0];
289+
return version;
290+
})
291+
.filter(version => version !== undefined) as string[];
292+
core.info(`Resolved ${versionFile} as ${versions.join(', ')}`);
293+
return versions;
279294
}
280295

281296
/**
@@ -319,7 +334,7 @@ export function getVersionInputFromFile(versionFile: string): string[] {
319334
} else if (versionFile.match('.tool-versions')) {
320335
return getVersionInputFromToolVersions(versionFile);
321336
} else {
322-
return getVersionInputFromPlainFile(versionFile);
337+
return getVersionsInputFromPlainFile(versionFile);
323338
}
324339
}
325340

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.