From fd03521cb42be5e587ae2854121b58621902d064 Mon Sep 17 00:00:00 2001 From: Steve Lacey Date: Sun, 29 Jan 2023 13:26:49 +0800 Subject: [PATCH] Support .php-version file; closes #629 --- README.md | 11 ++++++++++- __tests__/install.test.ts | 2 +- __tests__/utils.test.ts | 29 ++++++++++++++++++++++++++++- dist/index.js | 28 ++++++++++++++++++++++++++-- src/install.ts | 2 +- src/utils.ts | 32 ++++++++++++++++++++++++++++++++ 6 files changed, 98 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 67deaaac7..9436949ad 100644 --- a/README.md +++ b/README.md @@ -391,7 +391,7 @@ Disable coverage for these reasons: > Specify using `with` keyword -#### `php-version` (required) +#### `php-version` (optional) - Specify the PHP version you want to set up. - Accepts a `string`. For example `'8.0'`. @@ -399,6 +399,15 @@ Disable coverage for these reasons: - Accepts `nightly` to set up a nightly build from the master branch of PHP. - Accepts the format `d.x`, where `d` is the major version. For example `5.x`, `7.x` and `8.x`. - See [PHP support](#tada-php-support) for supported PHP versions. +- By default, the PHP version is read from `php-version-file`. +- Required if `php-version-file` does not exist. + +#### `php-version-file` (optional) + +- Specify the PHP version file you want to read when `php-version` is not provided. +- Accepts a `string`. For example `'.phpenv-version'`. +- See [PHP support](#tada-php-support) for supported PHP versions. +- By default, `.php-version` file is used. #### `extensions` (optional) diff --git a/__tests__/install.test.ts b/__tests__/install.test.ts index f7051dd73..00a51bc87 100644 --- a/__tests__/install.test.ts +++ b/__tests__/install.test.ts @@ -10,7 +10,7 @@ jest.mock('../src/install', () => ({ .mockImplementation(async (os: string): Promise => { const filename = os + (await utils.scriptExtension(os)); const version: string = await utils.parseVersion( - await utils.getInput('php-version', true) + await utils.resolveVersion() ); const ini_file: string = await utils.parseIniFile( await utils.getInput('ini-file', false) diff --git a/__tests__/utils.test.ts b/__tests__/utils.test.ts index d6fa5694b..1c862cead 100644 --- a/__tests__/utils.test.ts +++ b/__tests__/utils.test.ts @@ -1,3 +1,4 @@ +import fs from 'fs'; import * as path from 'path'; import * as utils from '../src/utils'; @@ -7,7 +8,8 @@ import * as utils from '../src/utils'; jest.mock('@actions/core', () => ({ getInput: jest.fn().mockImplementation(key => { return ['setup-php'].indexOf(key) !== -1 ? key : ''; - }) + }), + info: jest.fn() })); /** @@ -261,6 +263,31 @@ describe('Utils tests', () => { ); }); + it('checking resolveVersion', async () => { + await expect(utils.resolveVersion()).rejects.toThrow( + "Neither 'php-version' nor 'php-version-file' inputs were supplied, and could not find '.php-version' file." + ); + + process.env['php-version-file'] = '.phpenv-version'; + await expect(utils.resolveVersion()).rejects.toThrow( + "Could not find '.phpenv-version' file." + ); + + const existsSync = jest.spyOn(fs, 'existsSync').mockImplementation(); + const readFileSync = jest.spyOn(fs, 'readFileSync').mockImplementation(); + + existsSync.mockReturnValue(true); + readFileSync.mockReturnValue('8.1'); + + expect(await utils.resolveVersion()).toBe('8.1'); + + process.env['php-version'] = '8.2'; + expect(await utils.resolveVersion()).toBe('8.2'); + + existsSync.mockClear(); + readFileSync.mockClear(); + }); + it('checking setVariable', async () => { let script: string = await utils.setVariable('var', 'command', 'linux'); expect(script).toEqual('\nvar="$(command)"\n'); diff --git a/dist/index.js b/dist/index.js index d99edb22e..31504707a 100644 --- a/dist/index.js +++ b/dist/index.js @@ -557,7 +557,7 @@ async function getScript(os) { const ini_values_csv = await utils.getInput('ini-values', false); const coverage_driver = await utils.getInput('coverage', false); const tools_csv = await utils.getInput('tools', false); - const version = await utils.parseVersion(await utils.getInput('php-version', true)); + const version = await utils.parseVersion(await utils.resolveVersion()); const ini_file = await utils.parseIniFile(await utils.getInput('ini-file', false)); let script = await utils.joins('.', script_path, version, ini_file); if (extension_csv) { @@ -1032,8 +1032,12 @@ var __importStar = (this && this.__importStar) || function (mod) { __setModuleDefault(result, mod); return result; }; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.setVariable = exports.parseExtensionSource = exports.customPackage = exports.scriptTool = exports.scriptExtension = exports.joins = exports.getCommand = exports.getUnsupportedLog = exports.suppressOutput = exports.getExtensionPrefix = exports.CSVArray = exports.extensionArray = exports.addLog = exports.stepLog = exports.log = exports.color = exports.asyncForEach = exports.parseIniFile = exports.parseVersion = exports.getManifestURL = exports.getInput = exports.readEnv = void 0; +exports.setVariable = exports.resolveVersion = exports.parseExtensionSource = exports.customPackage = exports.scriptTool = exports.scriptExtension = exports.joins = exports.getCommand = exports.getUnsupportedLog = exports.suppressOutput = exports.getExtensionPrefix = exports.CSVArray = exports.extensionArray = exports.addLog = exports.stepLog = exports.log = exports.color = exports.asyncForEach = exports.parseIniFile = exports.parseVersion = exports.getManifestURL = exports.getInput = exports.readEnv = void 0; +const fs_1 = __importDefault(__nccwpck_require__(7147)); const path = __importStar(__nccwpck_require__(1017)); const core = __importStar(__nccwpck_require__(2186)); const fetch = __importStar(__nccwpck_require__(2387)); @@ -1279,6 +1283,26 @@ async function parseExtensionSource(extension, prefix) { return await joins('\nadd_extension_from_source', ...matches.splice(1, matches.length), prefix); } exports.parseExtensionSource = parseExtensionSource; +async function resolveVersion() { + let version = await getInput('php-version', false); + let versionFile = await getInput('php-version-file', false); + if (version) { + return version; + } + if (versionFile && !fs_1.default.existsSync(versionFile)) { + throw new Error(`Could not find '${versionFile}' file.`); + } + versionFile ??= '.php-version'; + if (fs_1.default.existsSync(versionFile)) { + version = fs_1.default.readFileSync(versionFile, 'utf8'); + core.info(`Resolved ${versionFile} as ${version}`); + } + if (!version) { + throw new Error("Neither 'php-version' nor 'php-version-file' inputs were supplied, and could not find '.php-version' file."); + } + return version; +} +exports.resolveVersion = resolveVersion; async function setVariable(variable, command, os) { switch (os) { case 'win32': diff --git a/src/install.ts b/src/install.ts index 4a09200d2..f298c6e49 100644 --- a/src/install.ts +++ b/src/install.ts @@ -24,7 +24,7 @@ export async function getScript(os: string): Promise { const coverage_driver: string = await utils.getInput('coverage', false); const tools_csv: string = await utils.getInput('tools', false); const version: string = await utils.parseVersion( - await utils.getInput('php-version', true) + await utils.resolveVersion() ); const ini_file: string = await utils.parseIniFile( await utils.getInput('ini-file', false) diff --git a/src/utils.ts b/src/utils.ts index 27d129934..8e4f3b6ef 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,3 +1,4 @@ +import fs from 'fs'; import * as path from 'path'; import * as core from '@actions/core'; import * as fetch from './fetch'; @@ -422,6 +423,37 @@ export async function parseExtensionSource( ); } +/** + * Resolve php version from input or file + */ +export async function resolveVersion(): Promise { + let version = await getInput('php-version', false); + let versionFile = await getInput('php-version-file', false); + + if (version) { + return version; + } + + if (versionFile && !fs.existsSync(versionFile)) { + throw new Error(`Could not find '${versionFile}' file.`); + } + + versionFile ??= '.php-version'; + + if (fs.existsSync(versionFile)) { + version = fs.readFileSync(versionFile, 'utf8'); + core.info(`Resolved ${versionFile} as ${version}`); + } + + if (!version) { + throw new Error( + "Neither 'php-version' nor 'php-version-file' inputs were supplied, and could not find '.php-version' file." + ); + } + + return version; +} + /** * Log to console *