mejora 2.0.2 → 2.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/run.mjs +14 -10
- package/package.json +1 -1
package/dist/run.mjs
CHANGED
|
@@ -1,22 +1,26 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{c as e,l as t,n,o as r,r as i,s as a,u as o}from"./config-CtJOKpPZ.mjs";import{inspect as s,parseArgs as c,styleText as l}from"node:util";import{mkdir as u,readFile as d,writeFile as f}from"node:fs/promises";import{env as p}from"node:process";function m(e,t){if(!(e===void 0||t===0))return e/t}function h(e){let{results:t,totalDuration:n}=e,r=t.length,i=[],a=[],o=[],s=[],c=0,l=0,u=0,d=0,f=0,p=[];for(let e of t){let t=e.snapshot.items.length;f+=t,e.isInitial?(u+=t,o.push(e.checkId)):(e.hasImprovement&&(c+=e.removedItems.length,i.push(e.checkId)),e.hasRegression&&(l+=e.newItems.length,a.push(e.checkId)),!e.hasImprovement&&!e.hasRegression&&(d+=t,s.push(e.checkId))),p.push({checkId:e.checkId,duration:e.duration,hasImprovement:e.hasImprovement,hasRegression:e.hasRegression,isInitial:e.isInitial,newItems:e.newItems,removedItems:e.removedItems,totalIssues:t})}let h={checks:p,exitCode:e.exitCode,hasImprovement:e.hasImprovement,hasRegression:e.hasRegression,summary:{avgDuration:m(n,r),checksRun:r,improvementChecks:i,improvements:c,initial:u,initialChecks:o,regressionChecks:a,regressions:l,totalIssues:f,unchanged:d,unchangedChecks:s},totalDuration:n};return JSON.stringify(h,null,2)}const g=e=>t=>l(e,typeof t==`number`?t.toString():t),_=g(`blue`),v=g(`bold`),ee=g(`cyan`),y=g(`dim`),b=g(`green`),x=g(`red`),S=g(`gray`),
|
|
3
|
-
`,r=e.snapshot.items.length,i=[`${n}${_(`ℹ`)} ${e.checkId}:`,` Initial baseline created with ${_(r)} ${
|
|
4
|
-
`}${e.hasRegression?x(`✖`):b(`✔`)} ${e.checkId}:`,...
|
|
5
|
-
`,r=e.snapshot.items.length;return e.duration===void 0?[`${n}${S(`ℹ`)} ${e.checkId} (${v(r)})`]:[`${n}${S(`ℹ`)} ${e.checkId} (${v(r)}) ${y(
|
|
6
|
-
`)}function
|
|
2
|
+
import{c as e,l as t,n,o as r,r as i,s as a,u as o}from"./config-CtJOKpPZ.mjs";import{inspect as s,parseArgs as c,styleText as l}from"node:util";import{mkdir as u,readFile as d,writeFile as f}from"node:fs/promises";import{env as p}from"node:process";function m(e,t){if(!(e===void 0||t===0))return e/t}function h(e){let{results:t,totalDuration:n}=e,r=t.length,i=[],a=[],o=[],s=[],c=0,l=0,u=0,d=0,f=0,p=[];for(let e of t){let t=e.snapshot.items.length;f+=t,e.isInitial?(u+=t,o.push(e.checkId)):(e.hasImprovement&&(c+=e.removedItems.length,i.push(e.checkId)),e.hasRegression&&(l+=e.newItems.length,a.push(e.checkId)),!e.hasImprovement&&!e.hasRegression&&(d+=t,s.push(e.checkId))),p.push({checkId:e.checkId,duration:e.duration,hasImprovement:e.hasImprovement,hasRegression:e.hasRegression,isInitial:e.isInitial,newItems:e.newItems,removedItems:e.removedItems,totalIssues:t})}let h={checks:p,exitCode:e.exitCode,hasImprovement:e.hasImprovement,hasRegression:e.hasRegression,summary:{avgDuration:m(n,r),checksRun:r,improvementChecks:i,improvements:c,initial:u,initialChecks:o,regressionChecks:a,regressions:l,totalIssues:f,unchanged:d,unchangedChecks:s},totalDuration:n};return JSON.stringify(h,null,2)}const g=e=>t=>l(e,typeof t==`number`?t.toString():t),_=g(`blue`),v=g(`bold`),ee=g(`cyan`),y=g(`dim`),b=g(`green`),x=g(`red`),S=g(`gray`),C=g(`underline`),w=g(`yellow`);function te(e){if(e<1e3)return`${e}ms`;let t=e/1e3;if(t<60)return t%1==0?`${t}s`:`${t.toFixed(1)}s`;let n=e/6e4;if(n<60)return n%1==0?`${n}m`:`${n.toFixed(1)}m`;let r=e/36e5;return r%1==0?`${r}h`:`${r.toFixed(1)}h`}function T(e){let t=Math.round(e);return t<1?`<1ms`:te(t)}function E(e,t){return e===1?t:`${t}s`}const D=` `,ne=`${D} `;function re(e){return e===`initial`?y(`→`):e===`improvement`?b(`↑`):x(`↓`)}function ie(t,n,r){let i=e(t),o=a(t),s=n>0?`:${n}:${r>0?r:1}`:``;return`${i===`.`?``:y(`${i}/`)}${C(o)}${s?y(s):``}`}function ae(e,t){return[`${re(t)} ${ie(e.file,e.line,e.column)} ${y(e.rule)}`,e.message]}function O(e,t){let n=[],r=e.slice(0,10);for(let e of r){let[r,i]=ae(e,t);n.push(`${D}${r}`,`${ne}${i}`)}let i=e.length-r.length;return i>0&&n.push(`${D}${y(`... and ${i} more`)}`),n}function oe(e){return e===void 0?[]:[` ${y(`Duration`)} ${T(e)}`]}function se(e){return[` ${y(`Issues`)} ${v(e)}`]}function k(e){return[...oe(e.duration),...se(e.snapshot.items.length)]}function ce(e){if(!e.hasRegression)return[];let t=e.newItems.length;return[` ${x(t)} new ${E(t,`issue`)} (${E(t,`regression`)}):`,...O(e.newItems,`regression`)]}function le(e){if(!e.hasImprovement)return[];let t=e.removedItems.length;return[` ${b(t)} ${E(t,`issue`)} fixed (${E(t,`improvement`)}):`,...O(e.removedItems,`improvement`)]}function ue(e,t){let n=t?``:`
|
|
3
|
+
`,r=e.snapshot.items.length,i=[`${n}${_(`ℹ`)} ${e.checkId}:`,` Initial baseline created with ${_(r)} ${E(r,`issue`)}`];return e.snapshot.items.length>0&&i.push(...O(e.snapshot.items,`initial`)),i.push(``,...k(e)),i}function de(e,t){return[`${t?``:`
|
|
4
|
+
`}${e.hasRegression?x(`✖`):b(`✔`)} ${e.checkId}:`,...ce(e),...le(e),``,...k(e)]}function fe(e,t){let n=t?``:`
|
|
5
|
+
`,r=e.snapshot.items.length;return e.duration===void 0?[`${n}${S(`ℹ`)} ${e.checkId} (${v(r)})`]:[`${n}${S(`ℹ`)} ${e.checkId} (${v(r)}) ${y(T(e.duration))}`]}function pe(e,t){return e.isInitial?ue(e,t):e.hasRegression||e.hasImprovement?de(e,t):fe(e,t)}function me(e,t,n){return t?_(`✔ Initial baseline created successfully`):e.hasRegression?n?w(`⚠ Regressions detected (forced)`):`${x(`✗ Regressions detected`)} - Run failed`:e.hasImprovement?`${b(`✔ Improvements detected`)} - Baseline updated`:b(`✔ All checks passed`)}function he(e,t){let n={hasAnyInitial:!1,totalImprovements:0,totalInitial:0,totalIssues:0,totalRegressions:0};for(let t of e.results){let e=t.snapshot.items.length;if(n.totalIssues+=e,t.isInitial){n.hasAnyInitial=!0,n.totalInitial+=e;continue}let{hasImprovement:r,hasRegression:i}=t;r&&(n.totalImprovements+=t.removedItems.length),i&&(n.totalRegressions+=t.newItems.length)}let r=[` ${y(`Improvements`)} ${b(n.totalImprovements)}`,` ${y(`Regressions`)} ${x(n.totalRegressions)}`,` ${y(`Initial`)} ${_(n.totalInitial)}`,` ${y(`Checks`)} ${e.results.length}`,` ${y(`Issues`)} ${v(n.totalIssues)}`],i=m(e.totalDuration,e.results.length);return e.totalDuration!==void 0&&i!==void 0&&r.push(` ${y(`Duration`)} ${T(e.totalDuration)} ${S(`(avg ${T(i)})`)}`),r.push(``,me(e,n.hasAnyInitial,t)),r.join(`
|
|
6
|
+
`)}function A(e,t){let n=[];for(let[t,r]of e.results.entries())n.push(...pe(r,t===0));return n.length>0&&n.push(``),n.push(he(e,t)),n.join(`
|
|
7
7
|
`)}const j=e=>e in p&&p[e]!==`0`&&p[e]!==`false`;var M=j(`CI`)||j(`CONTINUOUS_INTEGRATION`);function N(e){try{return JSON.parse(e)}catch{return}}function P(e){let t=e.trim();return t.endsWith(`,`)?t.slice(0,-1):t}function F(e,t){let n=e;for(let e=0;e<t;e++){let e=n.trimEnd();if(!e.endsWith(`}`))break;n=e.slice(0,-1)}return n}function I(e,t){return`${e}${`
|
|
8
8
|
}`.repeat(t)}`}function L(e){let t=0;for(let n of e)n===`{`?t++:n===`}`&&t--;return t===0?e:t<0?F(e,-t):I(e,t)}function R(e){return`{
|
|
9
9
|
"version": 2,
|
|
10
10
|
${P(e)}
|
|
11
|
-
}`}function z(e){if(typeof e!=`object`||!e)throw TypeError(`Baseline must be an object`);if(`checks`in e&&e.checks&&typeof e.checks==`object`)return{checks:e.checks,version:2};let t={};for(let[n,r]of Object.entries(e))n!==`version`&&(t[n]=r);return{checks:t,version:2}}function B(e){try{let t=N(e.trim());if(t)return z(t);let n=R(L(P(e)));return z(JSON.parse(n))}catch(e){let t=e instanceof Error?e.message:String(e);throw Error(`Failed to parse baseline during conflict resolution: ${t}`,{cause:e})}}function
|
|
11
|
+
}`}function z(e){if(typeof e!=`object`||!e)throw TypeError(`Baseline must be an object`);if(`checks`in e&&e.checks&&typeof e.checks==`object`)return{checks:e.checks,version:2};let t={};for(let[n,r]of Object.entries(e))n!==`version`&&(t[n]=r);return{checks:t,version:2}}function B(e){try{let t=N(e.trim());if(t)return z(t);let n=R(L(P(e)));return z(JSON.parse(n))}catch(e){let t=e instanceof Error?e.message:String(e);throw Error(`Failed to parse baseline during conflict resolution: ${t}`,{cause:e})}}function ge(e){let t=[...e.matchAll(/<<<<<<< .*\n([\s\S]*?)\n=======\n([\s\S]*?)\n>>>>>>> .*$/gm)];if(t.length===0)throw Error(`Could not parse conflict markers in baseline`);return t.map(([,e=``,t=``])=>({ours:e,theirs:t}))}function _e(e){let t=new Map;for(let n of e)for(let[e,{items:r=[]}]of Object.entries(n.checks)){if(r.length===0)continue;let n=t.get(e);n||(n=new Map,t.set(e,n));for(let e of r)n.set(e.id,e)}let n={};for(let[e,r]of t)n[e]={items:[...r.values()].toSorted((e,t)=>e.id.localeCompare(t.id)),type:`items`};return{checks:n,version:2}}function ve(e){let t=ge(e),n=[];for(let{ours:e,theirs:r}of t)n.push(B(e),B(r));return _e(n)}const V=`__unparsable__`;function H(e){return e.replaceAll(`<`,`<`).replaceAll(`>`,`>`).replaceAll(`[`,`[`).replaceAll(`]`,`]`)}function U(e,n){return t(n,e)}function W(e,n,r){let i=t(n,e);return r?`${i}#L${r}`:i}function G(e,t){return`[${e}](${t})`}function ye(e,t,n){let r=U(e.file,t),i=W(e.file,n,e.line);return`- ${G(e.line?`Line ${e.line}`:r,i)} - ${`${e.rule}: ${H(e.message)}`}\n`}function be(e){let t=Object.groupBy(e,e=>e.file||V);return Object.entries(t).map(([e,t=[]])=>({filePath:e,items:t})).toSorted((e,t)=>e.filePath===V?1:t.filePath===V?-1:e.filePath.localeCompare(t.filePath))}function xe(e){let t=`\n### Other Issues (${e.length})\n\n`;for(let n of e)t+=`- ${n.rule}: ${H(n.message)}\n`;return`${t}\n`}function Se(e,t,n){if(e.filePath===V)return xe(e.items);let r=`\n### ${G(U(e.filePath,t),W(e.filePath,n))} (${e.items.length})\n\n`;for(let i of e.items)r+=ye(i,t,n);return`${r}\n`}function Ce(e,t,n,r){let i=t.length,a=`\n## ${e} (${i} ${E(i,`issue`)})\n\n`;if(t.length===0)return`${a}No issues\n`;let o=be(t);for(let e of o)a+=Se(e,n,r);return a}function we(e){return`${e.replaceAll(/\n{3,}/g,`
|
|
12
12
|
|
|
13
|
-
`).trimEnd()}\n`}function
|
|
13
|
+
`).trimEnd()}\n`}function Te(e,t){let n=process.cwd(),r=`<!-- prettier-ignore-start -->
|
|
14
|
+
|
|
15
|
+
# Mejora Baseline
|
|
14
16
|
|
|
15
17
|
This file represents the current accepted state of the codebase.
|
|
16
|
-
`;for(let[i,{items:a=[]}]of Object.entries(e.checks))r+=
|
|
18
|
+
`;for(let[i,{items:a=[]}]of Object.entries(e.checks))r+=Ce(i,a,n,t);return r+=`
|
|
19
|
+
<!-- prettier-ignore-end -->
|
|
20
|
+
`,we(r)}const Ee=(e,t)=>{if(!t)return!1;let n=e.items??[],r=t.items??[];if(n.length!==r.length)return!1;let i=n.toSorted((e,t)=>e.id.localeCompare(t.id)),a=r.toSorted((e,t)=>e.id.localeCompare(t.id));return i.every((e,t)=>{let n=a[t];return e.id===n.id&&e.file===n.file&&e.line===n.line&&e.column===n.column&&e.rule===n.rule&&e.message===n.message})};function De(e){let t=[e.message];if(e.stack){let n=e.stack.split(`
|
|
17
21
|
`).slice(1).map(e=>y(e.trim())).join(`
|
|
18
22
|
`);t.push(n)}return t.join(`
|
|
19
|
-
`)}function K(...e){return e.map(e=>typeof e==`string`?e:e instanceof Error?
|
|
23
|
+
`)}function K(...e){return e.map(e=>typeof e==`string`?e:e instanceof Error?De(e):s(e,{colors:!1,depth:10})).join(` `)}const q={error:(...e)=>{console.error(x(`✖`),K(...e))},log:(...e)=>{console.log(K(...e))},start:(...e)=>{console.log(ee(`◐`),K(...e))},success:(...e)=>{console.log(b(`✔`),K(...e))}};var J=class t{baselinePath;constructor(e=`.mejora/baseline.json`){this.baselinePath=e}static create(e){return{checks:e,version:2}}static getEntry(e,t){return e?.checks[t]}static update(e,n,r){let i=e??t.create({}),a=i.checks[n];return Ee(r,a)?i:{...i,checks:{...i.checks,[n]:r}}}async load(){try{let e=await d(this.baselinePath,`utf8`);if(e.includes(`<<<<<<<`)){q.start(`Merge conflict detected in baseline, auto-resolving...`);let t=ve(e);return await this.save(t,!0),q.success(`Baseline conflict resolved`),t}return JSON.parse(e)}catch(e){if(e.code===`ENOENT`)return null;throw e}}async save(t,n=!1){if(M&&!n)return;let r=`${JSON.stringify(t,null,2)}\n`,i=this.baselinePath.replace(`.json`,`.md`),a=Te(t,e(this.baselinePath));await u(e(this.baselinePath),{recursive:!0}),await Promise.all([f(this.baselinePath,r,`utf8`),f(i,a,`utf8`)])}};function Y(){return{hasImprovement:!1,hasRegression:!1,hasRelocation:!1,isInitial:!0,newItems:[],removedItems:[]}}function Oe(e,t,n){return{hasImprovement:t.length>0,hasRegression:e.length>0,hasRelocation:n,isInitial:!1,newItems:e.toSorted((e,t)=>e.id.localeCompare(t.id)),removedItems:t.toSorted((e,t)=>e.id.localeCompare(t.id))}}function X(e=[]){return new Map(e.map(e=>[e.id,e]))}function Z(e){return new Set(e.keys())}function Q(e,t){let n=[];for(let r of t){let t=e.get(r);n.push(t)}return n}function ke(e,t){for(let[n,r]of e){let e=t.get(n);if(e&&(r.line!==e.line||r.column!==e.column))return!0}return!1}function Ae(e,t){let n=X(e.items),r=X(t.items),i=Z(n),a=Z(r),o=i.difference(a),s=a.difference(i);return Oe(Q(n,o),Q(r,s),ke(n,r))}function je(e,t){return t?Ae(e,t):Y()}var Me=class e{baselineManager;constructor(e){this.baselineManager=new J(e)}static filterChecks(t,n){let r=n.only?e.resolveRegex(n.only,`--only`):null,i=n.skip?e.resolveRegex(n.skip,`--skip`):null;return!r&&!i?t:Object.fromEntries(Object.entries(t).filter(([e])=>!(r&&!r.test(e)||i?.test(e))))}static getRequiredCheckTypes(e){return new Set(Object.values(e).map(e=>e.type))}static resolveRegex(e,t){try{return new RegExp(e)}catch{throw Error(`Invalid regex pattern for ${t}: "${e}"`)}}static async runCheck(e){return e.type===`eslint`?r(e):i(e)}static async setupInfrastructure(t){let n=o(process.cwd(),`node_modules`,`.cache`,`mejora`),r=[n,...[...e.getRequiredCheckTypes(t)].map(e=>o(n,e))];await Promise.all(r.map(e=>u(e,{recursive:!0})))}static async validateAllDeps(t){let n=e.getRequiredCheckTypes(t),r=[];n.has(`eslint`)&&r.push(import(`eslint`)),n.has(`typescript`)&&r.push(import(`typescript`)),await Promise.all(r)}async run(t,n={}){let r=performance.now(),i=await this.baselineManager.load(),a=e.filterChecks(t.checks,n);try{await Promise.all([e.setupInfrastructure(a),e.validateAllDeps(a)])}catch(e){return q.error(`Setup failed:`,e),{exitCode:2,hasImprovement:!1,hasRegression:!0,results:[],totalDuration:performance.now()-r}}let o=Object.keys(a).length;q.start(`Running ${o} check${o===1?``:`s`}...`);let s=await this.executeChecks(a,i);if(!s)return{exitCode:2,hasImprovement:!1,hasRegression:!0,results:[],totalDuration:performance.now()-r};let{flags:c,results:l,updatedBaseline:u}=this.buildResults(s,i,n);return u&&u!==i&&(!c.hasAnyRegression||n.force||c.hasAnyInitial)&&await this.baselineManager.save(u,n.force),{exitCode:c.hasAnyRegression&&!n.force?1:0,hasImprovement:c.hasAnyImprovement,hasRegression:c.hasAnyRegression,results:l,totalDuration:performance.now()-r}}buildResults(e,t,n){let r=[],i=t,a=!1,o=!1,s=!1;for(let{baselineEntry:t,checkId:c,comparison:l,duration:u,snapshot:d}of e)r.push({baseline:t,checkId:c,duration:u,hasImprovement:l.hasImprovement,hasRegression:l.hasRegression,hasRelocation:l.hasRelocation,isInitial:l.isInitial,newItems:l.newItems,removedItems:l.removedItems,snapshot:d}),l.hasRegression&&(a=!0),l.hasImprovement&&(o=!0),l.isInitial&&(s=!0),(l.hasImprovement||l.hasRelocation||n.force||l.isInitial)&&(i=J.update(i,c,{items:d.items,type:d.type}));return{flags:{hasAnyImprovement:o,hasAnyInitial:s,hasAnyRegression:a},results:r,updatedBaseline:i}}async executeChecks(t,n){let r=Object.entries(t).map(async([t,r])=>{try{let i=performance.now(),a=await e.runCheck(r),o=performance.now()-i,s=J.getEntry(n,t);return{baselineEntry:s,checkId:t,comparison:je(a,s),duration:o,snapshot:a}}catch(e){throw q.error(`Error running check "${t}":`,e),e}});try{return await Promise.all(r)}catch{return null}}};const{values:$}=c({allowPositionals:!1,options:{force:{default:!1,short:`f`,type:`boolean`},help:{short:`h`,type:`boolean`},json:{default:!1,type:`boolean`},only:{type:`string`},skip:{type:`string`}},strict:!0});$.help&&(q.log(`
|
|
20
24
|
mejora - Prevent regressions by allowing only improvement
|
|
21
25
|
|
|
22
26
|
Usage:
|
|
@@ -35,4 +39,4 @@ Examples:
|
|
|
35
39
|
mejora --json
|
|
36
40
|
mejora --only "eslint > *"
|
|
37
41
|
mejora --skip typescript
|
|
38
|
-
`),process.exit(0));try{let e=new
|
|
42
|
+
`),process.exit(0));try{let e=new Me,t=await n(),r=await e.run(t,{force:$.force,json:$.json,only:$.only,skip:$.skip});$.json?q.log(h(r)):(q.log(``),q.log(A(r,$.force))),process.exit(r.exitCode)}catch(e){e instanceof Error?q.error(e.message):q.error(e),process.exit(2)}export{};
|