From cb776d873aa1fbd19771f6d49a6c08b2e67ddeaa Mon Sep 17 00:00:00 2001 From: Daniel Tschinder <231804+danez@users.noreply.github.com> Date: Fri, 18 Nov 2022 23:55:04 +0100 Subject: [PATCH] fix: handle version for frameworks which are not detected by npm package --- src/core.js | 6 +- src/main.js | 36 +++++----- test/fixtures/package.json | 3 + test/main.js | 5 ++ test/snapshots/main.js.md | 130 ++++++++++++++++++++++++------------ test/snapshots/main.js.snap | Bin 1862 -> 2110 bytes 6 files changed, 116 insertions(+), 64 deletions(-) create mode 100644 test/fixtures/package.json diff --git a/src/core.js b/src/core.js index a6488424..b9588622 100644 --- a/src/core.js +++ b/src/core.js @@ -63,7 +63,7 @@ const getContext = (context) => { * * @param {Context} context - Context * - * @returns {Framework[]} frameworks - Frameworks used by a project + * @returns {Promise} frameworks - Frameworks used by a project */ export const listFrameworks = async function (context) { const { pathExists, packageJson, packageJsonPath, nodeVersion } = getContext(context) @@ -85,7 +85,7 @@ export const listFrameworks = async function (context) { * @param {string} frameworkId - Id such as `"gatsby"` * @param {Context} [context] - Context * - * @returns {boolean} result - Whether the project uses this framework + * @returns {Promise} result - Whether the project uses this framework */ export const hasFramework = async function (frameworkId, context) { const framework = getFrameworkById(frameworkId) @@ -101,7 +101,7 @@ export const hasFramework = async function (frameworkId, context) { * @param {string} frameworkId - Id such as `"gatsby"` * @param {Context} [context] - Context * - * @returns {Framework} framework - Framework used by a project + * @returns {Promise} framework - Framework used by a project */ export const getFramework = async function (frameworkId, context) { const framework = getFrameworkById(frameworkId) diff --git a/src/main.js b/src/main.js index 4712f5c3..873c6d8a 100644 --- a/src/main.js +++ b/src/main.js @@ -1,5 +1,5 @@ import { join } from 'path' -import { cwd, chdir } from 'process' +import { cwd } from 'process' import { findUp } from 'find-up' @@ -53,28 +53,22 @@ import { listFrameworks as list, hasFramework as has, getFramework as get } from * @returns {Promise} */ const getFrameworkVersion = async (projectDir, frameworkInfo) => { - // Need to change the CWD to the project directory in order to make sure we find and use the correct - // package.json - const originalCwd = cwd() - const returnToOriginalDirectory = () => { - chdir(originalCwd) + if (!frameworkInfo.package || !frameworkInfo.package.name) { + return frameworkInfo } - chdir(projectDir) const npmPackage = frameworkInfo.package.name // Get path of package.json for the installed framework. We need to traverse up the directories // in the event that the project uses something like npm workspaces, and the installed framework package // has been hoisted to the root directory of the project (which differs from the directory of the project/application being built) - const installedFrameworkPath = await findUp(join('node_modules', npmPackage, 'package.json')) + const installedFrameworkPath = await findUp(join('node_modules', npmPackage, 'package.json'), { cwd: projectDir }) const { packageJson } = await getPackageJson(installedFrameworkPath) - returnToOriginalDirectory() - return { ...frameworkInfo, package: { - name: frameworkInfo.package.name, + name: npmPackage, version: packageJson.version || 'unknown', }, } @@ -85,7 +79,7 @@ const getFrameworkVersion = async (projectDir, frameworkInfo) => { * * @param {Options} options - Options * - * @returns {Framework[]} frameworks - Frameworks used by a project + * @returns {Promise} frameworks - Frameworks used by a project */ export const listFrameworks = async function (opts) { const context = await getContext(opts) @@ -96,7 +90,13 @@ export const listFrameworks = async function (opts) { const settledPromises = await Promise.allSettled( frameworkList.map((framework) => getFrameworkVersion(projectDir, framework)), ) - const updatedList = settledPromises.map((result) => result.value) + const updatedList = settledPromises.map((result) => { + if (result.status === 'fulfilled') { + return result.value + } + + throw result.reason + }) return updatedList } @@ -107,22 +107,22 @@ export const listFrameworks = async function (opts) { * @param {string} frameworkId - Id such as `"gatsby"` * @param {Options} [options] - Context * - * @returns {boolean} result - Whether the project uses this framework + * @returns {Promise} result - Whether the project uses this framework */ export const hasFramework = async function (frameworkId, options) { const context = await getContext(options) - return await has(frameworkId, context) + return has(frameworkId, context) } /** * Return some information about a framework used by a project. * * @param {string} frameworkId - Id such as `"gatsby"` - * @param {Context} [context] - Context + * @param {Options} [options] - Context * - * @returns {Framework} framework - Framework used by a project + * @returns {Promise} framework - Framework used by a project */ export const getFramework = async function (frameworkId, options) { const context = await getContext(options) - return await get(frameworkId, context) + return get(frameworkId, context) } diff --git a/test/fixtures/package.json b/test/fixtures/package.json new file mode 100644 index 00000000..561cc98b --- /dev/null +++ b/test/fixtures/package.json @@ -0,0 +1,3 @@ +{ + "description": "This is only here so fixtures never reach outside of this folder when finding package.json" +} diff --git a/test/main.js b/test/main.js index 41563501..4686d22e 100644 --- a/test/main.js +++ b/test/main.js @@ -22,6 +22,11 @@ test('Should return the version of each framework when multiple are detected', a t.snapshot(frameworks) }) +test('Should return the version of a framework that is not detected by npm package', async (t) => { + const frameworks = await getFrameworks('no_package') + t.snapshot(frameworks) +}) + test('Should return the version of the framework when the installed package is hoisted to the root project directory', async (t) => { const frameworks = await getFrameworks('monorepos/app1') t.snapshot(frameworks) diff --git a/test/snapshots/main.js.md b/test/snapshots/main.js.md index f9e1f5e6..d61b6f97 100644 --- a/test/snapshots/main.js.md +++ b/test/snapshots/main.js.md @@ -4,49 +4,6 @@ The actual snapshot is saved in `main.js.snap`. Generated by [AVA](https://avajs.dev). -## Should return the version of the framework when the installed package is hoisted to the root project directory - -> Snapshot 1 - - [ - { - build: { - commands: [ - 'next build', - ], - directory: '.next', - }, - category: 'static_site_generator', - dev: { - commands: [ - 'next', - ], - pollingStrategies: [ - { - name: 'TCP', - }, - ], - port: 3000, - }, - env: {}, - id: 'next', - logo: { - dark: 'https://framework-info.netlify.app/logos/nextjs/dark.svg', - default: 'https://framework-info.netlify.app/logos/nextjs/light.svg', - light: 'https://framework-info.netlify.app/logos/nextjs/light.svg', - }, - name: 'Next.js', - package: { - name: 'next', - version: '3.2.1', - }, - plugins: [ - '@netlify/plugin-nextjs', - ], - staticAssetsDirectory: undefined, - }, - ] - ## Should detect frameworks > Snapshot 1 @@ -172,6 +129,93 @@ Generated by [AVA](https://avajs.dev). }, ] +## Should return the version of a framework that is not detected by npm package + +> Snapshot 1 + + [ + { + build: { + commands: [ + 'bundle exec middleman build', + ], + directory: 'build', + }, + category: 'static_site_generator', + dev: { + commands: [ + 'bundle exec middleman server', + ], + pollingStrategies: [ + { + name: 'TCP', + }, + { + name: 'HTTP', + }, + ], + port: 4567, + }, + env: {}, + id: 'middleman', + logo: { + dark: 'https://framework-info.netlify.app/logos/middleman/default.svg', + default: 'https://framework-info.netlify.app/logos/middleman/default.svg', + light: 'https://framework-info.netlify.app/logos/middleman/default.svg', + }, + name: 'Middleman', + package: { + name: undefined, + version: 'unknown', + }, + plugins: [], + staticAssetsDirectory: undefined, + }, + ] + +## Should return the version of the framework when the installed package is hoisted to the root project directory + +> Snapshot 1 + + [ + { + build: { + commands: [ + 'next build', + ], + directory: '.next', + }, + category: 'static_site_generator', + dev: { + commands: [ + 'next', + ], + pollingStrategies: [ + { + name: 'TCP', + }, + ], + port: 3000, + }, + env: {}, + id: 'next', + logo: { + dark: 'https://framework-info.netlify.app/logos/nextjs/dark.svg', + default: 'https://framework-info.netlify.app/logos/nextjs/light.svg', + light: 'https://framework-info.netlify.app/logos/nextjs/light.svg', + }, + name: 'Next.js', + package: { + name: 'next', + version: '3.2.1', + }, + plugins: [ + '@netlify/plugin-nextjs', + ], + staticAssetsDirectory: undefined, + }, + ] + ## Should allow getting a specific framework > Snapshot 1 diff --git a/test/snapshots/main.js.snap b/test/snapshots/main.js.snap index 13958a57ec58020ad6e584771c3d052c0b4b5a5e..9234effb8aea6c80f2a05cce41fb58464a9f6373 100644 GIT binary patch literal 2110 zcmV-E2*LM3RzVGTU3M2(K*3lsf)92ESU>^g5x_?TC4vGm zFzHP1&UAOSowS{0!5CjLin_i~Bu0OT{xuSVfJ&m0X!xPgsAzo07&SytqcO%9A749d zcjmS;o!OoBmz#WsoRU6P{T@edj%{;^RuG!MTEfhlZD7aLx!Y2q%Hb*?%( zIvBQd%&Ya4F4KHZOgu_5=ev$K<7 z+b!#pSoRGNr?MQwhVkljQO-*Y+kvJb=Vmk`8YHV~yPO-7`!rQCh$5xjZ?!C)F0;f* zWXQTXGgNkyC_|L-kSsZuExK4J5Y1|}w5%1MSF?Ppc5H-kL%Kj*(x)aAV&vt%T?zCzY5JU=EOk98 zkv_4QHxl|#ma-eMA5DPia9+;lnq;^%i8WS`v-B!IZir~QtSWAgdJ~Hhy;kU2jQLp} zt_)p#h2Ma*4TKa$YN1HnZV+w$F2N0tv1JsMy=K;AeufN zwxTJnj)kr0Y4-LTT%HP33nfagsZgwiVLDnUTFet$*;>QRZC1& zcyDkGC|>lYBH8FR{h6zxc{BO(XkMhfY~U{Co0TP`d7n{xgs*qhIE#HL5-_~cCu z&VceOFe5Vd)Bt9#K=U=gcG^sbr-OHavIlq;c#EcY)%@CN9%J9Yz$suwlwtNoDPz+; zUwayqUx0IC6m>?euRY5@5n3A?OCmHW;VkzgqHuW@B>UULlLupC%z_?1H#iHrqV9}h zwBvQ>K}|JYnF)>8bWko-7M5#gLyHoN6HChc;>ei%f~UOU^Qzu}NIY@ga9Jax+JGZ8 z%WkC)jKgZs^mnc@n`H8Gk5059IYWZnU_oM`ofKb;37X#;kQ84J!i}u~NwEgPFmPvU zt)v*%MnKq0kveJ8%OJc)ktWlx{1${CfZr(Ml)yZElCxk0J1_7fwYj9qRGf)B8RXn} zDTDND-Hp~gWph&NO&+fKOUhn(o%_mS+|B-9=AoSewXiq<`0dx;6zn5?h4F%iplB}Ps(1X&jp)o}MCLVA~=6b1!54fCm(UES1**{8ry z0FS-Lg}@3x0&WHN)mt$;-f+dN#wOy7U(sw<-9@w5pe#vw0+p~DE^DN27TZwKR<2e$ zdu&{#GdnLn2qTAq_kv4izk~7@Fdh4vW#cWGZGnO9z)@gYaLG&qWf<7ojFQof^m(_E_TgwH z?N9TP-hz6y^gK}J{`ZwMrKVt+|5AlC^A;kWA?EWCEITloLY7mJy5p9iS{zMqz8=?Cr)l)cbF zP!98zUfAX@YF~^^)Dopxbww={t|n@8C-Us4{+*-Q-+n!5Hm*a?mNshF60ATa8;{wb zovyvkf{uI^CKmW>#I#j*FOsEo)Klt$wPl6|dFoOD%!3 zKi-Y4`@>E^ehpV|2Al)cBTJ6nTx9DFtdVC?UKfnMN#;5*uwH}+ku!Zx5$>WHr&Jzi@;Yk|C2JWphT&$w@&YMov=%BSVA% zqUn;V2x`juo6^L7GN@{O!eEBv8IqzKqAZi7kQEbsVj5R;A)`vVflG#JaWqvmgsi6a zl7t~7B@G8v+bQXanAJ0?q3=1IOp1oM&3}bs0*v`%gRE~hj`M(tY*Pp8U!`f{PL{RL z+S=L}wwYmBh7GgqGP_XtMI48L_kr($+W^lp%-z5eU^_4X9AFE=O&fa5YO%iJX?uG+ z!?sxJtt|U7h?7{3Vf}b?Pfn7P4BLjHKKo)YAsQr&_ShFX(IJMEi0hI;;%TA~O+<4o zv8yFwT#^h}7dw3=7l|@J>HDOleab6j$gs+Emz3dUHLX&Gcm)Gx{|T%|v1qSumFy`g z87K^ybz|6ZL(Zi!vXp9}Wvg_Z82TD}9Id;77PI@g4zBCe;3ZQAyHW7)m<2&74%x{HQ{Pvt)dJR~g)yRdS~ztID#Zq&FLyIsYU=KZ(z( znqmFneW$~=zLSy^wLbgL;*4Qr^#@|H;!EBoDJd1TGh`{XGb(1YF>|KrF|)qCddw^w z)d$j)Xdp>aVoo;f|4ZuCm8EpXa1r)fHyR|-Z7s*>IXrmNKG{9B@p&gq<~9&bk?oetcy?x zWNw5)nYG}IZs z1#X(x5szm8i-D&B0~oH=8P3)13=>kCsu)B`#*1yWly17&!nB%gp-IPNCwYfiQjak- zZ5}C@spJa>$K(rE^{l&A;5`Ph4}mYe{lSM&9t36pYwPoevVhO`Kp+Er0!;G^`kVpE zF5o?y8gYGYVG6dm+rs%#*+NG=o*&kDJVu7hSYBcg*W4v>Co-NEv9#uxo3DDTU6>{kz}XqU6+O+`UdHKl4_g2&)Wk4tO%yFuzk7JI_(!&EDVoefRTnix zOl0U)O+Q9o%F09#HB#^` zzSdsj&}&waV|+a+0y@lII{w60=&q2z0ZYewAaXyjmJTK5sX-2uX8_vFUX>K9#2iw?O$Fm=YL$Y5%fCShB*|Z#O^3-?M+aA1Ez;4>Xd4&o$8(ltqF}L5o(RvuX_wpxHJor-1Ts0e`u6h z(5utEv!LZQXA~n9uQ?BDsJJr|8mqKdE>seht7k*=qYI)7OXkI?QOygUnhlpK&IUx{ z@tX~`Z=0Zd>X-JN(e7+@ zSK8Uy(a4>xT@c$1yhHD7l`YQrFF^SkxCOM+3oyRUFCSeH=mz!yS81{GFCQzA!>