Skip to content

Commit c155c58

Browse files
committed
Add support to .tool-version file format
Create a function to parse tool-version (asdf-vm) format, add the associated tests, and updated the documentation Ticket-ID: #571
1 parent 34b4b62 commit c155c58

File tree

4 files changed

+47
-6
lines changed

4 files changed

+47
-6
lines changed

__tests__/utils.test.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as cache from '@actions/cache';
22
import * as core from '@actions/core';
33
import {
4+
parsePythonVersionFile,
45
validateVersion,
56
validatePythonVersionFormatForPyPy,
67
isCacheFeatureAvailable
@@ -9,6 +10,20 @@ import {
910
jest.mock('@actions/cache');
1011
jest.mock('@actions/core');
1112

13+
describe('parsePythonVersionFile', () => {
14+
it('handle the content of a .python-version file', () => {
15+
expect(parsePythonVersionFile('3.6')).toEqual('3.6')
16+
});
17+
18+
it('trims extra spaces at the end of the content', () => {
19+
expect(parsePythonVersionFile('3.7 ')).toEqual('3.7')
20+
});
21+
22+
it('parses correctly the content of .tool-version files', () => {
23+
expect(parsePythonVersionFile('python 3.7')).toEqual('3.7')
24+
});
25+
});
26+
1227
describe('validatePythonVersionFormatForPyPy', () => {
1328
it.each([
1429
['3.6', true],

docs/advanced-usage.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,9 +238,10 @@ jobs:
238238

239239
## Using the `python-version-file` input
240240

241-
`setup-python` action can read Python or PyPy version from a version file. `python-version-file` input is used for specifying the path to the version file. If the file that was supplied to `python-version-file` input doesn't exist, the action will fail with error.
241+
The python-version-file input accepts a path to a file containing the version of Python to be used by a project, for example .python-version, or .tool-versions.
242+
If both the python-version and the python-version-file inputs are provided then the python-version input is used.
242243

243-
>In case both `python-version` and `python-version-file` inputs are supplied, the `python-version-file` input will be ignored due to its lower priority.
244+
> The action will search for the python version file relative to the repository root.
244245

245246
```yaml
246247
steps:

src/setup-python.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import * as path from 'path';
55
import * as os from 'os';
66
import fs from 'fs';
77
import {getCacheDistributor} from './cache-distributions/cache-factory';
8-
import {isCacheFeatureAvailable, logWarning, IS_MAC} from './utils';
8+
import {parsePythonVersionFile, isCacheFeatureAvailable, logWarning, IS_MAC} from './utils';
99

1010
function isPyPyVersion(versionSpec: string) {
1111
return versionSpec.startsWith('pypy');
@@ -37,20 +37,29 @@ function resolveVersionInput() {
3737
}
3838

3939
if (versionFile) {
40-
if (!fs.existsSync(versionFile)) {
40+
const versionFilePath = path.join(
41+
process.env.GITHUB_WORKSPACE!,
42+
versionFile
43+
);
44+
45+
if (!fs.existsSync(versionFilePath)) {
4146
throw new Error(
42-
`The specified python version file at: ${versionFile} doesn't exist.`
47+
`The specified python version file at: ${versionFilePath} doesn't exist.`
4348
);
4449
}
45-
const version = fs.readFileSync(versionFile, 'utf8');
50+
51+
const version = parsePythonVersionFile(fs.readFileSync(versionFilePath, 'utf8'));
4652
core.info(`Resolved ${versionFile} as ${version}`);
53+
4754
return [version];
4855
}
4956

5057
logWarning(
5158
"Neither 'python-version' nor 'python-version-file' inputs were supplied. Attempting to find '.python-version' file."
5259
);
60+
5361
versionFile = '.python-version';
62+
5463
if (fs.existsSync(versionFile)) {
5564
const version = fs.readFileSync(versionFile, 'utf8');
5665
core.info(`Resolved ${versionFile} as ${version}`);

src/utils.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,22 @@ export interface IPyPyManifestRelease {
2727
files: IPyPyManifestAsset[];
2828
}
2929

30+
export function parsePythonVersionFile(contents: string): string {
31+
let pythonVersion: string | undefined;
32+
33+
// Try to find the version in tool-version file
34+
const found = contents.match(/^(?:python\s+)?v?(?<version>[^\s]+)$/m);
35+
pythonVersion = found?.groups?.version;
36+
37+
// In the case of an unknown format,
38+
// return as is and evaluate the version separately.
39+
if (!pythonVersion) {
40+
pythonVersion = contents.trim();
41+
}
42+
43+
return pythonVersion as string;
44+
}
45+
3046
/** create Symlinks for downloaded PyPy
3147
* It should be executed only for downloaded versions in runtime, because
3248
* toolcache versions have this setup.

0 commit comments

Comments
 (0)