diff --git a/package.json b/package.json index 3885966..d02bcd5 100644 --- a/package.json +++ b/package.json @@ -519,9 +519,10 @@ "dayjs": "^1.11.7", "detect-indent": "^6.0.0", "find-up": "^5.0.0", + "mem": "^8.1.1", "phpfmt": "^0.0.2", "pjson": "^1.0.9", "tslib": "^2.5.0", "use-phpfmt": "^0.0.1" } -} \ No newline at end of file +} diff --git a/src/PHPFmt.ts b/src/PHPFmt.ts index d332ca8..aa6bf6d 100644 --- a/src/PHPFmt.ts +++ b/src/PHPFmt.ts @@ -111,20 +111,26 @@ export class PHPFmt { } public async format(text: string): Promise { - if (!this.config.use_old_phpfmt) { - const passes = [...this.config.passes, ...this.config.exclude]; - const transformations = await this.transformation.getTransformations(); - if (passes.length > 0) { - const invalidPasses = passes.filter( - pass => - !transformations.some(transformation => transformation.key === pass) - ); - if (invalidPasses.length > 0) { - throw new PHPFmtError( - `passes or exclude invalid: ${invalidPasses.join(', ')}` - ); + const passes = [...this.config.passes, ...this.config.exclude]; + const transformations = await this.transformation.getTransformations(); + if (passes.length > 0) { + const invalidPasses: string[] = []; + for (const pass of passes) { + if ( + !transformations.some( + transformation => transformation.key === pass + ) && + !(await this.transformation.isExists(pass)) + ) { + invalidPasses.push(pass); } } + + if (invalidPasses.length > 0) { + throw new PHPFmtError( + `passes or exclude invalid: ${invalidPasses.join(', ')}` + ); + } } if (this.config.detect_indent) { diff --git a/src/Transformation.ts b/src/Transformation.ts index a9e1429..0576a75 100644 --- a/src/Transformation.ts +++ b/src/Transformation.ts @@ -1,4 +1,6 @@ import os from 'os'; +import fs from 'fs'; +import mem from 'mem'; import type { TransformationItem } from './types'; import { exec } from './utils'; @@ -6,23 +8,31 @@ export class Transformation { public constructor( private readonly phpBin: string, private readonly pharPath: string - ) {} + ) { + this.getTransformations = mem(this.getTransformations, { + cacheKey: this.getCacheKey + }); + this.getPharContent = mem(this.getPharContent, { + cacheKey: this.getCacheKey + }); + this.isExists = mem(this.isExists, { + cacheKey: this.getCacheKey + }); + } private get baseCmd(): string { return `${this.phpBin} "${this.pharPath}"`; } - private static transformations: Record = {}; + private readonly getCacheKey = (args: any[]): string => { + return JSON.stringify([this.pharPath, args]); + }; public async getTransformations(): Promise { - if (Transformation.transformations[this.pharPath]?.length > 0) { - return Transformation.transformations[this.pharPath]; - } - try { const { stdout } = await exec(`${this.baseCmd} --list-simple`); - Transformation.transformations[this.pharPath] = stdout + return stdout .trim() .split(os.EOL) .map(v => { @@ -36,7 +46,6 @@ export class Transformation { .trim() }; }); - return Transformation.transformations[this.pharPath]; } catch (err) { return []; } @@ -55,4 +64,17 @@ export class Transformation { return ''; } } + + private async getPharContent(): Promise { + const content = String(await fs.promises.readFile(this.pharPath)); + return content; + } + + public async isExists(name: string): Promise { + const regex = new RegExp( + `class\\s+${name}\\s+extends\\s+(FormatterPass|AdditionalPass)\\s*\\{` + ); + + return regex.test(await this.getPharContent()); + } } diff --git a/yarn.lock b/yarn.lock index 98e7043..e6d0166 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1931,6 +1931,13 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" +map-age-cleaner@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" + integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w== + dependencies: + p-defer "^1.0.0" + map-obj@^1.0.0: version "1.0.1" resolved "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" @@ -1941,6 +1948,14 @@ map-obj@^4.1.0: resolved "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz#9304f906e93faae70880da102a9f1df0ea8bb05a" integrity sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ== +mem@^8.1.1: + version "8.1.1" + resolved "https://registry.yarnpkg.com/mem/-/mem-8.1.1.tgz#cf118b357c65ab7b7e0817bdf00c8062297c0122" + integrity sha512-qFCFUDs7U3b8mBDPyz5EToEKoAkgCzqquIgi9nkkR9bixxOVOre+09lbuH7+9Kn2NFpm56M3GUWVbU2hQgdACA== + dependencies: + map-age-cleaner "^0.1.3" + mimic-fn "^3.1.0" + meow@^10.1.2: version "10.1.5" resolved "https://registry.npmjs.org/meow/-/meow-10.1.5.tgz#be52a1d87b5f5698602b0f32875ee5940904aa7f" @@ -1982,6 +1997,11 @@ mimic-fn@^2.1.0: resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== +mimic-fn@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-3.1.0.tgz#65755145bbf3e36954b949c16450427451d5ca74" + integrity sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ== + min-indent@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" @@ -2225,6 +2245,11 @@ os-homedir@^1.0.0: resolved "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" integrity sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ== +p-defer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" + integrity sha512-wB3wfAxZpk2AzOfUMJNL+d36xothRSyj8EXOa4f6GMqYDN9BJaaSISbsk+wS9abmnebVw95C2Kb5t85UmpCxuw== + p-finally@^2.0.0: version "2.0.1" resolved "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz#bd6fcaa9c559a096b680806f4d657b3f0f240561"