@kitschpatrol/mdat-config 8.0.0 → 8.2.0
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/bin/cli.js +5 -6
- package/dist/index.d.ts +0 -1
- package/init/.vscode/tasks.json +73 -0
- package/package.json +2 -2
- package/readme.md +30 -8
package/bin/cli.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{cosmiconfig as e}from"cosmiconfig";import{TypeScriptLoader as t}from"cosmiconfig-typescript-loader";import{execa as n}from"execa";import r from"fs-extra";import i from"node:fs";import a from"node:path";import{PassThrough as o,Transform as s}from"node:stream";import{fileURLToPath as c}from"node:url";import{packageUp as l,packageUpSync as u}from"package-up";import d from"picocolors";import f from"yargs";import{hideBin as p}from"yargs/helpers";import m from"@pinojs/json-colorizer";import
|
|
3
|
-
`)
|
|
4
|
-
`)}})}
|
|
5
|
-
`);
|
|
6
|
-
`)
|
|
7
|
-
`);for(let t of r)e.write(`${t}\n`);return 0}async function $(e){let t=k(),n=await Z(),r=[];for(let i of t)r.push({cwdOverride:i,name:`mdat`,optionFlags:n===void 0||n===``?[`--format`]:[`--config`,n,`--format`],subcommands:[e]});return r}await J({commands:{fix:{commands:await $(`expand`),description:`Expand all Mdat content placeholders in your readme.md file(s). ${X.packageRun} ${X.monorepoRun}`,positionalArgumentMode:`none`},init:{configFile:`mdat.config.ts`,configPackageJson:{mdat:{$import:`node_modules/@kitschpatrol/mdat-config/dist/index.js`}},locationOptionFlag:!0},lint:{commands:await $(`check`),description:`Validate that all Mdat content placeholders in your readme.md file(s) have been expanded and are up to date. ${X.packageRun} ${X.monorepoRun}`,positionalArgumentMode:`none`},printConfig:{commands:[{execute:Q,name:Q.name}],description:`Print the effective Mdat configuration. ${X.packageSearch}. ${X.monorepoSearch}.`,positionalArgumentMode:`none`}},description:`Kitschpatrol's Mdat shared configuration tools.`,logColor:`green`,logPrefix:`[Mdat Config]`,name:`ksc-mdat`,order:2});export{};
|
|
2
|
+
import{cosmiconfig as e}from"cosmiconfig";import{TypeScriptLoader as t}from"cosmiconfig-typescript-loader";import{execa as n}from"execa";import r from"fs-extra";import i from"node:fs";import a from"node:path";import{PassThrough as o,Transform as s}from"node:stream";import{fileURLToPath as c}from"node:url";import{packageUp as l,packageUpSync as u}from"package-up";import d from"picocolors";import f from"yargs";import{hideBin as p}from"yargs/helpers";import{stripVTControlCharacters as m}from"node:util";import h from"@pinojs/json-colorizer";import ee from"decircular";import g from"deepmerge";import _ from"json-stringify-pretty-compact";import{findWorkspaces as v,findWorkspacesRoot as te}from"find-workspaces";import y from"node:fs/promises";import{loadConfig as b}from"mdat";var x=`8.2.0`;const S=/\s*\n\s*/gv,ne=/\r?\n/v;function re(e){let t=e.message.replaceAll(S,` `),n=e.rule===void 0?e.tool:`${e.tool}/${e.rule}`;return e.file===void 0?`${e.severity}: ${t} [${n}]`:`${e.file}:${e.line??1}:${e.column??1}: ${e.severity}: ${t} [${n}]`}function ie(e,t){let n=(e.file??``).localeCompare(t.file??``);if(n!==0)return n;let r=(e.line??0)-(t.line??0);return r===0?(e.column??0)-(t.column??0):r}function ae(e,t){let n=t.toSorted(ie);return{cwd:process.cwd(),diagnostics:n,success:e.every(e=>e.exitCode===0),summary:{errors:n.filter(e=>e.severity===`error`).length,infos:n.filter(e=>e.severity===`info`).length,warnings:n.filter(e=>e.severity===`warning`).length},tools:e,version:1}}function C(e){return m(e).split(ne).map(e=>e.trimEnd()).filter(e=>e.trim().length>0)}function w(e){return e instanceof Error&&`exitCode`in e&&typeof e.exitCode==`number`}function T(e){return h(_(ee(e),{indent:2,replacer(e,t){return typeof t==`function`?t.name:t}}),{colors:{BRACKET:`gray`}})}const E=(e,t,n)=>{let r=[...e];for(let[i,a]of t.entries())r[i]===void 0?r[i]=n.cloneUnlessOtherwiseSpecified(a,n):n.isMergeableObject(a)?r[i]=D(e[i],a,n):e.includes(a)||r.push(a);return r};function D(e,t,n={arrayMerge:E}){return g(e,t,n)}function O(e){let{tasks:t}=e;return Array.isArray(t)?t:[]}function oe(e,t){let n=[...O(e)];for(let e of O(t)){let t=n.findIndex(t=>t.label!==void 0&&t.label===e.label);t===-1?n.push(e):n[t]=e}return{...e,...t,tasks:n}}const k=[`json`,`machine`,`native`],A=k;function j(e){return typeof e==`string`&&k.includes(e)}function M(){let e=process.env.KSC_FORMAT;return j(e)?e:`native`}function se(){let{argv:e}=process;for(let[t,n]of e.entries()){let r;n===`--format`?r=e[t+1]:n.startsWith(`--format=`)&&(r=n.slice(9)),j(r)&&(process.env.KSC_FORMAT=r)}}function ce(e,t){return e.startsWith(t+a.sep)}function le(){let e=N(),t=new Set([e]),n=v();if(n!==null)for(let r of n){let n=a.resolve(r.location);ce(n,e)&&t.add(n)}return[...t]}function N(){let e=u();if(e===void 0)throw Error(`No package.json found.`);return a.dirname(e)}function ue(){let e=te();return e===null?N():a.resolve(e.location)}function P(e){if(e===`workspace-root`)return ue();if(e===`package-dir`)return N();if(typeof e==`string`){if(!r.pathExistsSync(e))throw Error(`Custom cwd directory does not exist: ${e}`);return e}return process.cwd()}async function de(e,t){try{let{default:n}=await import(`prettier`),r=await n.resolveConfig(e),i=await n.format(t,{filepath:e,...r});await y.writeFile(e,i,`utf8`)}catch{console.warn(`Skipped formatting ${e} since Prettier is not installed.`)}}async function F(e){try{await de(e,await y.readFile(e,`utf8`))}catch{}}const I=/\r?\n/v;function L(e){let t=``,n=t=>t.filter(t=>t.trim()!==``&&!e(m(t))).map(e=>`${e}\n`).join(``);return new s({flush(e){e(void 0,n([t]))},transform(e,r,i){let a=(t+e.toString()).split(I);t=a.pop()??``,i(void 0,n(a))}})}function R(e,t){let n=M()===`native`?e:void 0,r=n===void 0||n===``?``:t===void 0?n:d[t](n),i=``,a=e=>e.filter(e=>e.trim().length>0).map(e=>r===``?`${e}\n`:`${r} ${e}\n`).join(``);return new s({flush(e){e(void 0,a([i]))},transform(e,t,n){let r=(i+e.toString()).split(I);i=r.pop()??``,n(void 0,a(r))}})}async function z(e){let t=[];return new Promise((n,r)=>{e.on(`data`,e=>{t.push(e)}),e.on(`error`,e=>{r(e)}),e.on(`end`,()=>{n(Buffer.concat(t).toString(`utf8`))})})}function B(e,t){return t===1?e:e+`s`}async function V(e){return typeof e==`function`?e():e}async function fe(e,t,n,r,i){let a;if(r.logPrefix===void 0)a=e;else{let t=R(r.logPrefix,r.logColor);t.pipe(e),a=t}i&&a.write(d.bold(`Running: "${r.name}() with Positional arguments: ${String(t)} and Option flags: ${String(n)}"`)+`
|
|
3
|
+
`);try{return await r.execute(a,t,n)}catch(e){return console.error(String(e)),1}}function H(e,t,n,r){return[...e.subcommands??[],...e.receiveOptionFlags?n:[],...r??[],...e.receivePositionalArguments?t:[],...e.positionalArguments??[]]}async function pe(e,t,r,i,a){let s=1,c;if(i.logPrefix===void 0)c=e;else{let t=R(i.logPrefix,i.logColor);t.pipe(e),c=t}let l=H(i,t,r,i.optionFlags),u=P(i.cwdOverride);a&&c.write(`Running: "${i.name} ${l.join(` `)}"\n`);let d=i.prettyJsonOutput?new o:c,f=M()===`native`?process.env.NO_COLOR===void 0?{FORCE_COLOR:`true`}:{}:{NO_COLOR:`1`};try{let e=n(i.name,l,{cwd:u,env:{...f},preferLocal:!0,reject:!1,stdin:`inherit`});if(i.outputFilter){let t=L(i.outputFilter),n=L(i.outputFilter);e.stdout.pipe(t).pipe(d,{end:!1}),e.stderr.pipe(n).pipe(d,{end:!1})}else e.stdout.pipe(d,{end:!1}),e.stderr.pipe(d,{end:!1});if(await e,i.prettyJsonOutput){d.end();let e=await z(d),t=T(JSON.parse(e)).split(`
|
|
4
|
+
`);for(let e of t)c.write(`${e}\n`)}s=e.exitCode??1}catch(e){console.error(`${i.name} failed with error:`),console.error(e),w(e)&&(s=typeof e.exitCode==`number`?e.exitCode:1)}return s}function U(e){return`execute`in e}async function W(e,t,r,i){let a=H(r,e,t,r.collect?.optionFlags??r.optionFlags),o=P(r.cwdOverride);try{let e=n(r.name,a,{cwd:o,env:{NO_COLOR:`1`},preferLocal:!0,reject:!1,stdin:`inherit`});i!==void 0&&e.stderr.pipe(i,{end:!1});let t=await e;return{cwd:o,exitCode:t.exitCode??1,stderr:t.stderr,stdout:t.stdout}}catch(e){return console.error(`${r.name} failed with error:`),console.error(e),{cwd:o,exitCode:w(e)&&typeof e.exitCode==`number`?e.exitCode:1,stderr:``,stdout:``}}}function me(e){return typeof e==`object`&&!!e&&`version`in e&&e.version===1&&`diagnostics`in e&&Array.isArray(e.diagnostics)&&`tools`in e&&Array.isArray(e.tools)}async function he(e,t,n,r){let i=Date.now(),a=()=>Date.now()-i;if(U(r)){if(r.collect!==void 0)try{let{diagnostics:e,exitCode:i,unparsed:o}=await r.collect(t,n);return{diagnostics:e,exitCode:i,tools:[{durationMs:a(),exitCode:i,name:r.name,unparsed:o}]}}catch(e){return{diagnostics:[],exitCode:1,tools:[{durationMs:a(),exitCode:1,name:r.name,unparsed:[String(e)]}]}}let e=``,i=new o;i.on(`data`,t=>{e+=t.toString()});let s;try{s=await r.execute(i,t,n)}catch(t){e+=`\n${String(t)}`,s=1}return{diagnostics:[],exitCode:s,tools:[{durationMs:a(),exitCode:s,name:r.name,unparsed:C(e)}]}}if(r.outputFormatAware){let i=await W(t,n,r,e);try{let e=JSON.parse(i.stdout);if(!me(e))throw Error(`Child output is not a lint report`);return{diagnostics:e.diagnostics,exitCode:i.exitCode,tools:e.tools}}catch{return{diagnostics:[],exitCode:i.exitCode,tools:[{durationMs:a(),exitCode:i.exitCode,name:r.name,unparsed:C(i.stdout)}]}}}let s=await W(t,n,r);if(r.collect!==void 0)try{let{diagnostics:e,unparsed:t}=r.collect.parse(s);return{diagnostics:e,exitCode:s.exitCode,tools:[{durationMs:a(),exitCode:s.exitCode,name:r.name,unparsed:t}]}}catch(e){return{diagnostics:[],exitCode:s.exitCode,tools:[{durationMs:a(),exitCode:s.exitCode,name:r.name,unparsed:[...C(s.stdout),...C(s.stderr),String(e)]}]}}return{diagnostics:[],exitCode:s.exitCode,tools:[{durationMs:a(),exitCode:s.exitCode,name:r.name,unparsed:[...C(s.stdout),...C(s.stderr)]}]}}const ge=/^ksc-/v;function G(e){return e.replace(ge,``)}function K(e){return e===void 0||e.length===0?[]:e.flatMap(e=>e.split(`,`)).map(e=>G(e.trim()))}function q(e){return e.option(`skip`,{array:!0,describe:`Tool names to skip (with or without "ksc-" prefix).`,type:`string`})}function J(e){return e.option(`format`,{choices:A,default:`native`,describe:`Output format: "native" streams each tool's own output, "machine" prints one parseable line per issue for editor problem matchers, "json" prints an aggregate report.`})}function Y(e,t){return t===`native`||t===`machine`&&!U(e)&&e.outputFormatAware===!0}function _e(e,t){for(let n of t.diagnostics)e.write(`${re(n)}\n`);for(let n of t.tools)for(let t of n.unparsed)e.write(`${t}\n`)}function ve(e,t,n){let r=[],i=[];for(let e of t)n.length>0&&n.includes(G(e.name))?i.push(e):r.push(e);if(n.length>0){let r=new Set(i.map(e=>G(e.name))),a=n.filter(e=>!r.has(e));if(a.length>0){let n=t.map(e=>G(e.name)).join(`, `);e.write(`⚠️ ${d.yellow(`Unrecognized --skip ${B(`value`,a.length)}: ${a.join(`, `)}. Available: ${n}`)}\n`)}}return{commandsToRun:r,skippedCommands:i}}async function X(e,t,n,r,i,a,o,s=`native`){let{commandsToRun:c,skippedCommands:l}=ve(e,r,o??[]),u=[],f=[],p=[],m=s===`native`&&i;for(let r of c){if(Y(r,s)){let i=await(U(r)?fe(e,t,n,r,m):pe(e,t,n,r,m));u.push({exitCode:i,name:r.name});continue}let i=await he(e,t,n,r);u.push({exitCode:i.exitCode,name:r.name}),f.push(...i.tools),p.push(...i.diagnostics),s===`machine`&&_e(e,i)}let h=r.length;if(s===`native`&&l.length>0){let t=l.map(({name:e})=>e),n=d.bold(`${t.length} / ${h} ${B(`Command`,t.length)} Skipped:`);e.write(`⏭️ ${d.dim(n)} ${d.dim(t.join(`, `))}\n`)}if(s===`native`&&a){let t=u.filter(({exitCode:e})=>e===0).map(({name:e})=>e),n=u.filter(({exitCode:e})=>e!==0).map(({name:e})=>e);if(t.length>0){let n=d.bold(`${t.length} / ${h} ${B(`Command`,t.length)} Succeeded:`);e.write(`✅ ${d.green(n)} ${d.green(t.join(`, `))}\n`)}if(n.length>0){let t=d.bold(`${n.length} / ${h} ${B(`Command`,n.length)} Failed:`);e.write(`❌ ${d.red(t)} ${d.red(n.join(`, `))}\n`)}}return{exitCode:+!u.every(({exitCode:e})=>e===0),report:s===`json`?ae(f,p):void 0}}async function ye(e,t,n,o){let s=await l();if(s===void 0)throw Error("The `init` command must be used in a directory with a package.json file");let u=await l({cwd:c(import.meta.url)});if(u===void 0)return e.write(`Error: The script being called was not in a package, weird.
|
|
5
|
+
`),1;let d=a.join(a.dirname(u),`init`),f=a.dirname(s),p=(t===`file`||t===`package`)&&n!==void 0&&o!==void 0;try{if(p){let n=Object.keys(o)[0],i=r.readJsonSync(s);if(t===`package`){e.write(`Merging: \nPackage config key "${n}" → "${f}" (Because --location is set to "package")\n`);let t=D(i,o);r.writeJSONSync(s,t,{spaces:` `}),await F(s)}else n!==void 0&&Object.keys(i).includes(n)&&(e.write(`Deleting: \nPackage config key "${n}" in "${f}" (Because --location is set to "file")\n`),delete i[n],r.writeJSONSync(s,i,{spaces:` `}),await F(s))}if(!await r.pathExists(d))return 0;if((await r.readdir(d)).length===0)return e.write(`Source directory "${d}" is empty.\n`),0;e.write(`Adding initial configuration files from:\n"${d}" → "${f}"\n`),await r.copy(d,f,{async filter(o,s){let c=i.statSync(o).isFile(),l=i.existsSync(s);if(c){if(p&&t===`package`&&o.includes(n))return l?(e.write(`Deleting: \n"${o}" → "${s}" (Because --location is set to "package")\n`),r.removeSync(s)):e.write(`Skipping: \n"${o}" → "${s}" (Because --location is set to "package")\n`),!1;if(l&&(s.includes(`.vscode/`)||s.includes(`package.json`))&&a.extname(s)===`.json`){e.write(`Merging: \n"${o}" → "${s}"\n`);let t=r.readJSONSync(o),n=r.readJSONSync(s),i=s.endsWith(`.vscode/tasks.json`)?oe(n,t):D(n,t);return r.writeJSONSync(s,i,{spaces:` `}),await F(s),!1}return l?(e.write(`Overwriting: \n"${o}" → "${s}"\n`),await F(s),!0):(e.write(`Copying: \n"${o}" → "${s}"\n`),await F(s),!0)}return!0},overwrite:!0})}catch(e){return console.error(String(e)),1}return 0}async function be(e){let{commands:{fix:t,init:n,lint:r,printConfig:i},description:a,logColor:o,logPrefix:s,name:c,showSummary:l,verbose:u}=e;se();let d=R(s,o);d.pipe(M()===`json`?process.stderr:process.stdout);let m=f(p(process.argv)).scriptName(c).usage(`$0 <command>`,a);n!==void 0&&m.command({builder(e){let t=n.locationOptionFlag?e.option(`location`,{choices:[`file`,`package`],default:`file`,describe:`Where to store the configuration.`,type:`string`}):e;return l?q(t):t},command:`init`,describe:n.description??`Initialize by copying starter config files to your project root${n.locationOptionFlag?` or to your package.json file.`:`.`}`,async handler(e){let t=n.locationOptionFlag?e.location:void 0,r=K(e.skip),{exitCode:i}=await X(d,[],t===void 0?[]:[`--location`,t],[{async execute(e,t,r){return ye(e,r.at(1),n.configFile,n.configPackageJson)},name:`copyAndMergeInitFiles`},...n.commands??[]],void 0,void 0,r);process.exitCode=i}}),r!==void 0&&m.command({builder(e){let t=J(r.positionalArgumentMode===`none`?e:e.positional(`files`,{array:!0,...r.positionalArgumentDefault!==void 0&&{default:r.positionalArgumentDefault},describe:`Files or glob pattern to lint.`,type:`string`}));return l?q(t):t},command:r.positionalArgumentMode===`none`?`lint`:r.positionalArgumentMode===`optional`?`lint [files..]`:`lint <files..>`,describe:r.description,async handler(e){let t=e.files??[],n=K(e.skip),i=M(),{exitCode:a,report:o}=await X(d,t,[],await V(r.commands),u,l,n,i);o!==void 0&&process.stdout.write(`${JSON.stringify(o,void 0,` `)}\n`),process.exitCode=a}}),t!==void 0&&m.command({builder(e){let n=J(t.positionalArgumentMode===`none`?e:e.positional(`files`,{array:!0,...t.positionalArgumentDefault!==void 0&&{default:t.positionalArgumentDefault},describe:`Files or glob pattern to fix.`,type:`string`}));return l?q(n):n},command:t.positionalArgumentMode===`none`?`fix`:t.positionalArgumentMode===`optional`?`fix [files..]`:`fix <files..>`,describe:t.description,async handler(e){let n=e.files??[],r=K(e.skip),i=M(),{exitCode:a,report:o}=await X(d,n,[],await V(t.commands),void 0,void 0,r,i);o!==void 0&&process.stdout.write(`${JSON.stringify(o,void 0,` `)}\n`),process.exitCode=a}}),i!==void 0&&m.command({builder(e){let t=i.positionalArgumentMode===`none`?e:e.positional(`file`,{...i.positionalArgumentDefault!==void 0&&{default:i.positionalArgumentDefault},describe:`File or glob pattern to print configuration for.`,type:`string`});return l?q(t):t},command:i.positionalArgumentMode===`none`?`print-config`:i.positionalArgumentMode===`optional`?`print-config [file]`:`print-config <file>`,describe:i.description,async handler(e){let t=e.file??void 0,n=t===void 0?[]:[t],r=K(e.skip),{exitCode:a}=await X(d,n,[],await V(i.commands),u,l,r);process.exitCode=a}}),m.alias(`h`,`help`),m.version(x),m.alias(`v`,`version`),m.help(),m.wrap(process.stdout.isTTY?Math.min(120,m.terminalWidth()):0),await m.parseAsync()}async function Z(n){let r=e(n,{loaders:{".ts":t()},searchStrategy:`project`});try{let e=await r.search();if(e===null){console.error(`No ${n} configuration found.`);return}return e}catch(e){console.error(`Error while searching for ${n} configuration:`,e);return}}const Q={fileRun:`Matches files below the current working directory by default.`,monorepoRun:`In a monorepo, it will also run in all packages below the current working directory.`,monorepoSearch:`Searches up to the root of a monorepo if necessary.`,multiArgumentCaveat:`Will use file arguments / globs where possible if provided, but some of the invoked tools only operate at the package scope.`,multiOptionCaveat:`Will use option flags where possible if provided, but some of the invoked tools will ignore them.`,optionalFileRun:`Package-scoped by default, file-scoped if a file argument is provided.`,packageRun:`Package-scoped.`,packageSearch:`Package-scoped.`};async function xe(){return(await Z(`mdat`))?.filepath}async function Se(e){let t=`mdat`,n=await Z(t);n!==void 0&&e.write(`Found ${t} readme configuration at "${n.filepath}"\n`);let r=T(await b({additionalConfig:await b()})).split(`
|
|
6
|
+
`);for(let t of r)e.write(`${t}\n`);return 0}async function $(e){let t=le(),n=await xe(),r=[];for(let i of t)r.push({cwdOverride:i,name:`mdat`,optionFlags:n===void 0||n===``?[`--format`]:[`--config`,n,`--format`],subcommands:[e]});return r}await be({commands:{fix:{commands:await $(`expand`),description:`Expand all Mdat content placeholders in your readme.md file(s). ${Q.packageRun} ${Q.monorepoRun}`,positionalArgumentMode:`none`},init:{configFile:`mdat.config.ts`,configPackageJson:{mdat:{$import:`node_modules/@kitschpatrol/mdat-config/dist/index.js`}},locationOptionFlag:!0},lint:{commands:await $(`check`),description:`Validate that all Mdat content placeholders in your readme.md file(s) have been expanded and are up to date. ${Q.packageRun} ${Q.monorepoRun}`,positionalArgumentMode:`none`},printConfig:{commands:[{execute:Se,name:`mdat-config`}],description:`Print the effective Mdat configuration. ${Q.packageSearch}. ${Q.monorepoSearch}.`,positionalArgumentMode:`none`}},description:`Kitschpatrol's Mdat shared configuration tools.`,logColor:`green`,logPrefix:`[Mdat Config]`,name:`ksc-mdat`,order:2});export{};
|
package/dist/index.d.ts
CHANGED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "2.0.0",
|
|
3
|
+
"tasks": [
|
|
4
|
+
{
|
|
5
|
+
"label": "ksc-mdat lint",
|
|
6
|
+
"detail": "Validate that all Mdat content placeholders in your readme.md file(s) have been expanded and are up to date.",
|
|
7
|
+
"type": "shell",
|
|
8
|
+
"command": "pnpm exec ksc-mdat lint --format machine",
|
|
9
|
+
"options": {
|
|
10
|
+
"cwd": "${workspaceFolder}"
|
|
11
|
+
},
|
|
12
|
+
"presentation": {
|
|
13
|
+
"clear": true,
|
|
14
|
+
"echo": true,
|
|
15
|
+
"focus": false,
|
|
16
|
+
"panel": "dedicated",
|
|
17
|
+
"reveal": "silent",
|
|
18
|
+
"revealProblems": "onProblem",
|
|
19
|
+
"showReuseMessage": false
|
|
20
|
+
},
|
|
21
|
+
"problemMatcher": [
|
|
22
|
+
{
|
|
23
|
+
"owner": "ksc",
|
|
24
|
+
"source": "ksc",
|
|
25
|
+
"fileLocation": ["relative", "${workspaceFolder}"],
|
|
26
|
+
"pattern": {
|
|
27
|
+
"regexp": "^(.+?):(\\d+):(\\d+): (error|warning|info): (.+) \\[([^\\]]+)\\]$",
|
|
28
|
+
"file": 1,
|
|
29
|
+
"line": 2,
|
|
30
|
+
"column": 3,
|
|
31
|
+
"severity": 4,
|
|
32
|
+
"message": 5,
|
|
33
|
+
"code": 6
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
]
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"label": "ksc-mdat fix",
|
|
40
|
+
"detail": "Expand all Mdat content placeholders in your readme.md file(s).",
|
|
41
|
+
"type": "shell",
|
|
42
|
+
"command": "pnpm exec ksc-mdat fix --format machine",
|
|
43
|
+
"options": {
|
|
44
|
+
"cwd": "${workspaceFolder}"
|
|
45
|
+
},
|
|
46
|
+
"presentation": {
|
|
47
|
+
"clear": true,
|
|
48
|
+
"echo": true,
|
|
49
|
+
"focus": false,
|
|
50
|
+
"panel": "dedicated",
|
|
51
|
+
"reveal": "silent",
|
|
52
|
+
"revealProblems": "onProblem",
|
|
53
|
+
"showReuseMessage": false
|
|
54
|
+
},
|
|
55
|
+
"problemMatcher": [
|
|
56
|
+
{
|
|
57
|
+
"owner": "ksc",
|
|
58
|
+
"source": "ksc",
|
|
59
|
+
"fileLocation": ["relative", "${workspaceFolder}"],
|
|
60
|
+
"pattern": {
|
|
61
|
+
"regexp": "^(.+?):(\\d+):(\\d+): (error|warning|info): (.+) \\[([^\\]]+)\\]$",
|
|
62
|
+
"file": 1,
|
|
63
|
+
"line": 2,
|
|
64
|
+
"column": 3,
|
|
65
|
+
"severity": 4,
|
|
66
|
+
"message": 5,
|
|
67
|
+
"code": 6
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
]
|
|
71
|
+
}
|
|
72
|
+
]
|
|
73
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kitschpatrol/mdat-config",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.2.0",
|
|
4
4
|
"description": "MDAT configuration for @kitschpatrol/shared-config.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"shared-config",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"mdat": "^2.3.6",
|
|
57
57
|
"package-up": "^5.0.0",
|
|
58
58
|
"picocolors": "^1.1.1",
|
|
59
|
-
"prettier": "^3.9.
|
|
59
|
+
"prettier": "^3.9.5",
|
|
60
60
|
"yargs": "^18.0.0"
|
|
61
61
|
},
|
|
62
62
|
"engines": {
|
package/readme.md
CHANGED
|
@@ -150,10 +150,11 @@ Usage:
|
|
|
150
150
|
ksc-mdat lint
|
|
151
151
|
```
|
|
152
152
|
|
|
153
|
-
| Option | Description
|
|
154
|
-
| ------------------- |
|
|
155
|
-
| `--
|
|
156
|
-
| `--
|
|
153
|
+
| Option | Description | Type | Default |
|
|
154
|
+
| ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------- | ---------- |
|
|
155
|
+
| `--format` | Output format: "native" streams each tool's own output, "machine" prints one parseable line per issue for editor problem matchers, "json" prints an aggregate report. | `"json"` `"machine"` `"native"` | `"native"` |
|
|
156
|
+
| `--help`<br>`-h` | Show help | `boolean` | |
|
|
157
|
+
| `--version`<br>`-v` | Show version number | `boolean` | |
|
|
157
158
|
|
|
158
159
|
#### Subcommand: `ksc-mdat fix`
|
|
159
160
|
|
|
@@ -165,10 +166,11 @@ Usage:
|
|
|
165
166
|
ksc-mdat fix
|
|
166
167
|
```
|
|
167
168
|
|
|
168
|
-
| Option | Description
|
|
169
|
-
| ------------------- |
|
|
170
|
-
| `--
|
|
171
|
-
| `--
|
|
169
|
+
| Option | Description | Type | Default |
|
|
170
|
+
| ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------- | ---------- |
|
|
171
|
+
| `--format` | Output format: "native" streams each tool's own output, "machine" prints one parseable line per issue for editor problem matchers, "json" prints an aggregate report. | `"json"` `"machine"` `"native"` | `"native"` |
|
|
172
|
+
| `--help`<br>`-h` | Show help | `boolean` | |
|
|
173
|
+
| `--version`<br>`-v` | Show version number | `boolean` | |
|
|
172
174
|
|
|
173
175
|
#### Subcommand: `ksc-mdat print-config`
|
|
174
176
|
|
|
@@ -187,6 +189,26 @@ ksc-mdat print-config
|
|
|
187
189
|
|
|
188
190
|
<!-- /cli-help -->
|
|
189
191
|
|
|
192
|
+
### VS Code tasks
|
|
193
|
+
|
|
194
|
+
`ksc-mdat init` adds a `.vscode/tasks.json` with two tasks:
|
|
195
|
+
|
|
196
|
+
- **`ksc-mdat lint`** runs `ksc-mdat lint --format machine`, validating that readme content placeholders are expanded and up to date
|
|
197
|
+
- **`ksc-mdat fix`** runs `ksc-mdat fix --format machine`, expanding readme content placeholders
|
|
198
|
+
|
|
199
|
+
If you're using the complete [@kitschpatrol/shared-config](https://github.com/kitschpatrol/shared-config) package, you'd more likely want to run:
|
|
200
|
+
|
|
201
|
+
- **`ksc lint`** runs `ksc lint --format machine`, which runs all `ksc lint` tools across the whole project
|
|
202
|
+
- **`ksc fix`** runs `ksc fix --format machine`, which applies all `ksc fix` auto-fixes and reports anything unfixable
|
|
203
|
+
|
|
204
|
+
Run them via the _Tasks: Run Task_ command (or the _Terminal → Run Task…_ menu item).
|
|
205
|
+
|
|
206
|
+
Each task's problem matcher parses the machine-format output and populates VS Code's [Problems panel](https://code.visualstudio.com/docs/debugtest/debugging#_errors-and-warnings) with every reported issue, pointing to the offending file, line, and column.
|
|
207
|
+
|
|
208
|
+
The tasks share a problem matcher owner with the other `@kitschpatrol/shared-config` tasks, so the panel reflects the most recent run rather than stacking duplicates.
|
|
209
|
+
|
|
210
|
+
If your project already has a `.vscode/tasks.json`, `init` merges by task label: your own tasks are left alone, and same-label tasks are replaced with the latest definitions.
|
|
211
|
+
|
|
190
212
|
### API
|
|
191
213
|
|
|
192
214
|
The package also exports `fix`, `fixFile` functions for expanding Mdat comment placeholders programmatically, pre-configured with the shared Mdat configuration. The [mdat](https://github.com/kitschpatrol/mdat) project already provides a robust TypeScript API and CLI for general use cases, but these proxies are provided for convenience in @kitschpatrol/shared-config projects.
|