From 4d3cfaa6531effaa5068d7e54df6037e96c09aa8 Mon Sep 17 00:00:00 2001 From: Shivam Mathur Date: Fri, 20 Aug 2021 09:14:39 +0530 Subject: [PATCH] Fixed support for php-cs-fixer Added fetch_latest to tools.json. When fetch_latest is true for a tool it will fetch the release.atom for the tool and parse that to get the latest release. Bumped lib version to ES2020 in tsconfig.json for string.matchAll. --- __tests__/tools.test.ts | 36 +++++++++++++++++++++++++++++++---- dist/index.js | 24 +++++++++++++++++++---- src/configs/tools.json | 1 + src/configs/tools_schema.json | 11 +++++++++++ src/tools.ts | 30 ++++++++++++++++++++++++++++- tsconfig.json | 2 +- 6 files changed, 94 insertions(+), 10 deletions(-) diff --git a/__tests__/tools.test.ts b/__tests__/tools.test.ts index ba2e707f0..a1d8bab4f 100644 --- a/__tests__/tools.test.ts +++ b/__tests__/tools.test.ts @@ -3,7 +3,7 @@ import * as utils from '../src/utils'; interface IData { tool: string; - version: string; + version?: string; domain?: string; extension?: string; os_version?: string; @@ -11,6 +11,7 @@ interface IData { release?: string; repository?: string; type?: string; + fetch_latest?: string; version_parameter?: string; version_prefix?: string; } @@ -18,7 +19,7 @@ interface IData { function getData(data: IData): Record { return { tool: data.tool, - version: data.version, + version: data.version || '', domain: data.domain || 'https://example.com', extension: data.extension || '.phar', os_version: data.os_version || 'linux', @@ -26,6 +27,7 @@ function getData(data: IData): Record { release: data.release || [data.tool, data.version].join(':'), repository: data.repository || '', type: data.type || 'phar', + fetch_latest: data.fetch_latest || 'false', version_parameter: data.version_parameter || '-V', version_prefix: data.version_prefix || '', github: 'https://github.com', @@ -38,7 +40,13 @@ jest .spyOn(utils, 'fetch') .mockImplementation( async (url: string, token?: string): Promise> => { - if (!token || token === 'valid_token') { + if (url.includes('atom') && !url.includes('no-release')) { + return { + data: '"releases/tag/1.2.3", "releases/tag/3.2.1", "releases/tag/2.3.1"' + }; + } else if (url.includes('no-release')) { + return {data: ''}; + } else if (!token || token === 'valid_token') { return {data: `[{"ref": "refs/tags/1.2.3", "url": "${url}"}]`}; } else if (token === 'beta_token') { return {data: `[{"ref": "refs/tags/1.2.3-beta1", "url": "${url}"}]`}; @@ -64,6 +72,26 @@ describe('Tools tests', () => { ).toBe(version); }); + it.each` + tool | fetch_latest | version + ${'tool'} | ${'true'} | ${'3.2.1'} + ${'tool-no-release'} | ${'true'} | ${'latest'} + ${'tool'} | ${'false'} | ${'latest'} + `( + 'checking getLatestVersion: $tool, $fetch_latest, $version', + async ({tool, fetch_latest, version}) => { + expect( + await tools.getLatestVersion( + getData({ + tool: tool, + repository: 'user/' + tool, + fetch_latest: fetch_latest + }) + ) + ).toBe(version); + } + ); + it.each` version | tool | type | expected ${'latest'} | ${'tool'} | ${'phar'} | ${'latest'} @@ -353,7 +381,7 @@ describe('Tools tests', () => { 'add_tool https://github.com/staabm/annotate-pull-request-from-checkstyle/releases/latest/download/cs2pr cs2pr "-V"', 'add_composertool flex flex symfony/', 'add_grpc_php_plugin latest', - 'add_tool https://github.com/FriendsOfPHP/PHP-CS-Fixer/releases/latest/download/php-cs-fixer.phar php-cs-fixer "-V"', + 'add_tool https://github.com/FriendsOfPHP/PHP-CS-Fixer/releases/download/v3.2.1/php-cs-fixer.phar php-cs-fixer "-V"', 'add_composertool phplint phplint overtrue/', 'add_tool https://github.com/phpstan/phpstan/releases/latest/download/phpstan.phar phpstan "-V"', 'add_tool https://phar.phpunit.de/phpunit.phar phpunit "--version"', diff --git a/dist/index.js b/dist/index.js index b6b0f5f4d..a93615fe1 100644 --- a/dist/index.js +++ b/dist/index.js @@ -493,7 +493,7 @@ var __importStar = (this && this.__importStar) || function (mod) { return result; }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.addTools = exports.functionRecord = exports.getData = exports.addWPCLI = exports.addSymfony = exports.addPHPUnitTools = exports.addPhive = exports.addPhing = exports.addPECL = exports.addDevTools = exports.addDeployer = exports.addComposer = exports.addBlackfirePlayer = exports.addPackage = exports.addArchive = exports.getPharUrl = exports.getUrl = exports.filterList = exports.getRelease = exports.getVersion = exports.getSemverVersion = void 0; +exports.addTools = exports.functionRecord = exports.getData = exports.addWPCLI = exports.addSymfony = exports.addPHPUnitTools = exports.addPhive = exports.addPhing = exports.addPECL = exports.addDevTools = exports.addDeployer = exports.addComposer = exports.addBlackfirePlayer = exports.addPackage = exports.addArchive = exports.getPharUrl = exports.getUrl = exports.filterList = exports.getRelease = exports.getVersion = exports.getLatestVersion = exports.getSemverVersion = void 0; const utils = __importStar(__nccwpck_require__(918)); async function getSemverVersion(data) { var _a; @@ -513,6 +513,19 @@ async function getSemverVersion(data) { } } exports.getSemverVersion = getSemverVersion; +async function getLatestVersion(data) { + if (!data['version'] && data['fetch_latest'] === 'false') { + return 'latest'; + } + const resp = await utils.fetch(`${data['github']}/${data['repository']}/releases.atom`); + const releases = [ + ...resp['data'].matchAll(/releases\/tag\/([a-zA-Z]*)?(\d+.\d+.\d+)"/g) + ].map(match => match[2]); + return (releases + .sort((a, b) => a.localeCompare(b, undefined, { numeric: true })) + .pop() || 'latest'); +} +exports.getLatestVersion = getLatestVersion; async function getVersion(version, data) { const semver_regex = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/; const composer_regex = /^composer:(stable|preview|snapshot|[1|2])$/; @@ -747,7 +760,7 @@ async function addWPCLI(data) { } exports.addWPCLI = addWPCLI; async function getData(release, php_version, os_version) { - var _a, _b, _c; + var _a, _b, _c, _d; const json_file = await utils.readFile('tools.json', 'src/configs'); const json_objects = JSON.parse(json_file); release = release.replace(/\s+/g, ''); @@ -783,10 +796,13 @@ async function getData(release, php_version, os_version) { data['php_version'] = php_version; data['prefix'] = data['github'] === data['domain'] ? 'releases' : ''; data['verb'] = data['github'] === data['domain'] ? 'download' : ''; + (_c = data['fetch_latest']) !== null && _c !== void 0 ? _c : (data['fetch_latest'] = 'false'); data['version_parameter'] = JSON.stringify(data['version_parameter']) || ''; - (_c = data['version_prefix']) !== null && _c !== void 0 ? _c : (data['version_prefix'] = ''); + (_d = data['version_prefix']) !== null && _d !== void 0 ? _d : (data['version_prefix'] = ''); data['release'] = await getRelease(release, data); - data['version'] = version ? await getVersion(version, data) : 'latest'; + data['version'] = version + ? await getVersion(version, data) + : await getLatestVersion(data); return data; } exports.getData = getData; diff --git a/src/configs/tools.json b/src/configs/tools.json index 37c8c162f..1b2b079e1 100644 --- a/src/configs/tools.json +++ b/src/configs/tools.json @@ -36,6 +36,7 @@ "repository": "FriendsOfPHP/PHP-CS-Fixer", "extension": ".phar", "domain": "https://github.com", + "fetch_latest": "true", "version_prefix": "v", "version_parameter": "-V" }, diff --git a/src/configs/tools_schema.json b/src/configs/tools_schema.json index 391844526..d8ac2fbd6 100644 --- a/src/configs/tools_schema.json +++ b/src/configs/tools_schema.json @@ -10,6 +10,7 @@ "alias": "tool_alias", "domain": "https://example.com", "extension": ".ext", + "fetch_latest": "true", "function": "function_name", "repository": "user/tool", "type": "phar, composer, custom-package or custom-function", @@ -47,6 +48,16 @@ ".ext" ] }, + "fetch_latest": { + "$id": "#/items/properties/fetch_latest", + "type": "string", + "title": "The fetch_latest schema", + "description": "Fetch the latest version from GitHub releases.", + "enum": [ + "true", + "false" + ] + }, "function": { "$id": "#/items/properties/function", "type": "string", diff --git a/src/tools.ts b/src/tools.ts index 03acb2327..607bb6ab0 100644 --- a/src/tools.ts +++ b/src/tools.ts @@ -31,6 +31,31 @@ export async function getSemverVersion(data: RS): Promise { } } +/** + * Function to get latest version from releases.atom + * + * @param data + */ +export async function getLatestVersion(data: RS): Promise { + if (!data['version'] && data['fetch_latest'] === 'false') { + return 'latest'; + } + const resp: Record = await utils.fetch( + `${data['github']}/${data['repository']}/releases.atom` + ); + const releases: string[] = [ + ...resp['data'].matchAll(/releases\/tag\/([a-zA-Z]*)?(\d+.\d+.\d+)"/g) + ].map(match => match[2]); + + return ( + releases + .sort((a: string, b: string) => + a.localeCompare(b, undefined, {numeric: true}) + ) + .pop() || 'latest' + ); +} + /** * Function to get tool version * @@ -423,10 +448,13 @@ export async function getData( data['php_version'] = php_version; data['prefix'] = data['github'] === data['domain'] ? 'releases' : ''; data['verb'] = data['github'] === data['domain'] ? 'download' : ''; + data['fetch_latest'] ??= 'false'; data['version_parameter'] = JSON.stringify(data['version_parameter']) || ''; data['version_prefix'] ??= ''; data['release'] = await getRelease(release, data); - data['version'] = version ? await getVersion(version, data) : 'latest'; + data['version'] = version + ? await getVersion(version, data) + : await getLatestVersion(data); return data; } diff --git a/tsconfig.json b/tsconfig.json index 4e6bddea0..1cc91ce18 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { "esModuleInterop": true, "lib": [ - "ES2019" + "ES2020" ], "module": "commonjs", "moduleResolution": "node",