Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(cli): expands the info displayed in --info #959

Merged
merged 3 commits into from
Oct 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 46 additions & 31 deletions doc/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ available in dependency-cruiser configurations.
1. [`--init`](#--init)
1. [`--metrics`: calculate stability metrics](#--metrics)
1. [`--no-metrics`: do not calculate stability metrics](#--no-metrics)
1. [`--info`: show what alt-js are supported](#--info-showing-what-alt-js-are-supported)
1. [`--info`: show what alt-js are supported](#--info-show-what-alt-js-are-supported)
1. [`--ignore-known`: ignore known violations](#--ignore-known-ignore-known-violations)
1. [`--no-ignore-known`: don't ignore known violations](#--no-ignore-known)
1. [`--help`/ no parameters: get help](#--help--no-parameters)
Expand Down Expand Up @@ -749,7 +749,7 @@ Do not calculate metrics. You can use this to override an earlier set `--metrics
command line option or `metrics` option in a .dependency-cruiser.js configuration
file.

### `--info` showing what alt-js are supported
### `--info` show what alt-js are supported

Which alt-js languages dependency-cruiser supports depends on the availability
it has to them. To see how dependency-cruiser perceives its environment use
Expand All @@ -759,35 +759,50 @@ it has to them. To see how dependency-cruiser perceives its environment use
<summary>Typical output</summary>

```
Supported:

If you need a supported, but not enabled transpiler ('✖' below), install
it in the same folder dependency-cruiser is installed. E.g. 'npm i livescript'
will enable livescript support if it's installed in your project folder.

Transpilers:

✔ javascript (>es1)
✔ coffee-script (>=1.0.0 <2.0.0)
✔ coffeescript (>=1.0.0 <3.0.0)
✖ livescript (>=1.0.0 <2.0.0)
✔ typescript (>=2.0.0 <4.0.0)

Extensions:

✔ .js
✔ .mjs
✔ .jsx
✔ .vue
✔ .ts
✔ .tsx
✔ .d.ts
✖ .ls
✔ .coffee
✔ .litcoffee
✔ .coffee.md
✔ .csx
✔ .cjsx
[email protected]

node version supported : ^18.17||>=20
node version found : v22.8.0
os version found : x64 [email protected]

If you need a supported, but not enabled transpiler ('x' below), just install
it in the same folder dependency-cruiser is installed. E.g. 'npm i livescript'
will enable livescript support if it's installed in your project folder.

✔ transpiler versions supported version found
- ---------------------- ------------------- ------------------------
✔ javascript * [email protected]
✔ babel >=7.0.0 <8.0.0 @babel/[email protected]
✔ coffee-script >=1.0.0 <2.0.0 [email protected]
✔ coffeescript >=1.0.0 <3.0.0 [email protected]
x livescript >=1.0.0 <2.0.0 -
✔ svelte >=3.0.0 <5.0.0 svelte/[email protected]
✔ swc >=1.0.0 <2.0.0 @swc/[email protected]
✔ typescript >=2.0.0 <6.0.0 [email protected]
✔ vue-template-compiler >=2.0.0 <3.0.0 vue-template-compiler
✔ @vue/compiler-sfc >=3.0.0 <4.0.0 vue-template-compiler

✔ extension
- ---------
✔ .js
✔ .cjs
✔ .mjs
✔ .jsx
✔ .ts
✔ .tsx
✔ .d.ts
✔ .cts
✔ .d.cts
✔ .mts
✔ .d.mts
✔ .vue
✔ .svelte
x .ls
✔ .coffee
✔ .litcoffee
✔ .coffee.md
✔ .csx
✔ .cjsx
```

</details>
Expand Down
34 changes: 23 additions & 11 deletions src/cli/format-meta-info.mjs
Original file line number Diff line number Diff line change
@@ -1,19 +1,29 @@
import { release, platform, arch } from "node:os";
import pc from "picocolors";

import { getAvailableTranspilers, allExtensions } from "#main/index.mjs";
import meta from "#meta.cjs";

function bool2Symbol(pBool) {
return pBool ? pc.green("✔") : pc.red("x");
}

const MAX_VERSION_RANGE_STRING_LENGTH = 19;
const MAX_TRANSPILER_NAME_LENGTH = 22;
const MAX_VERSION_STRING_LENGTH = 24;

function formatTranspilers() {
return getAvailableTranspilers().reduce(
(pAll, pThis) =>
`${pAll} ${bool2Symbol(pThis.available)} ${pThis.name} (${
pThis.version
})\n`,
` ${bool2Symbol(true)} javascript (>es1)\n`,
let lTranspilerTableHeader = pc.bold(
` ✔ ${"transpiler".padEnd(MAX_TRANSPILER_NAME_LENGTH)} ${"versions supported".padEnd(MAX_VERSION_RANGE_STRING_LENGTH)} version found`,
);
let lTranspilerTableDivider = ` - ${"-".repeat(MAX_TRANSPILER_NAME_LENGTH)} ${"-".repeat(MAX_VERSION_RANGE_STRING_LENGTH)} ${"-".repeat(MAX_VERSION_STRING_LENGTH)}`;
let lTranspilerTable = getAvailableTranspilers()
.map(
(pTranspiler) =>
` ${bool2Symbol(pTranspiler.available)} ${pTranspiler.name.padEnd(MAX_TRANSPILER_NAME_LENGTH)} ${pTranspiler.version.padEnd(MAX_VERSION_RANGE_STRING_LENGTH)} ${pTranspiler.currentVersion}`,
)
.join("\n");
return `${lTranspilerTableHeader}\n${lTranspilerTableDivider}\n${lTranspilerTable}\n`;
}

function formatExtensions(pExtensions) {
Expand All @@ -26,19 +36,21 @@ function formatExtensions(pExtensions) {

export default function formatMetaInfo() {
return `
Supported:
${pc.bold("dependency-cruiser")}@${meta.version}

node version supported : ${meta.engines.node}
node version found : ${process.version}
os version found : ${arch()} ${platform()}@${release()}

If you need a supported, but not enabled transpiler ('${pc.red(
"x",
)}' below), just install
it in the same folder dependency-cruiser is installed. E.g. 'npm i livescript'
will enable livescript support if it's installed in your project folder.

Transpilers:

${formatTranspilers()}
Extensions:

${pc.bold("✔ extension")}
- ---------
${formatExtensions(allExtensions)}
`;
}
Expand Down
2 changes: 2 additions & 0 deletions src/extract/swc/parse.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,5 @@ export function clearCache() {
*/
// @ts-expect-error dfdfd
export const isAvailable = () => swc !== false;

export const version = () => `@swc/core@${swc.version}`;
3 changes: 3 additions & 0 deletions src/extract/transpile/babel-wrap.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ const babel = await tryImport("@babel/core", meta.supportedTranspilers.babel);

export default {
isAvailable: () => babel !== false,

version: () => `@babel/core@${babel.version}`,

transpile: (pSource, pFileName, pTranspileOptions = {}) =>
babel.transformSync(pSource, {
...(pTranspileOptions.babelConfig || {}),
Expand Down
3 changes: 3 additions & 0 deletions src/extract/transpile/coffeescript-wrap.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ const coffeeScript = await getCoffeeScriptModule();
export default function coffeeScriptWrap(pLiterate) {
return {
isAvailable: () => coffeeScript !== false,

version: () => `coffeescript@${coffeeScript.VERSION}`,

transpile: (pSource) => {
const lOptions = pLiterate ? { literate: true } : {};

Expand Down
8 changes: 8 additions & 0 deletions src/extract/transpile/javascript-wrap.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
import { createRequire } from "node:module";

export default {
isAvailable: () => true,

version: () => {
const require = createRequire(import.meta.url);
return `acorn@${require("acorn").version}`;
},

transpile: (pSource) => pSource,
};
2 changes: 2 additions & 0 deletions src/extract/transpile/livescript-wrap.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ const livescript = await tryImport(
export default {
isAvailable: () => livescript !== false,

version: () => `livescript@${livescript.VERSION}`,

transpile: (pSource) => livescript.compile(pSource),
};
/* c8 ignore stop */
50 changes: 45 additions & 5 deletions src/extract/transpile/meta.mjs
Original file line number Diff line number Diff line change
@@ -1,7 +1,26 @@
/* eslint security/detect-object-injection : 0*/
import {
isAvailable as swcIsAvailable,
version as swcVersion,
} from "../swc/parse.mjs";
import tryAvailable from "./try-import-available.mjs";
import javascriptWrap from "./javascript-wrap.mjs";
import babelWrap from "./babel-wrap.mjs";
import coffeeScriptWrapFunction from "./coffeescript-wrap.mjs";
import livescriptWrap from "./livescript-wrap.mjs";
import svelteWrapFunction from "./svelte-wrap.mjs";
import typescriptWrapFunction from "./typescript-wrap.mjs";
import vueTemplateWrap from "./vue-template-wrap.cjs";
import meta from "#meta.cjs";

const swcWrap = {
isAvailable: () => swcIsAvailable(),
version: () => swcVersion(),
};
const coffeeScriptWrap = coffeeScriptWrapFunction(false);
const svelteWrap = svelteWrapFunction(javascriptWrap);
const typescriptWrap = typescriptWrapFunction("esm");

function gotCoffee() {
return (
tryAvailable("coffeescript", meta.supportedTranspilers.coffeescript) ||
Expand All @@ -28,6 +47,19 @@ const TRANSPILER2AVAILABLE = {
),
};

const TRANSPILER2WRAPPER = {
babel: babelWrap,
javascript: javascriptWrap,
"coffee-script": coffeeScriptWrap,
coffeescript: coffeeScriptWrap,
livescript: livescriptWrap,
svelte: svelteWrap,
swc: swcWrap,
typescript: typescriptWrap,
"vue-template-compiler": vueTemplateWrap,
"@vue/compiler-sfc": vueTemplateWrap,
};

export const EXTENSION2AVAILABLE = new Map([
[".js", TRANSPILER2AVAILABLE.javascript],
[".cjs", TRANSPILER2AVAILABLE.javascript],
Expand Down Expand Up @@ -81,6 +113,11 @@ export const allExtensions = Array.from(EXTENSION2AVAILABLE.keys()).map(
}),
);

function getCurrentVersion(pTranspiler) {
const lTranspiler = TRANSPILER2WRAPPER[pTranspiler];
return lTranspiler.isAvailable() ? lTranspiler.version() : "-";
}

/**
* an array of extensions that are 'scannable' (have a valid transpiler
* available for) in the current environment.
Expand All @@ -99,9 +136,12 @@ export const scannableExtensions = Array.from(
* @return {IAvailableTranspiler[]} an array of supported transpilers
*/
export function getAvailableTranspilers() {
return Object.keys(meta.supportedTranspilers).map((pTranspiler) => ({
name: pTranspiler,
version: meta.supportedTranspilers[pTranspiler],
available: TRANSPILER2AVAILABLE[pTranspiler],
}));
return ["javascript"]
.concat(Object.keys(meta.supportedTranspilers))
.map((pTranspiler) => ({
name: pTranspiler,
version: meta.supportedTranspilers[pTranspiler] || "*",
available: TRANSPILER2AVAILABLE[pTranspiler],
currentVersion: getCurrentVersion(pTranspiler),
}));
}
3 changes: 2 additions & 1 deletion src/extract/transpile/svelte-wrap.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import preProcess from "./svelte-preprocess.mjs";
import tryImport from "#utl/try-import.mjs";
import meta from "#meta.cjs";

const { compile } = await tryImport(
const { compile, VERSION } = await tryImport(
"svelte/compiler",
meta.supportedTranspilers.svelte,
);
Expand All @@ -21,6 +21,7 @@ function getTranspiler(pTranspilerWrapper) {
export default function svelteWrap(pTranspilerWrapper) {
return {
isAvailable: () => Boolean(compile),
version: () => `svelte/compiler@${VERSION}`,
transpile: getTranspiler(pTranspilerWrapper),
};
}
2 changes: 2 additions & 0 deletions src/extract/transpile/typescript-wrap.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ export default function typescriptWrap(pFlavor) {
return {
isAvailable: () => typescript !== false,

version: () => `typescript@${typescript.version}`,

transpile: (pSource, _pFileName, pTranspileOptions = {}) =>
typescript.transpileModule(pSource, {
...(pTranspileOptions.tsConfig || {}),
Expand Down
4 changes: 4 additions & 0 deletions src/extract/transpile/vue-template-wrap.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ function vue2Transpile(pSource) {

module.exports = {
isAvailable: () => vueTemplateCompiler !== false,
version: () =>
vueTemplateCompiler.version
? `@vue/compiler-sfc@${vueTemplateCompiler.version}`
: "vue-template-compiler",
transpile: (pSource) =>
isVue3 ? vue3Transpile(pSource) : vue2Transpile(pSource),
};
Loading