From 46cb5030ab2adba881fd7dce301bbf59d4e2f0d3 Mon Sep 17 00:00:00 2001 From: Shivam Mathur Date: Wed, 21 Jan 2026 02:46:20 +0530 Subject: [PATCH] Replace generic record interfaces with specific ones --- __tests__/tools.test.ts | 116 ++++++---- dist/index.js | 2 +- src/tools.ts | 488 ++++++++++++++++++++++++---------------- 3 files changed, 376 insertions(+), 230 deletions(-) diff --git a/__tests__/tools.test.ts b/__tests__/tools.test.ts index 7759c53b..9d98b0b3 100644 --- a/__tests__/tools.test.ts +++ b/__tests__/tools.test.ts @@ -1,40 +1,33 @@ import * as fs from 'fs'; import * as tools from '../src/tools'; +import {ToolData, ToolInput} from '../src/tools'; -interface IData { - tool: string; - version?: string; - domain?: string; - extension?: string; - os?: string; - php_version?: string; - release?: string; - repository?: string; - scope?: string; - type?: string; - fetch_latest?: string; - version_parameter?: string; - version_prefix?: string; -} - -function getData(data: IData): Record { +function getData(data: Partial): ToolData { + const tool = data.tool || 'tool'; + const version = data.version || ''; return { - tool: data.tool, - version: data.version || '', + tool, + version, + url: data.url || '', domain: data.domain || 'https://example.com', extension: data.extension || '.phar', os: data.os || 'linux', php_version: data.php_version || '7.4', - release: data.release || [data.tool, data.version].join(':'), + release: data.release || [tool, version].join(':'), repository: data.repository || '', scope: data.scope || 'global', 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', - prefix: 'releases', - verb: 'download' + github: data.github || 'https://github.com', + prefix: data.prefix || 'releases', + verb: data.verb || 'download', + packagist: data.packagist || data.repository || '', + function: data.function, + alias: data.alias, + uri: data.uri, + error: data.error }; } @@ -161,6 +154,18 @@ describe('Tools tests', () => { } ); + it('checking getLatestVersion with fetch_latest=true but no repository', async () => { + expect( + await tools.getLatestVersion( + getData({ + tool: 'tool', + repository: '', + fetch_latest: 'true' + }) + ) + ).toBe('latest'); + }); + it.each` version | tool | type | expected ${'latest'} | ${'tool'} | ${'phar'} | ${'latest'} @@ -245,13 +250,15 @@ describe('Tools tests', () => { ); it('checking getUrl handles undefined version without double slash', async () => { - const data = getData({ - tool: 'cs2pr', - repository: 'staabm/annotate-pull-request-from-checkstyle', - domain: 'https://github.com' - }); - data['extension'] = ''; - delete data['version']; + const data: ToolInput = { + ...getData({ + tool: 'cs2pr', + repository: 'staabm/annotate-pull-request-from-checkstyle', + domain: 'https://github.com' + }), + version: undefined + }; + data.extension = ''; expect(await tools.getUrl(data)).toBe( 'https://github.com/staabm/annotate-pull-request-from-checkstyle/releases/download/cs2pr' ); @@ -284,9 +291,9 @@ describe('Tools tests', () => { tool: 'tool', version: 'latest', version_parameter: JSON.stringify('-v'), - os: os + os: os, + url: 'https://example.com/tool.phar' }); - data['url'] = 'https://example.com/tool.phar'; expect(await tools.addArchive(data)).toContain(script); }); @@ -649,14 +656,43 @@ describe('Tools tests', () => { expect(await tools.addTools(tools_csv, '7.4', 'linux')).toContain(script); }); - it.each` - tools_csv | token | script - ${'cs2pr:1.2'} | ${'invalid_token'} | ${'add_log "$cross" "cs2pr" "Invalid token"'} - ${'phpunit:1.2'} | ${'invalid_token'} | ${'add_log "$cross" "phpunit" "Invalid token"'} - ${'phpunit:0.1'} | ${'no_data'} | ${'add_log "$cross" "phpunit" "No version found with prefix 0.1."'} - `('checking error: $tools_csv', async ({tools_csv, token, script}) => { - process.env['GITHUB_TOKEN'] = token; - expect(await tools.addTools(tools_csv, '7.4', 'linux')).toContain(script); + it('checking error when custom-function tool is missing function field', async () => { + const brokenToolsJson = JSON.stringify({ + composer: { + type: 'custom-function', + domain: 'https://getcomposer.org', + repository: 'composer/composer', + function: 'composer' + }, + 'broken-tool': { + type: 'custom-function' + } + }); + + let result: string = ''; + await jest.isolateModulesAsync(async () => { + jest.doMock('fs', () => ({ + ...jest.requireActual('fs'), + readFileSync: ( + filePath: fs.PathOrFileDescriptor, + options?: unknown + ) => { + if (String(filePath).includes('tools.json')) { + return brokenToolsJson; + } + return (jest.requireActual('fs') as typeof fs).readFileSync( + filePath, + options as fs.ObjectEncodingOptions & {flag?: string} + ); + } + })); + const isolatedTools = await import('../src/tools'); + result = await isolatedTools.addTools('broken-tool', '7.4', 'linux'); + }); + + expect(result).toContain( + 'add_log "$cross" "broken-tool" "broken-tool has no function defined. Please report this issue."' + ); }); it.each` diff --git a/dist/index.js b/dist/index.js index cfdfbb46..cd1f1107 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1 +1 @@ -(()=>{var e={472:function(e,t,r){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;var i=Object.getOwnPropertyDescriptor(t,r);if(!i||("get"in i?!t.__esModule:i.writable||i.configurable)){i={enumerable:true,get:function(){return t[r]}}}Object.defineProperty(e,n,i)}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var s=this&&this.__importStar||function(){var ownKeys=function(e){ownKeys=Object.getOwnPropertyNames||function(e){var t=[];for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r))t[t.length]=r;return t};return ownKeys(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r=ownKeys(e),s=0;s/dev/null 2>&1'+r}async function addINIValuesWindows(e){const t=await o.CSVArray(e);let r="\n";await o.asyncForEach(t,(async function(e){r+=await o.addLog("$tick",e,"Added to php.ini","win32")+"\n"}));return'Add-Content "$php_dir\\php.ini" "'+t.join("\n")+'"'+r}async function addINIValues(e,t,r=false){let n="\n";switch(r){case true:n+=await o.stepLog("Add php.ini values",t)+await o.suppressOutput(t)+"\n";break;case false:default:n+=await o.stepLog("Add php.ini values",t)+"\n";break}switch(t){case"win32":return n+await addINIValuesWindows(e);case"darwin":case"linux":return n+await addINIValuesUnix(e);default:return await o.log("Platform "+t+" is not supported",t,"error")}}},469:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t.issueCommand=issueCommand;t.error=error;t.setFailed=setFailed;t.getInput=getInput;const n=r(857);function toCommandValue(e){if(e instanceof Error){return e.toString()}return e}function escapeData(e){return toCommandValue(e).replace(/%/g,"%25").replace(/\r/g,"%0D").replace(/\n/g,"%0A")}function escapeProperty(e){return e.replace(/%/g,"%25").replace(/\r/g,"%0D").replace(/\n/g,"%0A").replace(/:/g,"%3A").replace(/,/g,"%2C")}function issueCommand(e,t,r){let i=`::${e}`;if(t&&Object.keys(t).length>0){i+=" ";const e=Object.entries(t).filter((([,e])=>e)).map((([e,t])=>`${e}=${escapeProperty(t)}`)).join(",");i+=e}i+=`::${escapeData(r)}`;process.stdout.write(i+n.EOL)}function error(e){issueCommand("error",{},e)}function setFailed(e){process.exitCode=1;error(e)}function getInput(e,t=false){const r=process.env[`INPUT_${e.replace(/ /g,"_").toUpperCase()}`]||"";if(t&&!r){throw new Error(`Input required and not supplied: ${e}`)}return r.trim()}},524:function(e,t,r){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;var i=Object.getOwnPropertyDescriptor(t,r);if(!i||("get"in i?!t.__esModule:i.writable||i.configurable)){i={enumerable:true,get:function(){return t[r]}}}Object.defineProperty(e,n,i)}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var s=this&&this.__importStar||function(){var ownKeys=function(e){ownKeys=Object.getOwnPropertyNames||function(e){var t=[];for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r))t[t.length]=r;return t};return ownKeys(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r=ownKeys(e),s=0;s{"use strict";Object.defineProperty(t,"__esModule",{value:true});t.fetch=fetch;const r=new Set([301,302,303,307,308]);async function fetch(e,t,n=5){const i={"User-Agent":`Mozilla/5.0 (${process.platform} ${process.arch}) setup-php`};if(t){i["Authorization"]="Bearer "+t}try{const t=await globalThis.fetch(e,{headers:i,redirect:n>0?"follow":"manual"});if(t.ok){const e=await t.text();return{data:e}}else if(r.has(t.status)&&n<=0){return{error:`${t.status}: Redirect error`}}else{return{error:`${t.status}: ${t.statusText}`}}}catch(e){return{error:`Fetch error: ${e.message}`}}}},755:function(e,t,r){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;var i=Object.getOwnPropertyDescriptor(t,r);if(!i||("get"in i?!t.__esModule:i.writable||i.configurable)){i={enumerable:true,get:function(){return t[r]}}}Object.defineProperty(e,n,i)}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var s=this&&this.__importStar||function(){var ownKeys=function(e){ownKeys=Object.getOwnPropertyNames||function(e){var t=[];for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r))t[t.length]=r;return t};return ownKeys(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r=ownKeys(e),s=0;s{await run()})().catch((e=>{l.setFailed(e.message)}))},75:function(e,t,r){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;var i=Object.getOwnPropertyDescriptor(t,r);if(!i||("get"in i?!t.__esModule:i.writable||i.configurable)){i={enumerable:true,get:function(){return t[r]}}}Object.defineProperty(e,n,i)}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var s=this&&this.__importStar||function(){var ownKeys=function(e){ownKeys=Object.getOwnPropertyNames||function(e){var t=[];for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r))t[t.length]=r;return t};return ownKeys(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r=ownKeys(e),s=0;so.compareVersions(t.version,e.version)));const i=r.find((e=>{if(e?.require?.php){return e?.require?.php.split("|").some((e=>e&&o.satisfies(t+".0",e)))}return false}));return i?i.version:null}return null}},159:function(e,t,r){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;var i=Object.getOwnPropertyDescriptor(t,r);if(!i||("get"in i?!t.__esModule:i.writable||i.configurable)){i={enumerable:true,get:function(){return t[r]}}}Object.defineProperty(e,n,i)}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var s=this&&this.__importStar||function(){var ownKeys=function(e){ownKeys=Object.getOwnPropertyNames||function(e){var t=[];for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r))t[t.length]=r;return t};return ownKeys(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r=ownKeys(e),s=0;s{if(/^\d+\.\d+\.\d+(-|$)/.test(e))return e;const t=e.match(/^(\d+\.\d+\.\d+)([A-Za-z]+[0-9A-Za-z.]+)$/);return t?`${t[1]}-${t[2]}`:e};const t=e["version_prefix"]+e["version"];const r=`https://api.github.com/repos/${e["repository"]}/git/matching-refs/tags%2F${t}.`;const n=await f.readEnv("GITHUB_TOKEN")||await f.readEnv("COMPOSER_TOKEN");const i=await d.fetch(r,n);if(i.error||i.data==="[]"){e["error"]=i.error??`No version found with prefix ${t}.`;return e["version"]}else{const e=JSON.parse(i["data"]);const t=e.map((e=>(e.ref?.split("/").pop()??"").replace(/^v(?=\d)/,""))).filter((e=>e.length>0));const r=new Map;const n=t.map((e=>{const t=fixSemver(e);r.set(t,e);return t}));const s=n.toSorted(((e,t)=>{try{return u.compareVersions(t,e)}catch{return t.localeCompare(e,"en",{numeric:true,sensitivity:"base"})}}));return r.get(s[0])??s[0]}}async function getLatestVersion(e){if(!e["version"]&&e["fetch_latest"]==="false"){return"latest"}const t=await d.fetch(`${e["github"]}/${e["repository"]}/releases.atom`);if(t["data"]){const e=[...t["data"].matchAll(/releases\/tag\/([a-zA-Z]*)?(\d+.\d+.\d+)"/g)].map((e=>e[2]));const r=e.toSorted(((e,t)=>e.localeCompare(t,undefined,{numeric:true})));return r.at(-1)||"latest"}return"latest"}async function getVersion(e,t){const r=/^(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 n=/^composer:(stable|preview|snapshot|[1|2])$/;const i=/[><=^~]+.*/;const s=/^\d+(\.\d+)?$/;t["version"]=e.replace(/v?(\d)/,"$1").replace(/\.x/,"");switch(true){case n.test(t["release"]):case r.test(t["version"]):case i.test(t["version"])&&t["type"]==="composer":return t["version"];case s.test(t["version"])&&t["type"]==="composer":t["release"]=`${t["tool"]}:${t["version"]}.*`;return`${t["version"]}.*`;case t["repository"]&&s.test(t["version"]):return await getSemverVersion(t);default:return t["version"].replace(/[><=^~]*/,"")}}async function getRelease(e,t){e=e.includes("/")?e.split("/")[1]:e;return e.includes(":")?[t["tool"],e.split(":")[1]].join(":"):t["tool"]}async function filterList(e){const t=/^composer($|:.*)/;const r=/^composer:?($|preview$|snapshot$|v?\d+(\.\d+)?$|v?\d+\.\d+\.\d+[\w-]*$)/;const n=e.filter((e=>r.test(e)));let i="composer";e=e.filter((e=>!t.test(e)));switch(true){case n[0]==undefined:break;default:i=n.at(-1).replace(/v(\d\S*)/,"$1");break}e.unshift(i);return e}async function getUrl(e){if((e["version"]??"latest")==="latest"){return[e["domain"],e["repository"],e["prefix"],e["version"],e["verb"],e["tool"]+e["extension"]].filter(Boolean).join("/")}else{return[e["domain"],e["repository"],e["prefix"],e["verb"],e["version_prefix"]+e["version"],e["tool"]+e["extension"]].filter(Boolean).join("/")}}async function getPharUrl(e){if(e["version"]==="latest"){return e["domain"]+"/"+e["tool"]+".phar"}else{return e["domain"]+"/"+e["tool"]+"-"+e["version_prefix"]+e["version"]+".phar"}}async function addArchive(e){return await f.getCommand(e["os"],"tool")+await f.joins(e["url"],e["tool"],e["version_parameter"])}async function addPackage(e){const t=await f.getCommand(e["os"],"composer_tool");const r=e["repository"].split("/");const n=await f.joins(r[1],e["release"],r[0]+"/",e["scope"]);return t+n}async function addBlackfirePlayer(e){switch(e["os"]){case"win32":return await f.addLog("$cross",e["tool"],e["tool"]+" is not a windows tool","win32");default:if(e["version"]=="latest"){if(/5\.[5-6]|7\.0/.test(e["php_version"])){e["version"]="1.9.3"}else if(/7\.[1-4]|8\.0/.test(e["php_version"])){e["version"]="1.22.0"}}e["url"]=await getPharUrl(e);return addArchive(e)}}async function addCastor(e){e["tool"]="castor."+e["os"].replace("win32","windows")+"-amd64";e["url"]=await getUrl(e);e["tool"]="castor";e["version_parameter"]=c.default.existsSync("castor.php")?e["version_parameter"]:"";return await addArchive(e)}async function addComposer(e){const t=e["version"].replace("latest","stable");const r=e["github"];const n=e["domain"];const i="https://dl.cloudsmith.io";const s="https://artifacts.setup-php.com";const o=`composer-${e["php_version"]}-${t}.phar`;const a=`${r}/shivammathur/composer-cache/releases/latest/download/${o}`;const c=`${i}/public/shivammathur/composer-cache/raw/files/${o}`;const u=`${s}/composer/${o}`;const d=`${n}/download/latest-2.2.x/composer.phar`;const l=/^5\.[3-6]$|^7\.[0-1]$/.test(e["php_version"]);const p=`${n}/composer-${t}.phar`;const h=`${n}/download/${t}/composer.phar`;let g=`${a},${u},${c}`;let w=`${n}/composer.phar`;switch(true){case/^snapshot$/.test(t):w=l?d:w;break;case/^preview$|^2$/.test(t):w=l?d:p;break;case/^1$/.test(t):w=p;break;case/^\d+\.\d+\.\d+[\w-]*$/.test(e["version"]):g=`${r}/${e["repository"]}/releases/download/${e["version"]}/composer.phar`;w=h;break;default:w=l?d:p}const v=await f.readEnv("NO_TOOLS_CACHE")!=="true";e["url"]=v?`${g},${w}`:w;e["version_parameter"]=e["version"];return await addArchive(e)}async function addDeployer(e){if(e["version"]==="latest"){e["url"]=e["domain"]+"/deployer.phar"}else{const t=await d.fetch("https://deployer.org/manifest.json");const r=JSON.parse(t.data);const n=Object.keys(r).find((t=>r[t]["version"]===e["version"]));if(n){e["url"]=r[n]["url"]}else{return await f.addLog("$cross","deployer","Version missing in deployer manifest",e["os"])}}return await addArchive(e)}async function addDevTools(e){switch(e["os"]){case"linux":case"darwin":return"add_devtools "+e["tool"];case"win32":return await f.addLog("$tick",e["tool"],e["tool"]+" is not a windows tool","win32");default:return await f.log("Platform "+e["os"]+" is not supported",e["os"],"error")}}async function addPECL(e){return await f.getCommand(e["os"],"pecl")}async function addPhing(e){e["url"]=e["domain"]+"/get/phing-"+e["version"]+e["extension"];if(e["version"]!="latest"){[e["prefix"],e["verb"]]=["releases","download"];e["domain"]=e["github"];e["extension"]="-"+e["version"]+e["extension"];e["url"]+=","+await getUrl(e)}return await addArchive(e)}async function addPhive(e){switch(true){case/5\.[3-5]/.test(e["php_version"]):return await f.addLog("$cross","phive","Phive is not supported on PHP "+e["php_version"],e["os"]);case/5\.6|7\.0/.test(e["php_version"]):e["version"]="0.12.1";break;case/7\.1/.test(e["php_version"]):e["version"]="0.13.5";break;case/7\.2/.test(e["php_version"]):e["version"]="0.14.5";break;case/7\.3|7\.4/.test(e["php_version"]):e["version"]="0.15.3";break;case/^latest$/.test(e["version"]):e["version"]=await getLatestVersion(e);break}e["extension"]="-"+e["version"]+e["extension"];e["url"]=await getUrl(e);return await addArchive(e)}async function addPHPUnitTools(e){if(e["version"]==="latest"){e["version"]=await l.search(e["packagist"],e["php_version"])??"latest"}e["url"]=await getPharUrl(e);if(e["url"].match(/-\d+/)){e["url"]+=","+e["url"].replace(/-(\d+)\.\d+\.\d+/,"-$1")}return await addArchive(e)}async function addWPCLI(e){if(e["version"]==="latest"){e["uri"]="wp-cli/builds/blob/gh-pages/phar/wp-cli.phar?raw=true";e["url"]=[e["domain"],e["uri"]].join("/")}else{e["extension"]="-"+e["version"]+e["extension"];e["url"]=await getUrl(e)}return await addArchive(e)}async function getData(e,t,r){const n=a.default.join(__dirname,"../src/configs/tools.json");const i=c.default.readFileSync(n,"utf8");const s=JSON.parse(i);e=e.replace(/\s+/g,"");const o=e.split(":");const u=o[0];const d=o[1];let l;if(Object.hasOwn(s,u)){l=s[u];l["tool"]=u}else{const e=Object.keys(s).find((e=>s[e]["alias"]==u));if(e){l=s[e];l["tool"]=e}else{l={tool:u.split("/")[1],repository:u,type:"composer"};l=!u.includes("/")?{tool:u}:l}}l["github"]="https://github.com";l["domain"]??=l["github"];l["extension"]??=".phar";l["os"]=r;l["php_version"]=t;l["packagist"]??=l["repository"];l["prefix"]=l["github"]===l["domain"]?"releases":"";l["verb"]=l["github"]===l["domain"]?"download":"";l["fetch_latest"]??="false";l["scope"]??="global";l["version_parameter"]=JSON.stringify(l["version_parameter"])||"";l["version_prefix"]??="";l["release"]=await getRelease(e,l);l["version"]=d?await getVersion(d,l):await getLatestVersion(l);return l}t.functionRecord={castor:addCastor,composer:addComposer,deployer:addDeployer,dev_tools:addDevTools,phive:addPhive,blackfire_player:addBlackfirePlayer,pecl:addPECL,phing:addPhing,phpunit:addPHPUnitTools,phpcpd:addPHPUnitTools,wp_cli:addWPCLI};async function addTools(e,r,n){let i="\n";if(e==="none"){return""}else{i+=await f.stepLog("Setup Tools",n)}const s=await filterList(await f.CSVArray(e));await f.asyncForEach(s,(async function(e){const s=await getData(e,r,n);i+="\n";switch(true){case s["error"]!==undefined:i+=await f.addLog("$cross",s["tool"],s["error"],s["os"]);break;case"phar"===s["type"]:s["url"]=await getUrl(s);i+=await addArchive(s);break;case"composer"===s["type"]:i+=await addPackage(s);break;case"custom-package"===s["type"]:i+=await f.customPackage(s["tool"].split("-")[0],"tools",s["version"],s["os"]);break;case"custom-function"===s["type"]:i+=await t.functionRecord[s["function"]](s);break;case/^none$/.test(s["tool"]):break;default:i+=await f.addLog("$cross",s["tool"],"Tool "+s["tool"]+" is not supported",s["os"]);break}}));return i}},277:function(e,t,r){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;var i=Object.getOwnPropertyDescriptor(t,r);if(!i||("get"in i?!t.__esModule:i.writable||i.configurable)){i={enumerable:true,get:function(){return t[r]}}}Object.defineProperty(e,n,i)}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var s=this&&this.__importStar||function(){var ownKeys=function(e){ownKeys=Object.getOwnPropertyNames||function(e){var t=[];for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r))t[t.length]=r;return t};return ownKeys(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r=ownKeys(e),s=0;s1:return e.slice(0,3);default:return e+".0"}}}async function parseIniFile(e){switch(true){case/^(production|development|none)$/.test(e):return e;case/php\.ini-(production|development)$/.test(e):return e.split("-")[1];default:return"production"}}async function asyncForEach(e,t){for(const[r,n]of e.entries()){await t(n,r,e)}}async function color(e){switch(e){case"error":return"31";default:case"success":return"32";case"warning":return"33"}}async function log(e,t,r){switch(t){case"win32":return'printf "\\033['+await color(r)+";1m"+e+' \\033[0m"';case"linux":case"darwin":default:return'echo "\\033['+await color(r)+";1m"+e+'\\033[0m"'}}async function stepLog(e,t){switch(t){case"win32":return'Step-Log "'+e+'"';case"linux":case"darwin":return'step_log "'+e+'"';default:return await log("Platform "+t+" is not supported",t,"error")}}async function addLog(e,t,r,n){switch(n){case"win32":return'Add-Log "'+e+'" "'+t+'" "'+r+'"';case"linux":case"darwin":return'add_log "'+e+'" "'+t+'" "'+r+'"';default:return await log("Platform "+n+" is not supported",n,"error")}}async function extensionArray(e){switch(e){case"":case" ":return[];default:return[e.match(/(^|,\s?)none(\s?,|$)/)?"none":"",...e.split(",").map((function(e){if(/.+-.+\/.+@.+/.test(e)){return e}return e.trim().toLowerCase().replace(/^(:)?(php[-_]|none|zend )|(-[^-]*)-/,"$1$3")}))].filter(Boolean)}}async function CSVArray(e){switch(e){case"":case" ":return[];default:return e.split(/,(?=(?:(?:[^"']*["']){2})*[^"']*$)/).map((function(e){return e.trim().replace(/^["']|["']$|(?<==)["']/g,"").replace(/=(((?!E_).)*[?{}|&~![()^]+((?!E_).)+)/,"='$1'").replace(/=(.*?)(=.*)/,"='$1$2'").replace(/:\s*["'](.*?)/g,":$1")})).filter(Boolean)}}async function getExtensionPrefix(e){switch(true){default:return"extension";case/xdebug([2-3])?$|opcache|ioncube|eaccelerator/.test(e):return"zend_extension"}}async function suppressOutput(e){switch(e){case"win32":return" >$null 2>&1";case"linux":case"darwin":return" >/dev/null 2>&1";default:return await log("Platform "+e+" is not supported",e,"error")}}async function getUnsupportedLog(e,t,r){return"\n"+await addLog("$cross",e,[e,"is not supported on PHP",t].join(" "),r)+"\n"}async function getCommand(e,t){switch(e){case"linux":case"darwin":return"add_"+t+" ";case"win32":return"Add-"+t.split("_").map((e=>e.charAt(0).toUpperCase()+e.slice(1))).join("")+" ";default:return await log("Platform "+e+" is not supported",e,"error")}}async function joins(...e){return[...e].join(" ")}async function scriptExtension(e){switch(e){case"win32":return".ps1";case"linux":case"darwin":return".sh";default:return await log("Platform "+e+" is not supported",e,"error")}}async function scriptTool(e){switch(e){case"win32":return"pwsh ";case"linux":case"darwin":return"bash ";default:return await log("Platform "+e+" is not supported",e,"error")}}async function customPackage(e,t,r,n){const i=e.replace(/\d+|(pdo|pecl)[_-]|[_-]db2/,"");const s=await scriptExtension(n);const o=c.join(__dirname,"../src/scripts/"+t+"/"+i+s);const a=await getCommand(n,i);return"\n. "+o+"\n"+a+r}async function parseExtensionSource(e,t){const r=/(\w+)-(\w+:\/\/.{1,253}(?:[.:][^:/\s]{2,63})+\/)?([\w.-]+)\/([\w.-]+)@(.+)/;const n=r.exec(e);n[2]=n[2]?n[2].slice(0,-1):"https://github.com";return await joins("\nadd_extension_from_source",...n.splice(1,n.length),t)}async function readPHPVersion(){const e=await getInput("php-version",false);if(e){return e}const t=await getInput("php-version-file",false)||".php-version";if(a.default.existsSync(t)){const e=a.default.readFileSync(t,"utf8");const r=e.match(/^(?:php\s)?(\d+\.\d+\.\d+)$/m);return r?r[1]:e.trim()}else if(t!==".php-version"){throw new Error(`Could not find '${t}' file.`)}const r=await readEnv("COMPOSER_PROJECT_DIR");const n=c.join(r,"composer.lock");if(a.default.existsSync(n)){const e=JSON.parse(a.default.readFileSync(n,"utf8"));if(e["platform-overrides"]&&e["platform-overrides"]["php"]){return e["platform-overrides"]["php"]}}const i=c.join(r,"composer.json");if(a.default.existsSync(i)){const e=JSON.parse(a.default.readFileSync(i,"utf8"));if(e["config"]&&e["config"]["platform"]&&e["config"]["platform"]["php"]){return e["config"]["platform"]["php"]}}return"latest"}async function setVariable(e,t,r){switch(r){case"win32":return"\n$"+e+" = "+t+"\n";case"linux":case"darwin":default:return"\n"+e+'="$('+t+')"\n'}}},236:function(e,t,r){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;Object.defineProperty(e,n,{enumerable:true,get:function(){return t[r]}})}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var s=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r in e)if(r!=="default"&&Object.hasOwnProperty.call(e,r))n(t,e,r);i(t,e);return t};var o=this&&this.__awaiter||function(e,t,r,n){function adopt(e){return e instanceof r?e:new r((function(t){t(e)}))}return new(r||(r=Promise))((function(r,i){function fulfilled(e){try{step(n.next(e))}catch(e){i(e)}}function rejected(e){try{step(n["throw"](e))}catch(e){i(e)}}function step(e){e.done?r(e.value):adopt(e.value).then(fulfilled,rejected)}step((n=n.apply(e,t||[])).next())}))};Object.defineProperty(t,"__esModule",{value:true});t.getExecOutput=t.exec=void 0;const a=r(193);const c=s(r(665));function exec(e,t,r){return o(this,void 0,void 0,(function*(){const n=c.argStringToArray(e);if(n.length===0){throw new Error(`Parameter 'commandLine' cannot be null or empty.`)}const i=n[0];t=n.slice(1).concat(t||[]);const s=new c.ToolRunner(i,t,r);return s.exec()}))}t.exec=exec;function getExecOutput(e,t,r){var n,i;return o(this,void 0,void 0,(function*(){let s="";let o="";const c=new a.StringDecoder("utf8");const u=new a.StringDecoder("utf8");const d=(n=r===null||r===void 0?void 0:r.listeners)===null||n===void 0?void 0:n.stdout;const l=(i=r===null||r===void 0?void 0:r.listeners)===null||i===void 0?void 0:i.stderr;const stdErrListener=e=>{o+=u.write(e);if(l){l(e)}};const stdOutListener=e=>{s+=c.write(e);if(d){d(e)}};const f=Object.assign(Object.assign({},r===null||r===void 0?void 0:r.listeners),{stdout:stdOutListener,stderr:stdErrListener});const p=yield exec(e,t,Object.assign(Object.assign({},r),{listeners:f}));s+=c.end();o+=u.end();return{exitCode:p,stdout:s,stderr:o}}))}t.getExecOutput=getExecOutput},665:function(e,t,r){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;Object.defineProperty(e,n,{enumerable:true,get:function(){return t[r]}})}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var s=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r in e)if(r!=="default"&&Object.hasOwnProperty.call(e,r))n(t,e,r);i(t,e);return t};var o=this&&this.__awaiter||function(e,t,r,n){function adopt(e){return e instanceof r?e:new r((function(t){t(e)}))}return new(r||(r=Promise))((function(r,i){function fulfilled(e){try{step(n.next(e))}catch(e){i(e)}}function rejected(e){try{step(n["throw"](e))}catch(e){i(e)}}function step(e){e.done?r(e.value):adopt(e.value).then(fulfilled,rejected)}step((n=n.apply(e,t||[])).next())}))};Object.defineProperty(t,"__esModule",{value:true});t.argStringToArray=t.ToolRunner=void 0;const a=s(r(857));const c=s(r(434));const u=s(r(317));const d=s(r(928));const l=s(r(191));const f=s(r(120));const p=r(557);const h=process.platform==="win32";class ToolRunner extends c.EventEmitter{constructor(e,t,r){super();if(!e){throw new Error("Parameter 'toolPath' cannot be null or empty.")}this.toolPath=e;this.args=t||[];this.options=r||{}}_debug(e){if(this.options.listeners&&this.options.listeners.debug){this.options.listeners.debug(e)}}_getCommandString(e,t){const r=this._getSpawnFileName();const n=this._getSpawnArgs(e);let i=t?"":"[command]";if(h){if(this._isCmdFile()){i+=r;for(const e of n){i+=` ${e}`}}else if(e.windowsVerbatimArguments){i+=`"${r}"`;for(const e of n){i+=` ${e}`}}else{i+=this._windowsQuoteCmdArg(r);for(const e of n){i+=` ${this._windowsQuoteCmdArg(e)}`}}}else{i+=r;for(const e of n){i+=` ${e}`}}return i}_processLineBuffer(e,t,r){try{let n=t+e.toString();let i=n.indexOf(a.EOL);while(i>-1){const e=n.substring(0,i);r(e);n=n.substring(i+a.EOL.length);i=n.indexOf(a.EOL)}return n}catch(e){this._debug(`error processing line. Failed with error ${e}`);return""}}_getSpawnFileName(){if(h){if(this._isCmdFile()){return process.env["COMSPEC"]||"cmd.exe"}}return this.toolPath}_getSpawnArgs(e){if(h){if(this._isCmdFile()){let t=`/D /S /C "${this._windowsQuoteCmdArg(this.toolPath)}`;for(const r of this.args){t+=" ";t+=e.windowsVerbatimArguments?r:this._windowsQuoteCmdArg(r)}t+='"';return[t]}}return this.args}_endsWith(e,t){return e.endsWith(t)}_isCmdFile(){const e=this.toolPath.toUpperCase();return this._endsWith(e,".CMD")||this._endsWith(e,".BAT")}_windowsQuoteCmdArg(e){if(!this._isCmdFile()){return this._uvQuoteCmdArg(e)}if(!e){return'""'}const t=[" ","\t","&","(",")","[","]","{","}","^","=",";","!","'","+",",","`","~","|","<",">",'"'];let r=false;for(const n of e){if(t.some((e=>e===n))){r=true;break}}if(!r){return e}let n='"';let i=true;for(let t=e.length;t>0;t--){n+=e[t-1];if(i&&e[t-1]==="\\"){n+="\\"}else if(e[t-1]==='"'){i=true;n+='"'}else{i=false}}n+='"';return n.split("").reverse().join("")}_uvQuoteCmdArg(e){if(!e){return'""'}if(!e.includes(" ")&&!e.includes("\t")&&!e.includes('"')){return e}if(!e.includes('"')&&!e.includes("\\")){return`"${e}"`}let t='"';let r=true;for(let n=e.length;n>0;n--){t+=e[n-1];if(r&&e[n-1]==="\\"){t+="\\"}else if(e[n-1]==='"'){r=true;t+="\\"}else{r=false}}t+='"';return t.split("").reverse().join("")}_cloneExecOptions(e){e=e||{};const t={cwd:e.cwd||process.cwd(),env:e.env||process.env,silent:e.silent||false,windowsVerbatimArguments:e.windowsVerbatimArguments||false,failOnStdErr:e.failOnStdErr||false,ignoreReturnCode:e.ignoreReturnCode||false,delay:e.delay||1e4};t.outStream=e.outStream||process.stdout;t.errStream=e.errStream||process.stderr;return t}_getSpawnOptions(e,t){e=e||{};const r={};r.cwd=e.cwd;r.env=e.env;r["windowsVerbatimArguments"]=e.windowsVerbatimArguments||this._isCmdFile();if(e.windowsVerbatimArguments){r.argv0=`"${t}"`}return r}exec(){return o(this,void 0,void 0,(function*(){if(!f.isRooted(this.toolPath)&&(this.toolPath.includes("/")||h&&this.toolPath.includes("\\"))){this.toolPath=d.resolve(process.cwd(),this.options.cwd||process.cwd(),this.toolPath)}this.toolPath=yield l.which(this.toolPath,true);return new Promise(((e,t)=>o(this,void 0,void 0,(function*(){this._debug(`exec tool: ${this.toolPath}`);this._debug("arguments:");for(const e of this.args){this._debug(` ${e}`)}const r=this._cloneExecOptions(this.options);if(!r.silent&&r.outStream){r.outStream.write(this._getCommandString(r)+a.EOL)}const n=new ExecState(r,this.toolPath);n.on("debug",(e=>{this._debug(e)}));if(this.options.cwd&&!(yield f.exists(this.options.cwd))){return t(new Error(`The cwd: ${this.options.cwd} does not exist!`))}const i=this._getSpawnFileName();const s=u.spawn(i,this._getSpawnArgs(r),this._getSpawnOptions(this.options,i));let o="";if(s.stdout){s.stdout.on("data",(e=>{if(this.options.listeners&&this.options.listeners.stdout){this.options.listeners.stdout(e)}if(!r.silent&&r.outStream){r.outStream.write(e)}o=this._processLineBuffer(e,o,(e=>{if(this.options.listeners&&this.options.listeners.stdline){this.options.listeners.stdline(e)}}))}))}let c="";if(s.stderr){s.stderr.on("data",(e=>{n.processStderr=true;if(this.options.listeners&&this.options.listeners.stderr){this.options.listeners.stderr(e)}if(!r.silent&&r.errStream&&r.outStream){const t=r.failOnStdErr?r.errStream:r.outStream;t.write(e)}c=this._processLineBuffer(e,c,(e=>{if(this.options.listeners&&this.options.listeners.errline){this.options.listeners.errline(e)}}))}))}s.on("error",(e=>{n.processError=e.message;n.processExited=true;n.processClosed=true;n.CheckComplete()}));s.on("exit",(e=>{n.processExitCode=e;n.processExited=true;this._debug(`Exit code ${e} received from tool '${this.toolPath}'`);n.CheckComplete()}));s.on("close",(e=>{n.processExitCode=e;n.processExited=true;n.processClosed=true;this._debug(`STDIO streams have closed for tool '${this.toolPath}'`);n.CheckComplete()}));n.on("done",((r,n)=>{if(o.length>0){this.emit("stdline",o)}if(c.length>0){this.emit("errline",c)}s.removeAllListeners();if(r){t(r)}else{e(n)}}));if(this.options.input){if(!s.stdin){throw new Error("child process missing stdin")}s.stdin.end(this.options.input)}}))))}))}}t.ToolRunner=ToolRunner;function argStringToArray(e){const t=[];let r=false;let n=false;let i="";function append(e){if(n&&e!=='"'){i+="\\"}i+=e;n=false}for(let s=0;s0){t.push(i);i=""}continue}append(o)}if(i.length>0){t.push(i.trim())}return t}t.argStringToArray=argStringToArray;class ExecState extends c.EventEmitter{constructor(e,t){super();this.processClosed=false;this.processError="";this.processExitCode=0;this.processExited=false;this.processStderr=false;this.delay=1e4;this.done=false;this.timeout=null;if(!t){throw new Error("toolPath must not be empty")}this.options=e;this.toolPath=t;if(e.delay){this.delay=e.delay}}CheckComplete(){if(this.done){return}if(this.processClosed){this._setResult()}else if(this.processExited){this.timeout=p.setTimeout(ExecState.HandleTimeout,this.delay,this)}}_debug(e){this.emit("debug",e)}_setResult(){let e;if(this.processExited){if(this.processError){e=new Error(`There was an error when attempting to execute the process '${this.toolPath}'. This may indicate the process failed to start. Error: ${this.processError}`)}else if(this.processExitCode!==0&&!this.options.ignoreReturnCode){e=new Error(`The process '${this.toolPath}' failed with exit code ${this.processExitCode}`)}else if(this.processStderr&&this.options.failOnStdErr){e=new Error(`The process '${this.toolPath}' failed because one or more lines were written to the STDERR stream`)}}if(this.timeout){clearTimeout(this.timeout);this.timeout=null}this.done=true;this.emit("done",e,this.processExitCode)}static HandleTimeout(e){if(e.done){return}if(!e.processClosed&&e.processExited){const t=`The STDIO streams did not close within ${e.delay/1e3} seconds of the exit event from process '${e.toolPath}'. This may indicate a child process inherited the STDIO streams and has not yet exited.`;e._debug(t)}e._setResult()}}},120:function(e,t,r){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;Object.defineProperty(e,n,{enumerable:true,get:function(){return t[r]}})}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var s=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r in e)if(r!=="default"&&Object.hasOwnProperty.call(e,r))n(t,e,r);i(t,e);return t};var o=this&&this.__awaiter||function(e,t,r,n){function adopt(e){return e instanceof r?e:new r((function(t){t(e)}))}return new(r||(r=Promise))((function(r,i){function fulfilled(e){try{step(n.next(e))}catch(e){i(e)}}function rejected(e){try{step(n["throw"](e))}catch(e){i(e)}}function step(e){e.done?r(e.value):adopt(e.value).then(fulfilled,rejected)}step((n=n.apply(e,t||[])).next())}))};var a;Object.defineProperty(t,"__esModule",{value:true});t.getCmdPath=t.tryGetExecutablePath=t.isRooted=t.isDirectory=t.exists=t.READONLY=t.UV_FS_O_EXLOCK=t.IS_WINDOWS=t.unlink=t.symlink=t.stat=t.rmdir=t.rm=t.rename=t.readlink=t.readdir=t.open=t.mkdir=t.lstat=t.copyFile=t.chmod=void 0;const c=s(r(896));const u=s(r(928));a=c.promises,t.chmod=a.chmod,t.copyFile=a.copyFile,t.lstat=a.lstat,t.mkdir=a.mkdir,t.open=a.open,t.readdir=a.readdir,t.readlink=a.readlink,t.rename=a.rename,t.rm=a.rm,t.rmdir=a.rmdir,t.stat=a.stat,t.symlink=a.symlink,t.unlink=a.unlink;t.IS_WINDOWS=process.platform==="win32";t.UV_FS_O_EXLOCK=268435456;t.READONLY=c.constants.O_RDONLY;function exists(e){return o(this,void 0,void 0,(function*(){try{yield t.stat(e)}catch(e){if(e.code==="ENOENT"){return false}throw e}return true}))}t.exists=exists;function isDirectory(e,r=false){return o(this,void 0,void 0,(function*(){const n=r?yield t.stat(e):yield t.lstat(e);return n.isDirectory()}))}t.isDirectory=isDirectory;function isRooted(e){e=normalizeSeparators(e);if(!e){throw new Error('isRooted() parameter "p" cannot be empty')}if(t.IS_WINDOWS){return e.startsWith("\\")||/^[A-Z]:/i.test(e)}return e.startsWith("/")}t.isRooted=isRooted;function tryGetExecutablePath(e,r){return o(this,void 0,void 0,(function*(){let n=undefined;try{n=yield t.stat(e)}catch(t){if(t.code!=="ENOENT"){console.log(`Unexpected error attempting to determine if executable file exists '${e}': ${t}`)}}if(n&&n.isFile()){if(t.IS_WINDOWS){const t=u.extname(e).toUpperCase();if(r.some((e=>e.toUpperCase()===t))){return e}}else{if(isUnixExecutable(n)){return e}}}const i=e;for(const s of r){e=i+s;n=undefined;try{n=yield t.stat(e)}catch(t){if(t.code!=="ENOENT"){console.log(`Unexpected error attempting to determine if executable file exists '${e}': ${t}`)}}if(n&&n.isFile()){if(t.IS_WINDOWS){try{const r=u.dirname(e);const n=u.basename(e).toUpperCase();for(const i of yield t.readdir(r)){if(n===i.toUpperCase()){e=u.join(r,i);break}}}catch(t){console.log(`Unexpected error attempting to determine the actual case of the file '${e}': ${t}`)}return e}else{if(isUnixExecutable(n)){return e}}}}return""}))}t.tryGetExecutablePath=tryGetExecutablePath;function normalizeSeparators(e){e=e||"";if(t.IS_WINDOWS){e=e.replace(/\//g,"\\");return e.replace(/\\\\+/g,"\\")}return e.replace(/\/\/+/g,"/")}function isUnixExecutable(e){return(e.mode&1)>0||(e.mode&8)>0&&e.gid===process.getgid()||(e.mode&64)>0&&e.uid===process.getuid()}function getCmdPath(){var e;return(e=process.env["COMSPEC"])!==null&&e!==void 0?e:`cmd.exe`}t.getCmdPath=getCmdPath},191:function(e,t,r){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;Object.defineProperty(e,n,{enumerable:true,get:function(){return t[r]}})}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var s=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r in e)if(r!=="default"&&Object.hasOwnProperty.call(e,r))n(t,e,r);i(t,e);return t};var o=this&&this.__awaiter||function(e,t,r,n){function adopt(e){return e instanceof r?e:new r((function(t){t(e)}))}return new(r||(r=Promise))((function(r,i){function fulfilled(e){try{step(n.next(e))}catch(e){i(e)}}function rejected(e){try{step(n["throw"](e))}catch(e){i(e)}}function step(e){e.done?r(e.value):adopt(e.value).then(fulfilled,rejected)}step((n=n.apply(e,t||[])).next())}))};Object.defineProperty(t,"__esModule",{value:true});t.findInPath=t.which=t.mkdirP=t.rmRF=t.mv=t.cp=void 0;const a=r(613);const c=s(r(928));const u=s(r(120));function cp(e,t,r={}){return o(this,void 0,void 0,(function*(){const{force:n,recursive:i,copySourceDirectory:s}=readCopyOptions(r);const o=(yield u.exists(t))?yield u.stat(t):null;if(o&&o.isFile()&&!n){return}const a=o&&o.isDirectory()&&s?c.join(t,c.basename(e)):t;if(!(yield u.exists(e))){throw new Error(`no such file or directory: ${e}`)}const d=yield u.stat(e);if(d.isDirectory()){if(!i){throw new Error(`Failed to copy. ${e} is a directory, but tried to copy without recursive flag.`)}else{yield cpDirRecursive(e,a,0,n)}}else{if(c.relative(e,a)===""){throw new Error(`'${a}' and '${e}' are the same file`)}yield copyFile(e,a,n)}}))}t.cp=cp;function mv(e,t,r={}){return o(this,void 0,void 0,(function*(){if(yield u.exists(t)){let n=true;if(yield u.isDirectory(t)){t=c.join(t,c.basename(e));n=yield u.exists(t)}if(n){if(r.force==null||r.force){yield rmRF(t)}else{throw new Error("Destination already exists")}}}yield mkdirP(c.dirname(t));yield u.rename(e,t)}))}t.mv=mv;function rmRF(e){return o(this,void 0,void 0,(function*(){if(u.IS_WINDOWS){if(/[*"<>|]/.test(e)){throw new Error('File path must not contain `*`, `"`, `<`, `>` or `|` on Windows')}}try{yield u.rm(e,{force:true,maxRetries:3,recursive:true,retryDelay:300})}catch(e){throw new Error(`File was unable to be removed ${e}`)}}))}t.rmRF=rmRF;function mkdirP(e){return o(this,void 0,void 0,(function*(){a.ok(e,"a path argument must be provided");yield u.mkdir(e,{recursive:true})}))}t.mkdirP=mkdirP;function which(e,t){return o(this,void 0,void 0,(function*(){if(!e){throw new Error("parameter 'tool' is required")}if(t){const t=yield which(e,false);if(!t){if(u.IS_WINDOWS){throw new Error(`Unable to locate executable file: ${e}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also verify the file has a valid extension for an executable file.`)}else{throw new Error(`Unable to locate executable file: ${e}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also check the file mode to verify the file is executable.`)}}return t}const r=yield findInPath(e);if(r&&r.length>0){return r[0]}return""}))}t.which=which;function findInPath(e){return o(this,void 0,void 0,(function*(){if(!e){throw new Error("parameter 'tool' is required")}const t=[];if(u.IS_WINDOWS&&process.env["PATHEXT"]){for(const e of process.env["PATHEXT"].split(c.delimiter)){if(e){t.push(e)}}}if(u.isRooted(e)){const r=yield u.tryGetExecutablePath(e,t);if(r){return[r]}return[]}if(e.includes(c.sep)){return[]}const r=[];if(process.env.PATH){for(const e of process.env.PATH.split(c.delimiter)){if(e){r.push(e)}}}const n=[];for(const i of r){const r=yield u.tryGetExecutablePath(c.join(i,e),t);if(r){n.push(r)}}return n}))}t.findInPath=findInPath;function readCopyOptions(e){const t=e.force==null?true:e.force;const r=Boolean(e.recursive);const n=e.copySourceDirectory==null?true:Boolean(e.copySourceDirectory);return{force:t,recursive:r,copySourceDirectory:n}}function cpDirRecursive(e,t,r,n){return o(this,void 0,void 0,(function*(){if(r>=255)return;r++;yield mkdirP(t);const i=yield u.readdir(e);for(const s of i){const i=`${e}/${s}`;const o=`${t}/${s}`;const a=yield u.lstat(i);if(a.isDirectory()){yield cpDirRecursive(i,o,r,n)}else{yield copyFile(i,o,n)}}yield u.chmod(t,(yield u.stat(e)).mode)}))}function copyFile(e,t,r){return o(this,void 0,void 0,(function*(){if((yield u.lstat(e)).isSymbolicLink()){try{yield u.lstat(t);yield u.unlink(t)}catch(e){if(e.code==="EPERM"){yield u.chmod(t,"0666");yield u.unlink(t)}}const r=yield u.readlink(e);yield u.symlink(r,t,u.IS_WINDOWS?"junction":null)}else if(!(yield u.exists(t))||r){yield u.copyFile(e,t)}}))}},26:function(e,t){(function(e,r){true?r(t):0})(this,(function(e){"use strict";const t=/^[v^~<>=]*?(\d+)(?:\.([x*]|\d+)(?:\.([x*]|\d+)(?:\.([x*]|\d+))?(?:-([\da-z\-]+(?:\.[\da-z\-]+)*))?(?:\+[\da-z\-]+(?:\.[\da-z\-]+)*)?)?)?$/i;const validateAndParse=e=>{if(typeof e!=="string"){throw new TypeError("Invalid argument expected string")}const r=e.match(t);if(!r){throw new Error(`Invalid argument not valid semver ('${e}' received)`)}r.shift();return r};const isWildcard=e=>e==="*"||e==="x"||e==="X";const tryParse=e=>{const t=parseInt(e,10);return isNaN(t)?e:t};const forceType=(e,t)=>typeof e!==typeof t?[String(e),String(t)]:[e,t];const compareStrings=(e,t)=>{if(isWildcard(e)||isWildcard(t))return 0;const[r,n]=forceType(tryParse(e),tryParse(t));if(r>n)return 1;if(r{for(let r=0;r{const r=validateAndParse(e);const n=validateAndParse(t);const i=r.pop();const s=n.pop();const o=compareSegments(r,n);if(o!==0)return o;if(i&&s){return compareSegments(i.split("."),s.split("."))}else if(i||s){return i?-1:1}return 0};const compare=(e,t,n)=>{assertValidOperator(n);const i=compareVersions(e,t);return r[n].includes(i)};const r={">":[1],">=":[0,1],"=":[0],"<=":[-1,0],"<":[-1],"!=":[-1,1]};const n=Object.keys(r);const assertValidOperator=e=>{if(typeof e!=="string"){throw new TypeError(`Invalid operator type, expected string but got ${typeof e}`)}if(n.indexOf(e)===-1){throw new Error(`Invalid operator, expected one of ${n.join("|")}`)}};const satisfies=(e,t)=>{t=t.replace(/([><=]+)\s+/g,"$1");if(t.includes("||")){return t.split("||").some((t=>satisfies(e,t)))}else if(t.includes(" - ")){const[r,n]=t.split(" - ",2);return satisfies(e,`>=${r} <=${n}`)}else if(t.includes(" ")){return t.trim().replace(/\s{2,}/g," ").split(" ").every((t=>satisfies(e,t)))}const r=t.match(/^([<>=~^]+)/);const n=r?r[1]:"=";if(n!=="^"&&n!=="~")return compare(e,t,n);const[i,s,o,,a]=validateAndParse(e);const[c,u,d,,l]=validateAndParse(t);const f=[i,s,o];const p=[c,u!==null&&u!==void 0?u:"x",d!==null&&d!==void 0?d:"x"];if(l){if(!a)return false;if(compareSegments(f,p)!==0)return false;if(compareSegments(a.split("."),l.split("."))===-1)return false}const h=p.findIndex((e=>e!=="0"))+1;const g=n==="~"?2:h>1?h:1;if(compareSegments(f.slice(0,g),p.slice(0,g))!==0)return false;if(compareSegments(f.slice(g),p.slice(g))===-1)return false;return true};const validate=e=>typeof e==="string"&&/^[v\d]/.test(e)&&t.test(e);const validateStrict=e=>typeof e==="string"&&/^(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-]+)*))?$/.test(e);e.compare=compare;e.compareVersions=compareVersions;e.satisfies=satisfies;e.validate=validate;e.validateStrict=validateStrict}))},613:e=>{"use strict";e.exports=require("assert")},317:e=>{"use strict";e.exports=require("child_process")},434:e=>{"use strict";e.exports=require("events")},896:e=>{"use strict";e.exports=require("fs")},857:e=>{"use strict";e.exports=require("os")},928:e=>{"use strict";e.exports=require("path")},193:e=>{"use strict";e.exports=require("string_decoder")},557:e=>{"use strict";e.exports=require("timers")}};var t={};function __nccwpck_require__(r){var n=t[r];if(n!==undefined){return n.exports}var i=t[r]={exports:{}};var s=true;try{e[r].call(i.exports,i,i.exports,__nccwpck_require__);s=false}finally{if(s)delete t[r]}return i.exports}if(typeof __nccwpck_require__!=="undefined")__nccwpck_require__.ab=__dirname+"/";var r=__nccwpck_require__(755);module.exports=r})(); \ No newline at end of file +(()=>{var e={472:function(e,t,r){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;var i=Object.getOwnPropertyDescriptor(t,r);if(!i||("get"in i?!t.__esModule:i.writable||i.configurable)){i={enumerable:true,get:function(){return t[r]}}}Object.defineProperty(e,n,i)}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var s=this&&this.__importStar||function(){var ownKeys=function(e){ownKeys=Object.getOwnPropertyNames||function(e){var t=[];for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r))t[t.length]=r;return t};return ownKeys(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r=ownKeys(e),s=0;s/dev/null 2>&1'+r}async function addINIValuesWindows(e){const t=await o.CSVArray(e);let r="\n";await o.asyncForEach(t,(async function(e){r+=await o.addLog("$tick",e,"Added to php.ini","win32")+"\n"}));return'Add-Content "$php_dir\\php.ini" "'+t.join("\n")+'"'+r}async function addINIValues(e,t,r=false){let n="\n";switch(r){case true:n+=await o.stepLog("Add php.ini values",t)+await o.suppressOutput(t)+"\n";break;case false:default:n+=await o.stepLog("Add php.ini values",t)+"\n";break}switch(t){case"win32":return n+await addINIValuesWindows(e);case"darwin":case"linux":return n+await addINIValuesUnix(e);default:return await o.log("Platform "+t+" is not supported",t,"error")}}},469:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t.issueCommand=issueCommand;t.error=error;t.setFailed=setFailed;t.getInput=getInput;const n=r(857);function toCommandValue(e){if(e instanceof Error){return e.toString()}return e}function escapeData(e){return toCommandValue(e).replace(/%/g,"%25").replace(/\r/g,"%0D").replace(/\n/g,"%0A")}function escapeProperty(e){return e.replace(/%/g,"%25").replace(/\r/g,"%0D").replace(/\n/g,"%0A").replace(/:/g,"%3A").replace(/,/g,"%2C")}function issueCommand(e,t,r){let i=`::${e}`;if(t&&Object.keys(t).length>0){i+=" ";const e=Object.entries(t).filter((([,e])=>e)).map((([e,t])=>`${e}=${escapeProperty(t)}`)).join(",");i+=e}i+=`::${escapeData(r)}`;process.stdout.write(i+n.EOL)}function error(e){issueCommand("error",{},e)}function setFailed(e){process.exitCode=1;error(e)}function getInput(e,t=false){const r=process.env[`INPUT_${e.replace(/ /g,"_").toUpperCase()}`]||"";if(t&&!r){throw new Error(`Input required and not supplied: ${e}`)}return r.trim()}},524:function(e,t,r){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;var i=Object.getOwnPropertyDescriptor(t,r);if(!i||("get"in i?!t.__esModule:i.writable||i.configurable)){i={enumerable:true,get:function(){return t[r]}}}Object.defineProperty(e,n,i)}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var s=this&&this.__importStar||function(){var ownKeys=function(e){ownKeys=Object.getOwnPropertyNames||function(e){var t=[];for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r))t[t.length]=r;return t};return ownKeys(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r=ownKeys(e),s=0;s{"use strict";Object.defineProperty(t,"__esModule",{value:true});t.fetch=fetch;const r=new Set([301,302,303,307,308]);async function fetch(e,t,n=5){const i={"User-Agent":`Mozilla/5.0 (${process.platform} ${process.arch}) setup-php`};if(t){i["Authorization"]="Bearer "+t}try{const t=await globalThis.fetch(e,{headers:i,redirect:n>0?"follow":"manual"});if(t.ok){const e=await t.text();return{data:e}}else if(r.has(t.status)&&n<=0){return{error:`${t.status}: Redirect error`}}else{return{error:`${t.status}: ${t.statusText}`}}}catch(e){return{error:`Fetch error: ${e.message}`}}}},755:function(e,t,r){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;var i=Object.getOwnPropertyDescriptor(t,r);if(!i||("get"in i?!t.__esModule:i.writable||i.configurable)){i={enumerable:true,get:function(){return t[r]}}}Object.defineProperty(e,n,i)}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var s=this&&this.__importStar||function(){var ownKeys=function(e){ownKeys=Object.getOwnPropertyNames||function(e){var t=[];for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r))t[t.length]=r;return t};return ownKeys(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r=ownKeys(e),s=0;s{await run()})().catch((e=>{l.setFailed(e.message)}))},75:function(e,t,r){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;var i=Object.getOwnPropertyDescriptor(t,r);if(!i||("get"in i?!t.__esModule:i.writable||i.configurable)){i={enumerable:true,get:function(){return t[r]}}}Object.defineProperty(e,n,i)}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var s=this&&this.__importStar||function(){var ownKeys=function(e){ownKeys=Object.getOwnPropertyNames||function(e){var t=[];for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r))t[t.length]=r;return t};return ownKeys(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r=ownKeys(e),s=0;so.compareVersions(t.version,e.version)));const i=r.find((e=>{if(e?.require?.php){return e?.require?.php.split("|").some((e=>e&&o.satisfies(t+".0",e)))}return false}));return i?i.version:null}return null}},159:function(e,t,r){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;var i=Object.getOwnPropertyDescriptor(t,r);if(!i||("get"in i?!t.__esModule:i.writable||i.configurable)){i={enumerable:true,get:function(){return t[r]}}}Object.defineProperty(e,n,i)}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var s=this&&this.__importStar||function(){var ownKeys=function(e){ownKeys=Object.getOwnPropertyNames||function(e){var t=[];for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r))t[t.length]=r;return t};return ownKeys(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r=ownKeys(e),s=0;s{if(/^\d+\.\d+\.\d+(-|$)/.test(e))return e;const t=e.match(/^(\d+\.\d+\.\d+)([A-Za-z]+[0-9A-Za-z.]+)$/);return t?`${t[1]}-${t[2]}`:e};const t=e["version_prefix"]+e["version"];const r=`https://api.github.com/repos/${e["repository"]}/git/matching-refs/tags%2F${t}.`;const n=await f.readEnv("GITHUB_TOKEN")||await f.readEnv("COMPOSER_TOKEN");const i=await d.fetch(r,n);if(i.error||i.data==="[]"){e.error=i.error??`No version found with prefix ${t}.`;return e.version}else{const e=JSON.parse(i.data);const t=e.map((e=>(e.ref?.split("/").pop()??"").replace(/^v(?=\d)/,""))).filter((e=>e.length>0));const r=new Map;const n=t.map((e=>{const t=fixSemver(e);r.set(t,e);return t}));const s=n.toSorted(((e,t)=>{try{return u.compareVersions(t,e)}catch{return t.localeCompare(e,"en",{numeric:true,sensitivity:"base"})}}));return r.get(s[0])??s[0]}}async function getLatestVersion(e){if(!e.version&&e.fetch_latest==="false"){return"latest"}if(e.fetch_latest==="true"&&!e.repository){return"latest"}const t=await d.fetch(`${e.github}/${e.repository}/releases.atom`);if(t.data){const e=[...t.data.matchAll(/releases\/tag\/([a-zA-Z]*)?(\d+\.\d+\.\d+)"/g)].map((e=>e[2]));const r=e.toSorted(((e,t)=>e.localeCompare(t,undefined,{numeric:true})));return r.at(-1)||"latest"}return"latest"}async function getVersion(e,t){const r=/^(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 n=/^composer:(stable|preview|snapshot|[12])$/;const i=/[><=^~]+.*/;const s=/^\d+(\.\d+)?$/;t.version=e.replace(/v?(\d)/,"$1").replace(/\.x/,"");switch(true){case n.test(t.release):case r.test(t.version):case i.test(t.version)&&t.type==="composer":return t.version;case s.test(t.version)&&t.type==="composer":t.release=`${t.tool}:${t.version}.*`;return`${t.version}.*`;case!!t.repository&&s.test(t.version):return await getSemverVersion(t);default:return t.version.replace(/[><=^~]*/,"")}}async function getRelease(e,t){e=e.includes("/")?e.split("/")[1]:e;return e.includes(":")?[t.tool,e.split(":")[1]].join(":"):t.tool}async function filterList(e){const t=/^composer($|:.*)/;const r=/^composer:?($|preview$|snapshot$|v?\d+(\.\d+)?$|v?\d+\.\d+\.\d+[\w-]*$)/;const n=e.filter((e=>r.test(e)));let i="composer";e=e.filter((e=>!t.test(e)));switch(true){case n[0]==undefined:break;default:i=n.at(-1).replace(/v(\d\S*)/,"$1");break}e.unshift(i);return e}async function getUrl(e){if((e.version??"latest")==="latest"){return[e.domain,e.repository,e.prefix,e.version,e.verb,e.tool+e.extension].filter(Boolean).join("/")}else{return[e.domain,e.repository,e.prefix,e.verb,e.version_prefix+e.version,e.tool+e.extension].filter(Boolean).join("/")}}async function getPharUrl(e){if(e.version==="latest"){return e.domain+"/"+e.tool+".phar"}else{return e.domain+"/"+e.tool+"-"+e.version_prefix+e.version+".phar"}}async function addArchive(e){return await f.getCommand(e.os,"tool")+await f.joins(e.url,e.tool,e.version_parameter)}async function addPackage(e){const t=await f.getCommand(e.os,"composer_tool");const r=e.repository.split("/");const n=await f.joins(r[1],e.release,r[0]+"/",e.scope);return t+n}async function addBlackfirePlayer(e){switch(e.os){case"win32":return await f.addLog("$cross",e.tool,e.tool+" is not a windows tool","win32");default:if(e.version=="latest"){if(/5\.[5-6]|7\.0/.test(e.php_version)){e.version="1.9.3"}else if(/7\.[1-4]|8\.0/.test(e.php_version)){e.version="1.22.0"}}e.url=await getPharUrl(e);return addArchive(e)}}async function addCastor(e){e.tool="castor."+e.os.replace("win32","windows")+"-amd64";e.url=await getUrl(e);e.tool="castor";e.version_parameter=c.default.existsSync("castor.php")?e.version_parameter:"";return await addArchive(e)}async function addComposer(e){const t=e.version.replace("latest","stable");const r=e.github;const n=e.domain;const i="https://dl.cloudsmith.io";const s="https://artifacts.setup-php.com";const o=`composer-${e.php_version}-${t}.phar`;const a=`${r}/shivammathur/composer-cache/releases/latest/download/${o}`;const c=`${i}/public/shivammathur/composer-cache/raw/files/${o}`;const u=`${s}/composer/${o}`;const d=`${n}/download/latest-2.2.x/composer.phar`;const l=/^5\.[3-6]$|^7\.[0-1]$/.test(e.php_version);const p=`${n}/composer-${t}.phar`;const h=`${n}/download/${t}/composer.phar`;let w=`${a},${u},${c}`;let g=`${n}/composer.phar`;switch(true){case/^snapshot$/.test(t):g=l?d:g;break;case/^preview$|^2$/.test(t):g=l?d:p;break;case/^1$/.test(t):g=p;break;case/^\d+\.\d+\.\d+[\w-]*$/.test(e.version):w=`${r}/${e.repository}/releases/download/${e.version}/composer.phar`;g=h;break;default:g=l?d:p}const v=await f.readEnv("NO_TOOLS_CACHE")!=="true";e.url=v?`${w},${g}`:g;e.version_parameter=e.version;return await addArchive(e)}async function addDeployer(e){if(e.version==="latest"){e.url=e.domain+"/deployer.phar"}else{const t=await d.fetch("https://deployer.org/manifest.json");const r=JSON.parse(t.data);const n=Object.keys(r).find((t=>r[t].version===e.version));if(n){e.url=r[n].url}else{return await f.addLog("$cross","deployer","Version missing in deployer manifest",e.os)}}return await addArchive(e)}async function addDevTools(e){switch(e.os){case"linux":case"darwin":return"add_devtools "+e.tool;case"win32":return await f.addLog("$tick",e.tool,e.tool+" is not a windows tool","win32");default:return await f.log("Platform "+e.os+" is not supported",e.os,"error")}}async function addPECL(e){return await f.getCommand(e.os,"pecl")}async function addPhing(e){e.url=e.domain+"/get/phing-"+e.version+e.extension;if(e.version!="latest"){[e.prefix,e.verb]=["releases","download"];e.domain=e.github;e.extension="-"+e.version+e.extension;e.url+=","+await getUrl(e)}return await addArchive(e)}async function addPhive(e){switch(true){case/5\.[3-5]/.test(e.php_version):return await f.addLog("$cross","phive","Phive is not supported on PHP "+e.php_version,e.os);case/5\.6|7\.0/.test(e.php_version):e.version="0.12.1";break;case/7\.1/.test(e.php_version):e.version="0.13.5";break;case/7\.2/.test(e.php_version):e.version="0.14.5";break;case/7\.3|7\.4/.test(e.php_version):e.version="0.15.3";break;case/^latest$/.test(e.version):e.version=await getLatestVersion(e);break}e.extension="-"+e.version+e.extension;e.url=await getUrl(e);return await addArchive(e)}async function addPHPUnitTools(e){if(e.version==="latest"){e.version=await l.search(e.packagist,e.php_version)??"latest"}e.url=await getPharUrl(e);if(e.url.match(/-\d+/)){e.url+=","+e.url.replace(/-(\d+)\.\d+\.\d+/,"-$1")}return await addArchive(e)}async function addWPCLI(e){if(e.version==="latest"){e.uri="wp-cli/builds/blob/gh-pages/phar/wp-cli.phar?raw=true";e.url=[e.domain,e.uri].join("/")}else{e.extension="-"+e.version+e.extension;e.url=await getUrl(e)}return await addArchive(e)}async function getData(e,t,r){const n=a.default.join(__dirname,"../src/configs/tools.json");const i=c.default.readFileSync(n,"utf8");const s=JSON.parse(i);e=e.replace(/\s+/g,"");const o=e.split(":");const u=o[0];const d=o[1];let l;if(Object.hasOwn(s,u)){l={...s[u],tool:u}}else{const e=Object.keys(s).find((e=>s[e].alias==u));if(e){l={...s[e],tool:e}}else if(u.includes("/")){l={tool:u.split("/")[1],repository:u,type:"composer"}}else{l={tool:u}}}const f="https://github.com";const p=l.domain??f;const h={tool:l.tool,version:"",url:"",os:r,php_version:t,github:f,domain:p,extension:l.extension??".phar",repository:l.repository??"",prefix:p===f?"releases":"",verb:p===f?"download":"",fetch_latest:l.fetch_latest??"false",scope:l.scope??"global",version_parameter:l.version_parameter!=null?JSON.stringify(l.version_parameter):"",version_prefix:l.version_prefix??"",release:"",packagist:l.packagist??l.repository??"",type:l.type,function:l.function,alias:l.alias};h.release=await getRelease(e,h);h.version=d?await getVersion(d,h):await getLatestVersion(h);h.url=await getUrl(h);return h}t.functionRecord={castor:addCastor,composer:addComposer,deployer:addDeployer,dev_tools:addDevTools,phive:addPhive,blackfire_player:addBlackfirePlayer,pecl:addPECL,phing:addPhing,phpunit:addPHPUnitTools,phpcpd:addPHPUnitTools,wp_cli:addWPCLI};async function addTools(e,r,n){let i="\n";if(e==="none"){return""}else{i+=await f.stepLog("Setup Tools",n)}const s=await filterList(await f.CSVArray(e));await f.asyncForEach(s,(async function(e){const s=await getData(e,r,n);i+="\n";switch(true){case s.error!==undefined:i+=await f.addLog("$cross",s.tool,s.error,s.os);break;case"phar"===s.type:i+=await addArchive(s);break;case"composer"===s.type:i+=await addPackage(s);break;case"custom-package"===s.type:i+=await f.customPackage(s.tool.split("-")[0],"tools",s.version,s.os);break;case"custom-function"===s.type:if(!s.function){i+=await f.addLog("$cross",s.tool,s.tool+" has no function defined. Please report this issue.",s.os)}else{i+=await t.functionRecord[s.function](s)}break;case/^none$/.test(s.tool):break;default:i+=await f.addLog("$cross",s.tool,"Tool "+s.tool+" is not supported",s.os);break}}));return i}},277:function(e,t,r){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;var i=Object.getOwnPropertyDescriptor(t,r);if(!i||("get"in i?!t.__esModule:i.writable||i.configurable)){i={enumerable:true,get:function(){return t[r]}}}Object.defineProperty(e,n,i)}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var s=this&&this.__importStar||function(){var ownKeys=function(e){ownKeys=Object.getOwnPropertyNames||function(e){var t=[];for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r))t[t.length]=r;return t};return ownKeys(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r=ownKeys(e),s=0;s1:return e.slice(0,3);default:return e+".0"}}}async function parseIniFile(e){switch(true){case/^(production|development|none)$/.test(e):return e;case/php\.ini-(production|development)$/.test(e):return e.split("-")[1];default:return"production"}}async function asyncForEach(e,t){for(const[r,n]of e.entries()){await t(n,r,e)}}async function color(e){switch(e){case"error":return"31";default:case"success":return"32";case"warning":return"33"}}async function log(e,t,r){switch(t){case"win32":return'printf "\\033['+await color(r)+";1m"+e+' \\033[0m"';case"linux":case"darwin":default:return'echo "\\033['+await color(r)+";1m"+e+'\\033[0m"'}}async function stepLog(e,t){switch(t){case"win32":return'Step-Log "'+e+'"';case"linux":case"darwin":return'step_log "'+e+'"';default:return await log("Platform "+t+" is not supported",t,"error")}}async function addLog(e,t,r,n){switch(n){case"win32":return'Add-Log "'+e+'" "'+t+'" "'+r+'"';case"linux":case"darwin":return'add_log "'+e+'" "'+t+'" "'+r+'"';default:return await log("Platform "+n+" is not supported",n,"error")}}async function extensionArray(e){switch(e){case"":case" ":return[];default:return[e.match(/(^|,\s?)none(\s?,|$)/)?"none":"",...e.split(",").map((function(e){if(/.+-.+\/.+@.+/.test(e)){return e}return e.trim().toLowerCase().replace(/^(:)?(php[-_]|none|zend )|(-[^-]*)-/,"$1$3")}))].filter(Boolean)}}async function CSVArray(e){switch(e){case"":case" ":return[];default:return e.split(/,(?=(?:(?:[^"']*["']){2})*[^"']*$)/).map((function(e){return e.trim().replace(/^["']|["']$|(?<==)["']/g,"").replace(/=(((?!E_).)*[?{}|&~![()^]+((?!E_).)+)/,"='$1'").replace(/=(.*?)(=.*)/,"='$1$2'").replace(/:\s*["'](.*?)/g,":$1")})).filter(Boolean)}}async function getExtensionPrefix(e){switch(true){default:return"extension";case/xdebug([2-3])?$|opcache|ioncube|eaccelerator/.test(e):return"zend_extension"}}async function suppressOutput(e){switch(e){case"win32":return" >$null 2>&1";case"linux":case"darwin":return" >/dev/null 2>&1";default:return await log("Platform "+e+" is not supported",e,"error")}}async function getUnsupportedLog(e,t,r){return"\n"+await addLog("$cross",e,[e,"is not supported on PHP",t].join(" "),r)+"\n"}async function getCommand(e,t){switch(e){case"linux":case"darwin":return"add_"+t+" ";case"win32":return"Add-"+t.split("_").map((e=>e.charAt(0).toUpperCase()+e.slice(1))).join("")+" ";default:return await log("Platform "+e+" is not supported",e,"error")}}async function joins(...e){return[...e].join(" ")}async function scriptExtension(e){switch(e){case"win32":return".ps1";case"linux":case"darwin":return".sh";default:return await log("Platform "+e+" is not supported",e,"error")}}async function scriptTool(e){switch(e){case"win32":return"pwsh ";case"linux":case"darwin":return"bash ";default:return await log("Platform "+e+" is not supported",e,"error")}}async function customPackage(e,t,r,n){const i=e.replace(/\d+|(pdo|pecl)[_-]|[_-]db2/,"");const s=await scriptExtension(n);const o=c.join(__dirname,"../src/scripts/"+t+"/"+i+s);const a=await getCommand(n,i);return"\n. "+o+"\n"+a+r}async function parseExtensionSource(e,t){const r=/(\w+)-(\w+:\/\/.{1,253}(?:[.:][^:/\s]{2,63})+\/)?([\w.-]+)\/([\w.-]+)@(.+)/;const n=r.exec(e);n[2]=n[2]?n[2].slice(0,-1):"https://github.com";return await joins("\nadd_extension_from_source",...n.splice(1,n.length),t)}async function readPHPVersion(){const e=await getInput("php-version",false);if(e){return e}const t=await getInput("php-version-file",false)||".php-version";if(a.default.existsSync(t)){const e=a.default.readFileSync(t,"utf8");const r=e.match(/^(?:php\s)?(\d+\.\d+\.\d+)$/m);return r?r[1]:e.trim()}else if(t!==".php-version"){throw new Error(`Could not find '${t}' file.`)}const r=await readEnv("COMPOSER_PROJECT_DIR");const n=c.join(r,"composer.lock");if(a.default.existsSync(n)){const e=JSON.parse(a.default.readFileSync(n,"utf8"));if(e["platform-overrides"]&&e["platform-overrides"]["php"]){return e["platform-overrides"]["php"]}}const i=c.join(r,"composer.json");if(a.default.existsSync(i)){const e=JSON.parse(a.default.readFileSync(i,"utf8"));if(e["config"]&&e["config"]["platform"]&&e["config"]["platform"]["php"]){return e["config"]["platform"]["php"]}}return"latest"}async function setVariable(e,t,r){switch(r){case"win32":return"\n$"+e+" = "+t+"\n";case"linux":case"darwin":default:return"\n"+e+'="$('+t+')"\n'}}},236:function(e,t,r){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;Object.defineProperty(e,n,{enumerable:true,get:function(){return t[r]}})}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var s=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r in e)if(r!=="default"&&Object.hasOwnProperty.call(e,r))n(t,e,r);i(t,e);return t};var o=this&&this.__awaiter||function(e,t,r,n){function adopt(e){return e instanceof r?e:new r((function(t){t(e)}))}return new(r||(r=Promise))((function(r,i){function fulfilled(e){try{step(n.next(e))}catch(e){i(e)}}function rejected(e){try{step(n["throw"](e))}catch(e){i(e)}}function step(e){e.done?r(e.value):adopt(e.value).then(fulfilled,rejected)}step((n=n.apply(e,t||[])).next())}))};Object.defineProperty(t,"__esModule",{value:true});t.getExecOutput=t.exec=void 0;const a=r(193);const c=s(r(665));function exec(e,t,r){return o(this,void 0,void 0,(function*(){const n=c.argStringToArray(e);if(n.length===0){throw new Error(`Parameter 'commandLine' cannot be null or empty.`)}const i=n[0];t=n.slice(1).concat(t||[]);const s=new c.ToolRunner(i,t,r);return s.exec()}))}t.exec=exec;function getExecOutput(e,t,r){var n,i;return o(this,void 0,void 0,(function*(){let s="";let o="";const c=new a.StringDecoder("utf8");const u=new a.StringDecoder("utf8");const d=(n=r===null||r===void 0?void 0:r.listeners)===null||n===void 0?void 0:n.stdout;const l=(i=r===null||r===void 0?void 0:r.listeners)===null||i===void 0?void 0:i.stderr;const stdErrListener=e=>{o+=u.write(e);if(l){l(e)}};const stdOutListener=e=>{s+=c.write(e);if(d){d(e)}};const f=Object.assign(Object.assign({},r===null||r===void 0?void 0:r.listeners),{stdout:stdOutListener,stderr:stdErrListener});const p=yield exec(e,t,Object.assign(Object.assign({},r),{listeners:f}));s+=c.end();o+=u.end();return{exitCode:p,stdout:s,stderr:o}}))}t.getExecOutput=getExecOutput},665:function(e,t,r){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;Object.defineProperty(e,n,{enumerable:true,get:function(){return t[r]}})}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var s=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r in e)if(r!=="default"&&Object.hasOwnProperty.call(e,r))n(t,e,r);i(t,e);return t};var o=this&&this.__awaiter||function(e,t,r,n){function adopt(e){return e instanceof r?e:new r((function(t){t(e)}))}return new(r||(r=Promise))((function(r,i){function fulfilled(e){try{step(n.next(e))}catch(e){i(e)}}function rejected(e){try{step(n["throw"](e))}catch(e){i(e)}}function step(e){e.done?r(e.value):adopt(e.value).then(fulfilled,rejected)}step((n=n.apply(e,t||[])).next())}))};Object.defineProperty(t,"__esModule",{value:true});t.argStringToArray=t.ToolRunner=void 0;const a=s(r(857));const c=s(r(434));const u=s(r(317));const d=s(r(928));const l=s(r(191));const f=s(r(120));const p=r(557);const h=process.platform==="win32";class ToolRunner extends c.EventEmitter{constructor(e,t,r){super();if(!e){throw new Error("Parameter 'toolPath' cannot be null or empty.")}this.toolPath=e;this.args=t||[];this.options=r||{}}_debug(e){if(this.options.listeners&&this.options.listeners.debug){this.options.listeners.debug(e)}}_getCommandString(e,t){const r=this._getSpawnFileName();const n=this._getSpawnArgs(e);let i=t?"":"[command]";if(h){if(this._isCmdFile()){i+=r;for(const e of n){i+=` ${e}`}}else if(e.windowsVerbatimArguments){i+=`"${r}"`;for(const e of n){i+=` ${e}`}}else{i+=this._windowsQuoteCmdArg(r);for(const e of n){i+=` ${this._windowsQuoteCmdArg(e)}`}}}else{i+=r;for(const e of n){i+=` ${e}`}}return i}_processLineBuffer(e,t,r){try{let n=t+e.toString();let i=n.indexOf(a.EOL);while(i>-1){const e=n.substring(0,i);r(e);n=n.substring(i+a.EOL.length);i=n.indexOf(a.EOL)}return n}catch(e){this._debug(`error processing line. Failed with error ${e}`);return""}}_getSpawnFileName(){if(h){if(this._isCmdFile()){return process.env["COMSPEC"]||"cmd.exe"}}return this.toolPath}_getSpawnArgs(e){if(h){if(this._isCmdFile()){let t=`/D /S /C "${this._windowsQuoteCmdArg(this.toolPath)}`;for(const r of this.args){t+=" ";t+=e.windowsVerbatimArguments?r:this._windowsQuoteCmdArg(r)}t+='"';return[t]}}return this.args}_endsWith(e,t){return e.endsWith(t)}_isCmdFile(){const e=this.toolPath.toUpperCase();return this._endsWith(e,".CMD")||this._endsWith(e,".BAT")}_windowsQuoteCmdArg(e){if(!this._isCmdFile()){return this._uvQuoteCmdArg(e)}if(!e){return'""'}const t=[" ","\t","&","(",")","[","]","{","}","^","=",";","!","'","+",",","`","~","|","<",">",'"'];let r=false;for(const n of e){if(t.some((e=>e===n))){r=true;break}}if(!r){return e}let n='"';let i=true;for(let t=e.length;t>0;t--){n+=e[t-1];if(i&&e[t-1]==="\\"){n+="\\"}else if(e[t-1]==='"'){i=true;n+='"'}else{i=false}}n+='"';return n.split("").reverse().join("")}_uvQuoteCmdArg(e){if(!e){return'""'}if(!e.includes(" ")&&!e.includes("\t")&&!e.includes('"')){return e}if(!e.includes('"')&&!e.includes("\\")){return`"${e}"`}let t='"';let r=true;for(let n=e.length;n>0;n--){t+=e[n-1];if(r&&e[n-1]==="\\"){t+="\\"}else if(e[n-1]==='"'){r=true;t+="\\"}else{r=false}}t+='"';return t.split("").reverse().join("")}_cloneExecOptions(e){e=e||{};const t={cwd:e.cwd||process.cwd(),env:e.env||process.env,silent:e.silent||false,windowsVerbatimArguments:e.windowsVerbatimArguments||false,failOnStdErr:e.failOnStdErr||false,ignoreReturnCode:e.ignoreReturnCode||false,delay:e.delay||1e4};t.outStream=e.outStream||process.stdout;t.errStream=e.errStream||process.stderr;return t}_getSpawnOptions(e,t){e=e||{};const r={};r.cwd=e.cwd;r.env=e.env;r["windowsVerbatimArguments"]=e.windowsVerbatimArguments||this._isCmdFile();if(e.windowsVerbatimArguments){r.argv0=`"${t}"`}return r}exec(){return o(this,void 0,void 0,(function*(){if(!f.isRooted(this.toolPath)&&(this.toolPath.includes("/")||h&&this.toolPath.includes("\\"))){this.toolPath=d.resolve(process.cwd(),this.options.cwd||process.cwd(),this.toolPath)}this.toolPath=yield l.which(this.toolPath,true);return new Promise(((e,t)=>o(this,void 0,void 0,(function*(){this._debug(`exec tool: ${this.toolPath}`);this._debug("arguments:");for(const e of this.args){this._debug(` ${e}`)}const r=this._cloneExecOptions(this.options);if(!r.silent&&r.outStream){r.outStream.write(this._getCommandString(r)+a.EOL)}const n=new ExecState(r,this.toolPath);n.on("debug",(e=>{this._debug(e)}));if(this.options.cwd&&!(yield f.exists(this.options.cwd))){return t(new Error(`The cwd: ${this.options.cwd} does not exist!`))}const i=this._getSpawnFileName();const s=u.spawn(i,this._getSpawnArgs(r),this._getSpawnOptions(this.options,i));let o="";if(s.stdout){s.stdout.on("data",(e=>{if(this.options.listeners&&this.options.listeners.stdout){this.options.listeners.stdout(e)}if(!r.silent&&r.outStream){r.outStream.write(e)}o=this._processLineBuffer(e,o,(e=>{if(this.options.listeners&&this.options.listeners.stdline){this.options.listeners.stdline(e)}}))}))}let c="";if(s.stderr){s.stderr.on("data",(e=>{n.processStderr=true;if(this.options.listeners&&this.options.listeners.stderr){this.options.listeners.stderr(e)}if(!r.silent&&r.errStream&&r.outStream){const t=r.failOnStdErr?r.errStream:r.outStream;t.write(e)}c=this._processLineBuffer(e,c,(e=>{if(this.options.listeners&&this.options.listeners.errline){this.options.listeners.errline(e)}}))}))}s.on("error",(e=>{n.processError=e.message;n.processExited=true;n.processClosed=true;n.CheckComplete()}));s.on("exit",(e=>{n.processExitCode=e;n.processExited=true;this._debug(`Exit code ${e} received from tool '${this.toolPath}'`);n.CheckComplete()}));s.on("close",(e=>{n.processExitCode=e;n.processExited=true;n.processClosed=true;this._debug(`STDIO streams have closed for tool '${this.toolPath}'`);n.CheckComplete()}));n.on("done",((r,n)=>{if(o.length>0){this.emit("stdline",o)}if(c.length>0){this.emit("errline",c)}s.removeAllListeners();if(r){t(r)}else{e(n)}}));if(this.options.input){if(!s.stdin){throw new Error("child process missing stdin")}s.stdin.end(this.options.input)}}))))}))}}t.ToolRunner=ToolRunner;function argStringToArray(e){const t=[];let r=false;let n=false;let i="";function append(e){if(n&&e!=='"'){i+="\\"}i+=e;n=false}for(let s=0;s0){t.push(i);i=""}continue}append(o)}if(i.length>0){t.push(i.trim())}return t}t.argStringToArray=argStringToArray;class ExecState extends c.EventEmitter{constructor(e,t){super();this.processClosed=false;this.processError="";this.processExitCode=0;this.processExited=false;this.processStderr=false;this.delay=1e4;this.done=false;this.timeout=null;if(!t){throw new Error("toolPath must not be empty")}this.options=e;this.toolPath=t;if(e.delay){this.delay=e.delay}}CheckComplete(){if(this.done){return}if(this.processClosed){this._setResult()}else if(this.processExited){this.timeout=p.setTimeout(ExecState.HandleTimeout,this.delay,this)}}_debug(e){this.emit("debug",e)}_setResult(){let e;if(this.processExited){if(this.processError){e=new Error(`There was an error when attempting to execute the process '${this.toolPath}'. This may indicate the process failed to start. Error: ${this.processError}`)}else if(this.processExitCode!==0&&!this.options.ignoreReturnCode){e=new Error(`The process '${this.toolPath}' failed with exit code ${this.processExitCode}`)}else if(this.processStderr&&this.options.failOnStdErr){e=new Error(`The process '${this.toolPath}' failed because one or more lines were written to the STDERR stream`)}}if(this.timeout){clearTimeout(this.timeout);this.timeout=null}this.done=true;this.emit("done",e,this.processExitCode)}static HandleTimeout(e){if(e.done){return}if(!e.processClosed&&e.processExited){const t=`The STDIO streams did not close within ${e.delay/1e3} seconds of the exit event from process '${e.toolPath}'. This may indicate a child process inherited the STDIO streams and has not yet exited.`;e._debug(t)}e._setResult()}}},120:function(e,t,r){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;Object.defineProperty(e,n,{enumerable:true,get:function(){return t[r]}})}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var s=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r in e)if(r!=="default"&&Object.hasOwnProperty.call(e,r))n(t,e,r);i(t,e);return t};var o=this&&this.__awaiter||function(e,t,r,n){function adopt(e){return e instanceof r?e:new r((function(t){t(e)}))}return new(r||(r=Promise))((function(r,i){function fulfilled(e){try{step(n.next(e))}catch(e){i(e)}}function rejected(e){try{step(n["throw"](e))}catch(e){i(e)}}function step(e){e.done?r(e.value):adopt(e.value).then(fulfilled,rejected)}step((n=n.apply(e,t||[])).next())}))};var a;Object.defineProperty(t,"__esModule",{value:true});t.getCmdPath=t.tryGetExecutablePath=t.isRooted=t.isDirectory=t.exists=t.READONLY=t.UV_FS_O_EXLOCK=t.IS_WINDOWS=t.unlink=t.symlink=t.stat=t.rmdir=t.rm=t.rename=t.readlink=t.readdir=t.open=t.mkdir=t.lstat=t.copyFile=t.chmod=void 0;const c=s(r(896));const u=s(r(928));a=c.promises,t.chmod=a.chmod,t.copyFile=a.copyFile,t.lstat=a.lstat,t.mkdir=a.mkdir,t.open=a.open,t.readdir=a.readdir,t.readlink=a.readlink,t.rename=a.rename,t.rm=a.rm,t.rmdir=a.rmdir,t.stat=a.stat,t.symlink=a.symlink,t.unlink=a.unlink;t.IS_WINDOWS=process.platform==="win32";t.UV_FS_O_EXLOCK=268435456;t.READONLY=c.constants.O_RDONLY;function exists(e){return o(this,void 0,void 0,(function*(){try{yield t.stat(e)}catch(e){if(e.code==="ENOENT"){return false}throw e}return true}))}t.exists=exists;function isDirectory(e,r=false){return o(this,void 0,void 0,(function*(){const n=r?yield t.stat(e):yield t.lstat(e);return n.isDirectory()}))}t.isDirectory=isDirectory;function isRooted(e){e=normalizeSeparators(e);if(!e){throw new Error('isRooted() parameter "p" cannot be empty')}if(t.IS_WINDOWS){return e.startsWith("\\")||/^[A-Z]:/i.test(e)}return e.startsWith("/")}t.isRooted=isRooted;function tryGetExecutablePath(e,r){return o(this,void 0,void 0,(function*(){let n=undefined;try{n=yield t.stat(e)}catch(t){if(t.code!=="ENOENT"){console.log(`Unexpected error attempting to determine if executable file exists '${e}': ${t}`)}}if(n&&n.isFile()){if(t.IS_WINDOWS){const t=u.extname(e).toUpperCase();if(r.some((e=>e.toUpperCase()===t))){return e}}else{if(isUnixExecutable(n)){return e}}}const i=e;for(const s of r){e=i+s;n=undefined;try{n=yield t.stat(e)}catch(t){if(t.code!=="ENOENT"){console.log(`Unexpected error attempting to determine if executable file exists '${e}': ${t}`)}}if(n&&n.isFile()){if(t.IS_WINDOWS){try{const r=u.dirname(e);const n=u.basename(e).toUpperCase();for(const i of yield t.readdir(r)){if(n===i.toUpperCase()){e=u.join(r,i);break}}}catch(t){console.log(`Unexpected error attempting to determine the actual case of the file '${e}': ${t}`)}return e}else{if(isUnixExecutable(n)){return e}}}}return""}))}t.tryGetExecutablePath=tryGetExecutablePath;function normalizeSeparators(e){e=e||"";if(t.IS_WINDOWS){e=e.replace(/\//g,"\\");return e.replace(/\\\\+/g,"\\")}return e.replace(/\/\/+/g,"/")}function isUnixExecutable(e){return(e.mode&1)>0||(e.mode&8)>0&&e.gid===process.getgid()||(e.mode&64)>0&&e.uid===process.getuid()}function getCmdPath(){var e;return(e=process.env["COMSPEC"])!==null&&e!==void 0?e:`cmd.exe`}t.getCmdPath=getCmdPath},191:function(e,t,r){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;Object.defineProperty(e,n,{enumerable:true,get:function(){return t[r]}})}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var s=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r in e)if(r!=="default"&&Object.hasOwnProperty.call(e,r))n(t,e,r);i(t,e);return t};var o=this&&this.__awaiter||function(e,t,r,n){function adopt(e){return e instanceof r?e:new r((function(t){t(e)}))}return new(r||(r=Promise))((function(r,i){function fulfilled(e){try{step(n.next(e))}catch(e){i(e)}}function rejected(e){try{step(n["throw"](e))}catch(e){i(e)}}function step(e){e.done?r(e.value):adopt(e.value).then(fulfilled,rejected)}step((n=n.apply(e,t||[])).next())}))};Object.defineProperty(t,"__esModule",{value:true});t.findInPath=t.which=t.mkdirP=t.rmRF=t.mv=t.cp=void 0;const a=r(613);const c=s(r(928));const u=s(r(120));function cp(e,t,r={}){return o(this,void 0,void 0,(function*(){const{force:n,recursive:i,copySourceDirectory:s}=readCopyOptions(r);const o=(yield u.exists(t))?yield u.stat(t):null;if(o&&o.isFile()&&!n){return}const a=o&&o.isDirectory()&&s?c.join(t,c.basename(e)):t;if(!(yield u.exists(e))){throw new Error(`no such file or directory: ${e}`)}const d=yield u.stat(e);if(d.isDirectory()){if(!i){throw new Error(`Failed to copy. ${e} is a directory, but tried to copy without recursive flag.`)}else{yield cpDirRecursive(e,a,0,n)}}else{if(c.relative(e,a)===""){throw new Error(`'${a}' and '${e}' are the same file`)}yield copyFile(e,a,n)}}))}t.cp=cp;function mv(e,t,r={}){return o(this,void 0,void 0,(function*(){if(yield u.exists(t)){let n=true;if(yield u.isDirectory(t)){t=c.join(t,c.basename(e));n=yield u.exists(t)}if(n){if(r.force==null||r.force){yield rmRF(t)}else{throw new Error("Destination already exists")}}}yield mkdirP(c.dirname(t));yield u.rename(e,t)}))}t.mv=mv;function rmRF(e){return o(this,void 0,void 0,(function*(){if(u.IS_WINDOWS){if(/[*"<>|]/.test(e)){throw new Error('File path must not contain `*`, `"`, `<`, `>` or `|` on Windows')}}try{yield u.rm(e,{force:true,maxRetries:3,recursive:true,retryDelay:300})}catch(e){throw new Error(`File was unable to be removed ${e}`)}}))}t.rmRF=rmRF;function mkdirP(e){return o(this,void 0,void 0,(function*(){a.ok(e,"a path argument must be provided");yield u.mkdir(e,{recursive:true})}))}t.mkdirP=mkdirP;function which(e,t){return o(this,void 0,void 0,(function*(){if(!e){throw new Error("parameter 'tool' is required")}if(t){const t=yield which(e,false);if(!t){if(u.IS_WINDOWS){throw new Error(`Unable to locate executable file: ${e}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also verify the file has a valid extension for an executable file.`)}else{throw new Error(`Unable to locate executable file: ${e}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also check the file mode to verify the file is executable.`)}}return t}const r=yield findInPath(e);if(r&&r.length>0){return r[0]}return""}))}t.which=which;function findInPath(e){return o(this,void 0,void 0,(function*(){if(!e){throw new Error("parameter 'tool' is required")}const t=[];if(u.IS_WINDOWS&&process.env["PATHEXT"]){for(const e of process.env["PATHEXT"].split(c.delimiter)){if(e){t.push(e)}}}if(u.isRooted(e)){const r=yield u.tryGetExecutablePath(e,t);if(r){return[r]}return[]}if(e.includes(c.sep)){return[]}const r=[];if(process.env.PATH){for(const e of process.env.PATH.split(c.delimiter)){if(e){r.push(e)}}}const n=[];for(const i of r){const r=yield u.tryGetExecutablePath(c.join(i,e),t);if(r){n.push(r)}}return n}))}t.findInPath=findInPath;function readCopyOptions(e){const t=e.force==null?true:e.force;const r=Boolean(e.recursive);const n=e.copySourceDirectory==null?true:Boolean(e.copySourceDirectory);return{force:t,recursive:r,copySourceDirectory:n}}function cpDirRecursive(e,t,r,n){return o(this,void 0,void 0,(function*(){if(r>=255)return;r++;yield mkdirP(t);const i=yield u.readdir(e);for(const s of i){const i=`${e}/${s}`;const o=`${t}/${s}`;const a=yield u.lstat(i);if(a.isDirectory()){yield cpDirRecursive(i,o,r,n)}else{yield copyFile(i,o,n)}}yield u.chmod(t,(yield u.stat(e)).mode)}))}function copyFile(e,t,r){return o(this,void 0,void 0,(function*(){if((yield u.lstat(e)).isSymbolicLink()){try{yield u.lstat(t);yield u.unlink(t)}catch(e){if(e.code==="EPERM"){yield u.chmod(t,"0666");yield u.unlink(t)}}const r=yield u.readlink(e);yield u.symlink(r,t,u.IS_WINDOWS?"junction":null)}else if(!(yield u.exists(t))||r){yield u.copyFile(e,t)}}))}},26:function(e,t){(function(e,r){true?r(t):0})(this,(function(e){"use strict";const t=/^[v^~<>=]*?(\d+)(?:\.([x*]|\d+)(?:\.([x*]|\d+)(?:\.([x*]|\d+))?(?:-([\da-z\-]+(?:\.[\da-z\-]+)*))?(?:\+[\da-z\-]+(?:\.[\da-z\-]+)*)?)?)?$/i;const validateAndParse=e=>{if(typeof e!=="string"){throw new TypeError("Invalid argument expected string")}const r=e.match(t);if(!r){throw new Error(`Invalid argument not valid semver ('${e}' received)`)}r.shift();return r};const isWildcard=e=>e==="*"||e==="x"||e==="X";const tryParse=e=>{const t=parseInt(e,10);return isNaN(t)?e:t};const forceType=(e,t)=>typeof e!==typeof t?[String(e),String(t)]:[e,t];const compareStrings=(e,t)=>{if(isWildcard(e)||isWildcard(t))return 0;const[r,n]=forceType(tryParse(e),tryParse(t));if(r>n)return 1;if(r{for(let r=0;r{const r=validateAndParse(e);const n=validateAndParse(t);const i=r.pop();const s=n.pop();const o=compareSegments(r,n);if(o!==0)return o;if(i&&s){return compareSegments(i.split("."),s.split("."))}else if(i||s){return i?-1:1}return 0};const compare=(e,t,n)=>{assertValidOperator(n);const i=compareVersions(e,t);return r[n].includes(i)};const r={">":[1],">=":[0,1],"=":[0],"<=":[-1,0],"<":[-1],"!=":[-1,1]};const n=Object.keys(r);const assertValidOperator=e=>{if(typeof e!=="string"){throw new TypeError(`Invalid operator type, expected string but got ${typeof e}`)}if(n.indexOf(e)===-1){throw new Error(`Invalid operator, expected one of ${n.join("|")}`)}};const satisfies=(e,t)=>{t=t.replace(/([><=]+)\s+/g,"$1");if(t.includes("||")){return t.split("||").some((t=>satisfies(e,t)))}else if(t.includes(" - ")){const[r,n]=t.split(" - ",2);return satisfies(e,`>=${r} <=${n}`)}else if(t.includes(" ")){return t.trim().replace(/\s{2,}/g," ").split(" ").every((t=>satisfies(e,t)))}const r=t.match(/^([<>=~^]+)/);const n=r?r[1]:"=";if(n!=="^"&&n!=="~")return compare(e,t,n);const[i,s,o,,a]=validateAndParse(e);const[c,u,d,,l]=validateAndParse(t);const f=[i,s,o];const p=[c,u!==null&&u!==void 0?u:"x",d!==null&&d!==void 0?d:"x"];if(l){if(!a)return false;if(compareSegments(f,p)!==0)return false;if(compareSegments(a.split("."),l.split("."))===-1)return false}const h=p.findIndex((e=>e!=="0"))+1;const w=n==="~"?2:h>1?h:1;if(compareSegments(f.slice(0,w),p.slice(0,w))!==0)return false;if(compareSegments(f.slice(w),p.slice(w))===-1)return false;return true};const validate=e=>typeof e==="string"&&/^[v\d]/.test(e)&&t.test(e);const validateStrict=e=>typeof e==="string"&&/^(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-]+)*))?$/.test(e);e.compare=compare;e.compareVersions=compareVersions;e.satisfies=satisfies;e.validate=validate;e.validateStrict=validateStrict}))},613:e=>{"use strict";e.exports=require("assert")},317:e=>{"use strict";e.exports=require("child_process")},434:e=>{"use strict";e.exports=require("events")},896:e=>{"use strict";e.exports=require("fs")},857:e=>{"use strict";e.exports=require("os")},928:e=>{"use strict";e.exports=require("path")},193:e=>{"use strict";e.exports=require("string_decoder")},557:e=>{"use strict";e.exports=require("timers")}};var t={};function __nccwpck_require__(r){var n=t[r];if(n!==undefined){return n.exports}var i=t[r]={exports:{}};var s=true;try{e[r].call(i.exports,i,i.exports,__nccwpck_require__);s=false}finally{if(s)delete t[r]}return i.exports}if(typeof __nccwpck_require__!=="undefined")__nccwpck_require__.ab=__dirname+"/";var r=__nccwpck_require__(755);module.exports=r})(); \ No newline at end of file diff --git a/src/tools.ts b/src/tools.ts index 3d15072c..ea493122 100644 --- a/src/tools.ts +++ b/src/tools.ts @@ -5,14 +5,94 @@ import * as fetch from './fetch'; import * as packagist from './packagist'; import * as utils from './utils'; -type RS = Record; -type RSRS = Record; +/** + * Valid function names for custom tool handlers + */ +type ToolFunction = + | 'castor' + | 'composer' + | 'deployer' + | 'dev_tools' + | 'phive' + | 'blackfire_player' + | 'pecl' + | 'phing' + | 'phpunit' + | 'phpcpd' + | 'wp_cli'; -interface IRef { +/** + * Tool data interface containing all properties for tool installation + */ +export interface ToolData { + tool: string; + version: string; + os: string; + php_version: string; + github: string; + domain: string; + extension: string; + repository: string; + prefix: string; + verb: string; + fetch_latest: 'true' | 'false'; + scope: string; + version_parameter: string; + version_prefix: string; + release: string; + packagist: string; + type?: string; + function?: ToolFunction; + alias?: string; + url: string; + uri?: string; + error?: string; +} + +/** + * Input type for functions that may receive partial/unresolved tool data + * Used by getUrl, getLatestVersion etc. before version is fully resolved + */ +export type ToolInput = Omit & {version?: string}; + +/** + * Partial tool data from tools.json configuration + */ +interface ToolConfig { + tool?: string; + repository?: string; + type?: string; + function?: ToolFunction; + alias?: string; + domain?: string; + extension?: string; + fetch_latest?: 'true' | 'false'; + scope?: string; + version_parameter?: string; + version_prefix?: string; + packagist?: string; +} + +/** + * GitHub reference object from API response + */ +interface GitHubRef { ref: string; node_id: string; url: string; - object: RS; + object: { + sha: string; + type: string; + url: string; + }; +} + +/** + * Deployer manifest entry + */ +interface DeployerManifestEntry { + version: string; + url: string; } /** @@ -20,7 +100,7 @@ interface IRef { * * @param data */ -export async function getSemverVersion(data: RS): Promise { +export async function getSemverVersion(data: ToolData): Promise { const fixSemver = (t: string): string => { if (/^\d+\.\d+\.\d+(-|$)/.test(t)) return t; const m = t.match(/^(\d+\.\d+\.\d+)([A-Za-z]+[0-9A-Za-z.]+)$/); @@ -31,14 +111,16 @@ export async function getSemverVersion(data: RS): Promise { const github_token: string = (await utils.readEnv('GITHUB_TOKEN')) || (await utils.readEnv('COMPOSER_TOKEN')); - const response: RS = await fetch.fetch(url, github_token); + const response = await fetch.fetch(url, github_token); if (response.error || response.data === '[]') { - data['error'] = response.error ?? `No version found with prefix ${search}.`; - return data['version']; + data.error = response.error ?? `No version found with prefix ${search}.`; + return data.version; } else { - const refs: IRef[] = JSON.parse(response['data']); + const refs: GitHubRef[] = JSON.parse(response.data); const tags = refs - .map((i: IRef) => (i.ref?.split('/').pop() ?? '').replace(/^v(?=\d)/, '')) + .map((i: GitHubRef) => + (i.ref?.split('/').pop() ?? '').replace(/^v(?=\d)/, '') + ) .filter((t: string) => t.length > 0); const fixedToOriginal = new Map(); const fixed = tags.map(t => { @@ -62,16 +144,19 @@ export async function getSemverVersion(data: RS): Promise { * * @param data */ -export async function getLatestVersion(data: RS): Promise { - if (!data['version'] && data['fetch_latest'] === 'false') { +export async function getLatestVersion(data: ToolInput): Promise { + if (!data.version && data.fetch_latest === 'false') { return 'latest'; } - const resp: Record = await fetch.fetch( - `${data['github']}/${data['repository']}/releases.atom` + if (data.fetch_latest === 'true' && !data.repository) { + return 'latest'; + } + const resp = await fetch.fetch( + `${data.github}/${data.repository}/releases.atom` ); - if (resp['data']) { + if (resp.data) { const releases: string[] = [ - ...resp['data'].matchAll(/releases\/tag\/([a-zA-Z]*)?(\d+.\d+.\d+)"/g) + ...resp.data.matchAll(/releases\/tag\/([a-zA-Z]*)?(\d+\.\d+\.\d+)"/g) ].map(match => match[2]); const sorted = releases.toSorted((a: string, b: string) => @@ -88,26 +173,29 @@ export async function getLatestVersion(data: RS): Promise { * @param version * @param data */ -export async function getVersion(version: string, data: RS): Promise { +export async function getVersion( + version: string, + data: ToolData +): Promise { // semver_regex - https://semver.org/ 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])$/; + const composer_regex = /^composer:(stable|preview|snapshot|[12])$/; const constraint_regex = /[><=^~]+.*/; const major_minor_regex = /^\d+(\.\d+)?$/; - data['version'] = version.replace(/v?(\d)/, '$1').replace(/\.x/, ''); + data.version = version.replace(/v?(\d)/, '$1').replace(/\.x/, ''); switch (true) { - case composer_regex.test(data['release']): - case semver_regex.test(data['version']): - case constraint_regex.test(data['version']) && data['type'] === 'composer': - return data['version']; - case major_minor_regex.test(data['version']) && data['type'] === 'composer': - data['release'] = `${data['tool']}:${data['version']}.*`; - return `${data['version']}.*`; - case data['repository'] && major_minor_regex.test(data['version']): + case composer_regex.test(data.release): + case semver_regex.test(data.version): + case constraint_regex.test(data.version) && data.type === 'composer': + return data.version; + case major_minor_regex.test(data.version) && data.type === 'composer': + data.release = `${data.tool}:${data.version}.*`; + return `${data.version}.*`; + case !!data.repository && major_minor_regex.test(data.version): return await getSemverVersion(data); default: - return data['version'].replace(/[><=^~]*/, ''); + return data.version.replace(/[><=^~]*/, ''); } } @@ -117,11 +205,14 @@ export async function getVersion(version: string, data: RS): Promise { * @param release * @param data */ -export async function getRelease(release: string, data: RS): Promise { +export async function getRelease( + release: string, + data: ToolData +): Promise { release = release.includes('/') ? release.split('/')[1] : release; return release.includes(':') - ? [data['tool'], release.split(':')[1]].join(':') - : data['tool']; + ? [data.tool, release.split(':')[1]].join(':') + : data.tool; } /** @@ -152,26 +243,26 @@ export async function filterList(tools_list: string[]): Promise { * * @param data */ -export async function getUrl(data: RS): Promise { - if ((data['version'] ?? 'latest') === 'latest') { +export async function getUrl(data: ToolInput): Promise { + if ((data.version ?? 'latest') === 'latest') { return [ - data['domain'], - data['repository'], - data['prefix'], - data['version'], - data['verb'], - data['tool'] + data['extension'] + data.domain, + data.repository, + data.prefix, + data.version, + data.verb, + data.tool + data.extension ] .filter(Boolean) .join('/'); } else { return [ - data['domain'], - data['repository'], - data['prefix'], - data['verb'], - data['version_prefix'] + data['version'], - data['tool'] + data['extension'] + data.domain, + data.repository, + data.prefix, + data.verb, + data.version_prefix + data.version, + data.tool + data.extension ] .filter(Boolean) .join('/'); @@ -183,17 +274,17 @@ export async function getUrl(data: RS): Promise { * * @param data */ -export async function getPharUrl(data: RS): Promise { - if (data['version'] === 'latest') { - return data['domain'] + '/' + data['tool'] + '.phar'; +export async function getPharUrl(data: ToolData): Promise { + if (data.version === 'latest') { + return data.domain + '/' + data.tool + '.phar'; } else { return ( - data['domain'] + + data.domain + '/' + - data['tool'] + + data.tool + '-' + - data['version_prefix'] + - data['version'] + + data.version_prefix + + data.version + '.phar' ); } @@ -204,10 +295,10 @@ export async function getPharUrl(data: RS): Promise { * * @param data */ -export async function addArchive(data: RS): Promise { +export async function addArchive(data: ToolData): Promise { return ( - (await utils.getCommand(data['os'], 'tool')) + - (await utils.joins(data['url'], data['tool'], data['version_parameter'])) + (await utils.getCommand(data.os, 'tool')) + + (await utils.joins(data.url, data.tool, data.version_parameter)) ); } @@ -216,14 +307,14 @@ export async function addArchive(data: RS): Promise { * * @param data */ -export async function addPackage(data: RS): Promise { - const command = await utils.getCommand(data['os'], 'composer_tool'); - const parts: string[] = data['repository'].split('/'); +export async function addPackage(data: ToolData): Promise { + const command = await utils.getCommand(data.os, 'composer_tool'); + const parts: string[] = data.repository.split('/'); const args: string = await utils.joins( parts[1], - data['release'], + data.release, parts[0] + '/', - data['scope'] + data.scope ); return command + args; } @@ -233,24 +324,24 @@ export async function addPackage(data: RS): Promise { * * @param data */ -export async function addBlackfirePlayer(data: RS): Promise { - switch (data['os']) { +export async function addBlackfirePlayer(data: ToolData): Promise { + switch (data.os) { case 'win32': return await utils.addLog( '$cross', - data['tool'], - data['tool'] + ' is not a windows tool', + data.tool, + data.tool + ' is not a windows tool', 'win32' ); default: - if (data['version'] == 'latest') { - if (/5\.[5-6]|7\.0/.test(data['php_version'])) { - data['version'] = '1.9.3'; - } else if (/7\.[1-4]|8\.0/.test(data['php_version'])) { - data['version'] = '1.22.0'; + if (data.version == 'latest') { + if (/5\.[5-6]|7\.0/.test(data.php_version)) { + data.version = '1.9.3'; + } else if (/7\.[1-4]|8\.0/.test(data.php_version)) { + data.version = '1.22.0'; } } - data['url'] = await getPharUrl(data); + data.url = await getPharUrl(data); return addArchive(data); } } @@ -260,12 +351,12 @@ export async function addBlackfirePlayer(data: RS): Promise { * * @param data */ -export async function addCastor(data: RS): Promise { - data['tool'] = 'castor.' + data['os'].replace('win32', 'windows') + '-amd64'; - data['url'] = await getUrl(data); - data['tool'] = 'castor'; - data['version_parameter'] = fs.existsSync('castor.php') - ? data['version_parameter'] +export async function addCastor(data: ToolData): Promise { + data.tool = 'castor.' + data.os.replace('win32', 'windows') + '-amd64'; + data.url = await getUrl(data); + data.tool = 'castor'; + data.version_parameter = fs.existsSync('castor.php') + ? data.version_parameter : ''; return await addArchive(data); } @@ -275,18 +366,18 @@ export async function addCastor(data: RS): Promise { * * @param data */ -export async function addComposer(data: RS): Promise { - const channel = data['version'].replace('latest', 'stable'); - const github = data['github']; - const getcomposer = data['domain']; +export async function addComposer(data: ToolData): Promise { + const channel = data.version.replace('latest', 'stable'); + const github = data.github; + const getcomposer = data.domain; const cds = 'https://dl.cloudsmith.io'; const spc = 'https://artifacts.setup-php.com'; - const filename = `composer-${data['php_version']}-${channel}.phar`; + const filename = `composer-${data.php_version}-${channel}.phar`; const releases_url = `${github}/shivammathur/composer-cache/releases/latest/download/${filename}`; const cds_url = `${cds}/public/shivammathur/composer-cache/raw/files/${filename}`; const spc_url = `${spc}/composer/${filename}`; const lts_url = `${getcomposer}/download/latest-2.2.x/composer.phar`; - const is_lts = /^5\.[3-6]$|^7\.[0-1]$/.test(data['php_version']); + const is_lts = /^5\.[3-6]$|^7\.[0-1]$/.test(data.php_version); const channel_source_url = `${getcomposer}/composer-${channel}.phar`; const version_source_url = `${getcomposer}/download/${channel}/composer.phar`; let cache_url = `${releases_url},${spc_url},${cds_url}`; @@ -301,16 +392,16 @@ export async function addComposer(data: RS): Promise { case /^1$/.test(channel): source_url = channel_source_url; break; - case /^\d+\.\d+\.\d+[\w-]*$/.test(data['version']): - cache_url = `${github}/${data['repository']}/releases/download/${data['version']}/composer.phar`; + case /^\d+\.\d+\.\d+[\w-]*$/.test(data.version): + cache_url = `${github}/${data.repository}/releases/download/${data.version}/composer.phar`; source_url = version_source_url; break; default: source_url = is_lts ? lts_url : channel_source_url; } const use_cache: boolean = (await utils.readEnv('NO_TOOLS_CACHE')) !== 'true'; - data['url'] = use_cache ? `${cache_url},${source_url}` : source_url; - data['version_parameter'] = data['version']; + data.url = use_cache ? `${cache_url},${source_url}` : source_url; + data.version_parameter = data.version; return await addArchive(data); } @@ -319,27 +410,27 @@ export async function addComposer(data: RS): Promise { * * @param data */ -export async function addDeployer(data: RS): Promise { - if (data['version'] === 'latest') { - data['url'] = data['domain'] + '/deployer.phar'; +export async function addDeployer(data: ToolData): Promise { + if (data.version === 'latest') { + data.url = data.domain + '/deployer.phar'; } else { - const manifest: RS = await fetch.fetch( - 'https://deployer.org/manifest.json' + const manifest = await fetch.fetch('https://deployer.org/manifest.json'); + const version_data: Record = JSON.parse( + manifest.data ); - const version_data: RSRS = JSON.parse(manifest.data); const version_key: string | undefined = Object.keys(version_data).find( (key: string) => { - return version_data[key]['version'] === data['version']; + return version_data[key].version === data.version; } ); if (version_key) { - data['url'] = version_data[version_key]['url']; + data.url = version_data[version_key].url; } else { return await utils.addLog( '$cross', 'deployer', 'Version missing in deployer manifest', - data['os'] + data.os ); } } @@ -351,22 +442,22 @@ export async function addDeployer(data: RS): Promise { * * @param data */ -export async function addDevTools(data: RS): Promise { - switch (data['os']) { +export async function addDevTools(data: ToolData): Promise { + switch (data.os) { case 'linux': case 'darwin': - return 'add_devtools ' + data['tool']; + return 'add_devtools ' + data.tool; case 'win32': return await utils.addLog( '$tick', - data['tool'], - data['tool'] + ' is not a windows tool', + data.tool, + data.tool + ' is not a windows tool', 'win32' ); default: return await utils.log( - 'Platform ' + data['os'] + ' is not supported', - data['os'], + 'Platform ' + data.os + ' is not supported', + data.os, 'error' ); } @@ -377,8 +468,8 @@ export async function addDevTools(data: RS): Promise { * * @param data */ -export async function addPECL(data: RS): Promise { - return await utils.getCommand(data['os'], 'pecl'); +export async function addPECL(data: ToolData): Promise { + return await utils.getCommand(data.os, 'pecl'); } /** @@ -386,14 +477,13 @@ export async function addPECL(data: RS): Promise { * * @param data */ -export async function addPhing(data: RS): Promise { - data['url'] = - data['domain'] + '/get/phing-' + data['version'] + data['extension']; - if (data['version'] != 'latest') { - [data['prefix'], data['verb']] = ['releases', 'download']; - data['domain'] = data['github']; - data['extension'] = '-' + data['version'] + data['extension']; - data['url'] += ',' + (await getUrl(data)); +export async function addPhing(data: ToolData): Promise { + data.url = data.domain + '/get/phing-' + data.version + data.extension; + if (data.version != 'latest') { + [data.prefix, data.verb] = ['releases', 'download']; + data.domain = data.github; + data.extension = '-' + data.version + data.extension; + data.url += ',' + (await getUrl(data)); } return await addArchive(data); } @@ -403,33 +493,33 @@ export async function addPhing(data: RS): Promise { * * @param data */ -export async function addPhive(data: RS): Promise { +export async function addPhive(data: ToolData): Promise { switch (true) { - case /5\.[3-5]/.test(data['php_version']): + case /5\.[3-5]/.test(data.php_version): return await utils.addLog( '$cross', 'phive', - 'Phive is not supported on PHP ' + data['php_version'], - data['os'] + 'Phive is not supported on PHP ' + data.php_version, + data.os ); - case /5\.6|7\.0/.test(data['php_version']): - data['version'] = '0.12.1'; + case /5\.6|7\.0/.test(data.php_version): + data.version = '0.12.1'; break; - case /7\.1/.test(data['php_version']): - data['version'] = '0.13.5'; + case /7\.1/.test(data.php_version): + data.version = '0.13.5'; break; - case /7\.2/.test(data['php_version']): - data['version'] = '0.14.5'; + case /7\.2/.test(data.php_version): + data.version = '0.14.5'; break; - case /7\.3|7\.4/.test(data['php_version']): - data['version'] = '0.15.3'; + case /7\.3|7\.4/.test(data.php_version): + data.version = '0.15.3'; break; - case /^latest$/.test(data['version']): - data['version'] = await getLatestVersion(data); + case /^latest$/.test(data.version): + data.version = await getLatestVersion(data); break; } - data['extension'] = '-' + data['version'] + data['extension']; - data['url'] = await getUrl(data); + data.extension = '-' + data.version + data.extension; + data.url = await getUrl(data); return await addArchive(data); } @@ -438,16 +528,15 @@ export async function addPhive(data: RS): Promise { * * @param data */ -export async function addPHPUnitTools(data: RS): Promise { +export async function addPHPUnitTools(data: ToolData): Promise { /* istanbul ignore next */ - if (data['version'] === 'latest') { - data['version'] = - (await packagist.search(data['packagist'], data['php_version'])) ?? - 'latest'; + if (data.version === 'latest') { + data.version = + (await packagist.search(data.packagist, data.php_version)) ?? 'latest'; } - data['url'] = await getPharUrl(data); - if (data['url'].match(/-\d+/)) { - data['url'] += ',' + data['url'].replace(/-(\d+)\.\d+\.\d+/, '-$1'); + data.url = await getPharUrl(data); + if (data.url.match(/-\d+/)) { + data.url += ',' + data.url.replace(/-(\d+)\.\d+\.\d+/, '-$1'); } return await addArchive(data); } @@ -457,13 +546,13 @@ export async function addPHPUnitTools(data: RS): Promise { * * @param data */ -export async function addWPCLI(data: RS): Promise { - if (data['version'] === 'latest') { - data['uri'] = 'wp-cli/builds/blob/gh-pages/phar/wp-cli.phar?raw=true'; - data['url'] = [data['domain'], data['uri']].join('/'); +export async function addWPCLI(data: ToolData): Promise { + if (data.version === 'latest') { + data.uri = 'wp-cli/builds/blob/gh-pages/phar/wp-cli.phar?raw=true'; + data.url = [data.domain, data.uri].join('/'); } else { - data['extension'] = '-' + data['version'] + data['extension']; - data['url'] = await getUrl(data); + data.extension = '-' + data.version + data.extension; + data.url = await getUrl(data); } return await addArchive(data); } @@ -479,56 +568,74 @@ export async function getData( release: string, php_version: string, os: string -): Promise { +): Promise { const json_file_path = path.join(__dirname, '../src/configs/tools.json'); const json_file: string = fs.readFileSync(json_file_path, 'utf8'); - const json_objects: RSRS = JSON.parse(json_file); + const json_objects: Record = JSON.parse(json_file); release = release.replace(/\s+/g, ''); const parts: string[] = release.split(':'); const tool = parts[0]; const version = parts[1]; - let data: RS; + let config: ToolConfig & {tool: string}; if (Object.hasOwn(json_objects, tool)) { - data = json_objects[tool]; - data['tool'] = tool; + config = {...json_objects[tool], tool}; } else { const key: string | undefined = Object.keys(json_objects).find( (key: string) => { - return json_objects[key]['alias'] == tool; + return json_objects[key].alias == tool; } ); if (key) { - data = json_objects[key]; - data['tool'] = key; - } else { - data = { + config = {...json_objects[key], tool: key}; + } else if (tool.includes('/')) { + config = { tool: tool.split('/')[1], repository: tool, type: 'composer' }; - data = !tool.includes('/') ? {tool: tool} : data; + } else { + config = {tool}; } } - data['github'] = 'https://github.com'; - data['domain'] ??= data['github']; - data['extension'] ??= '.phar'; - data['os'] = os; - data['php_version'] = php_version; - data['packagist'] ??= data['repository']; - data['prefix'] = data['github'] === data['domain'] ? 'releases' : ''; - data['verb'] = data['github'] === data['domain'] ? 'download' : ''; - data['fetch_latest'] ??= 'false'; - data['scope'] ??= 'global'; - data['version_parameter'] = JSON.stringify(data['version_parameter']) || ''; - data['version_prefix'] ??= ''; - data['release'] = await getRelease(release, data); - data['version'] = version + const github = 'https://github.com'; + const domain = config.domain ?? github; + const data: ToolData = { + tool: config.tool, + version: '', + url: '', + os, + php_version, + github, + domain, + extension: config.extension ?? '.phar', + repository: config.repository ?? '', + prefix: domain === github ? 'releases' : '', + verb: domain === github ? 'download' : '', + fetch_latest: config.fetch_latest ?? 'false', + scope: config.scope ?? 'global', + version_parameter: + config.version_parameter != null + ? JSON.stringify(config.version_parameter) + : '', + version_prefix: config.version_prefix ?? '', + release: '', + packagist: config.packagist ?? config.repository ?? '', + type: config.type, + function: config.function, + alias: config.alias + }; + data.release = await getRelease(release, data); + data.version = version ? await getVersion(version, data) : await getLatestVersion(data); + data.url = await getUrl(data); return data; } -export const functionRecord: Record Promise> = { +export const functionRecord: Record< + ToolFunction, + (data: ToolData) => Promise +> = { castor: addCastor, composer: addComposer, deployer: addDeployer, @@ -562,43 +669,46 @@ export async function addTools( } const tools_list = await filterList(await utils.CSVArray(tools_csv)); await utils.asyncForEach(tools_list, async function (release: string) { - const data: RS = await getData(release, php_version, os); + const data: ToolData = await getData(release, php_version, os); script += '\n'; switch (true) { - case data['error'] !== undefined: - script += await utils.addLog( - '$cross', - data['tool'], - data['error'], - data['os'] - ); + case data.error !== undefined: + script += await utils.addLog('$cross', data.tool, data.error, data.os); break; - case 'phar' === data['type']: - data['url'] = await getUrl(data); + case 'phar' === data.type: script += await addArchive(data); break; - case 'composer' === data['type']: + case 'composer' === data.type: script += await addPackage(data); break; - case 'custom-package' === data['type']: + case 'custom-package' === data.type: script += await utils.customPackage( - data['tool'].split('-')[0], + data.tool.split('-')[0], 'tools', - data['version'], - data['os'] + data.version, + data.os ); break; - case 'custom-function' === data['type']: - script += await functionRecord[data['function']](data); + case 'custom-function' === data.type: + if (!data.function) { + script += await utils.addLog( + '$cross', + data.tool, + data.tool + ' has no function defined. Please report this issue.', + data.os + ); + } else { + script += await functionRecord[data.function](data); + } break; - case /^none$/.test(data['tool']): + case /^none$/.test(data.tool): break; default: script += await utils.addLog( '$cross', - data['tool'], - 'Tool ' + data['tool'] + ' is not supported', - data['os'] + data.tool, + 'Tool ' + data.tool + ' is not supported', + data.os ); break; }