@code-pushup/cli 0.10.7 → 0.11.1

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.
Files changed (3) hide show
  1. package/README.md +4 -5
  2. package/index.js +173 -143
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -40,10 +40,6 @@ _If you're looking for programmatic usage, then refer to the underlying [@code-p
40
40
 
41
41
  ```js
42
42
  export default {
43
- persist: {
44
- outputDir: '.code-pushup',
45
- format: ['json', 'md'],
46
- },
47
43
  plugins: [
48
44
  // ...
49
45
  ],
@@ -154,7 +150,10 @@ Each example is fully tested to demonstrate best practices for plugin testing as
154
150
  | ---------------- | --------- | ----------------------- | ---------------------------------------------------------------------- |
155
151
  | **`--progress`** | `boolean` | `true` | Show progress bar in stdout. |
156
152
  | **`--verbose`** | `boolean` | `false` | When true creates more verbose output. This is helpful when debugging. |
157
- | **`--config`** | `string` | `code-pushup.config.js` | Path to the config file, e.g. code-pushup.config.js |
153
+ | **`--config`** | `string` | `code-pushup.config.ts` | Path to the config file, e.g. code-pushup.config.(ts\|mjs\|js) |
154
+
155
+ > [!NOTE]
156
+ > By default, the CLI loads `code-pushup.config.(ts|mjs|js)` if no config path is provided with `--config`.
158
157
 
159
158
  ### Common Command Options
160
159
 
package/index.js CHANGED
@@ -6,16 +6,6 @@ import { hideBin } from "yargs/helpers";
6
6
  // packages/cli/src/lib/autorun/autorun-command.ts
7
7
  import chalk5 from "chalk";
8
8
 
9
- // packages/core/src/lib/implementation/persist.ts
10
- import { mkdir as mkdir2, stat as stat2, writeFile } from "node:fs/promises";
11
- import { join as join2 } from "node:path";
12
-
13
- // packages/utils/src/lib/execute-process.ts
14
- import { spawn } from "node:child_process";
15
-
16
- // packages/utils/src/lib/reports/utils.ts
17
- import { join } from "node:path";
18
-
19
9
  // packages/models/src/lib/audit.ts
20
10
  import { z as z2 } from "zod";
21
11
 
@@ -502,6 +492,10 @@ var PERSIST_OUTPUT_DIR = ".code-pushup";
502
492
  var PERSIST_FORMAT = ["json"];
503
493
  var PERSIST_FILENAME = "report";
504
494
 
495
+ // packages/models/src/lib/implementation/configuration.ts
496
+ var CONFIG_FILE_NAME = "code-pushup.config";
497
+ var SUPPORTED_CONFIG_FILE_FORMATS = ["ts", "mjs", "js"];
498
+
505
499
  // packages/models/src/lib/report.ts
506
500
  import { z as z12 } from "zod";
507
501
  var auditReportSchema = auditSchema.merge(auditOutputSchema);
@@ -564,6 +558,12 @@ var reportSchema = packageVersionSchema({
564
558
  })
565
559
  );
566
560
 
561
+ // packages/utils/src/lib/execute-process.ts
562
+ import { spawn } from "node:child_process";
563
+
564
+ // packages/utils/src/lib/reports/utils.ts
565
+ import { join } from "node:path";
566
+
567
567
  // packages/utils/src/lib/file-system.ts
568
568
  import { bundleRequire } from "bundle-require";
569
569
  import chalk from "chalk";
@@ -1526,76 +1526,15 @@ var verboseUtils = (verbose) => ({
1526
1526
  exec: getExecVerbose(verbose)
1527
1527
  });
1528
1528
 
1529
- // packages/core/src/lib/implementation/persist.ts
1530
- var PersistDirError = class extends Error {
1531
- constructor(outputDir) {
1532
- super(`outPath: ${outputDir} is no directory.`);
1533
- }
1534
- };
1535
- var PersistError = class extends Error {
1536
- constructor(reportPath) {
1537
- super(`fileName: ${reportPath} could not be saved.`);
1538
- }
1539
- };
1540
- async function persistReport(report, options2) {
1541
- const { outputDir, filename, format } = options2;
1542
- const sortedScoredReport = sortReport(scoreReport(report));
1543
- console.info(generateStdoutSummary(sortedScoredReport));
1544
- const results = await Promise.all(
1545
- format.map(async (reportType) => {
1546
- switch (reportType) {
1547
- case "json":
1548
- return {
1549
- format: "json",
1550
- content: JSON.stringify(report, null, 2)
1551
- };
1552
- case "md":
1553
- const commitData = await getLatestCommit();
1554
- validateCommitData(commitData);
1555
- return {
1556
- format: "md",
1557
- content: generateMdReport(sortedScoredReport, commitData)
1558
- };
1559
- }
1560
- })
1561
- );
1562
- if (!await directoryExists(outputDir)) {
1563
- try {
1564
- await mkdir2(outputDir, { recursive: true });
1565
- } catch (error) {
1566
- console.warn(error);
1567
- throw new PersistDirError(outputDir);
1568
- }
1569
- }
1570
- return Promise.allSettled(
1571
- results.map(
1572
- (result) => persistResult(
1573
- join2(outputDir, `${filename}.${result.format}`),
1574
- result.content
1575
- )
1576
- )
1577
- );
1578
- }
1579
- function validateCommitData(commitData) {
1580
- if (!commitData) {
1581
- console.warn("no commit data available");
1582
- }
1583
- }
1584
- async function persistResult(reportPath, content) {
1585
- return writeFile(reportPath, content).then(() => stat2(reportPath)).then((stats) => [reportPath, stats.size]).catch((error) => {
1586
- console.warn(error);
1587
- throw new PersistError(reportPath);
1588
- });
1589
- }
1590
- function logPersistedResults(persistResults) {
1591
- logMultipleFileResults(persistResults, "Generated reports");
1592
- }
1529
+ // packages/core/package.json
1530
+ var name = "@code-pushup/core";
1531
+ var version = "0.11.1";
1593
1532
 
1594
1533
  // packages/core/src/lib/implementation/execute-plugin.ts
1595
1534
  import chalk4 from "chalk";
1596
1535
 
1597
1536
  // packages/core/src/lib/implementation/runner.ts
1598
- import { join as join3 } from "node:path";
1537
+ import { join as join2 } from "node:path";
1599
1538
  async function executeRunnerConfig(cfg, onProgress) {
1600
1539
  const { args, command, outputFile, outputTransform } = cfg;
1601
1540
  const { duration, date } = await executeProcess({
@@ -1603,7 +1542,7 @@ async function executeRunnerConfig(cfg, onProgress) {
1603
1542
  args,
1604
1543
  observer: { onStdout: onProgress }
1605
1544
  });
1606
- const outputs = await readJsonFile(join3(process.cwd(), outputFile));
1545
+ const outputs = await readJsonFile(join2(process.cwd(), outputFile));
1607
1546
  const audits = outputTransform ? await outputTransform(outputs) : outputs;
1608
1547
  return {
1609
1548
  duration,
@@ -1701,10 +1640,6 @@ function auditOutputsCorrelateWithPluginOutput(auditOutputs, pluginConfigAudits)
1701
1640
  });
1702
1641
  }
1703
1642
 
1704
- // packages/core/package.json
1705
- var name = "@code-pushup/core";
1706
- var version = "0.10.7";
1707
-
1708
1643
  // packages/core/src/lib/implementation/collect.ts
1709
1644
  async function collect(options2) {
1710
1645
  const { plugins, categories } = options2;
@@ -1721,6 +1656,132 @@ async function collect(options2) {
1721
1656
  };
1722
1657
  }
1723
1658
 
1659
+ // packages/core/src/lib/implementation/persist.ts
1660
+ import { mkdir as mkdir2, stat as stat2, writeFile } from "node:fs/promises";
1661
+ import { join as join3 } from "node:path";
1662
+ var PersistDirError = class extends Error {
1663
+ constructor(outputDir) {
1664
+ super(`outPath: ${outputDir} is no directory.`);
1665
+ }
1666
+ };
1667
+ var PersistError = class extends Error {
1668
+ constructor(reportPath) {
1669
+ super(`fileName: ${reportPath} could not be saved.`);
1670
+ }
1671
+ };
1672
+ async function persistReport(report, options2) {
1673
+ const { outputDir, filename, format } = options2;
1674
+ const sortedScoredReport = sortReport(scoreReport(report));
1675
+ console.info(generateStdoutSummary(sortedScoredReport));
1676
+ const results = await Promise.all(
1677
+ format.map(async (reportType) => {
1678
+ switch (reportType) {
1679
+ case "json":
1680
+ return {
1681
+ format: "json",
1682
+ content: JSON.stringify(report, null, 2)
1683
+ };
1684
+ case "md":
1685
+ const commitData = await getLatestCommit();
1686
+ validateCommitData(commitData);
1687
+ return {
1688
+ format: "md",
1689
+ content: generateMdReport(sortedScoredReport, commitData)
1690
+ };
1691
+ }
1692
+ })
1693
+ );
1694
+ if (!await directoryExists(outputDir)) {
1695
+ try {
1696
+ await mkdir2(outputDir, { recursive: true });
1697
+ } catch (error) {
1698
+ console.warn(error);
1699
+ throw new PersistDirError(outputDir);
1700
+ }
1701
+ }
1702
+ return Promise.allSettled(
1703
+ results.map(
1704
+ (result) => persistResult(
1705
+ join3(outputDir, `${filename}.${result.format}`),
1706
+ result.content
1707
+ )
1708
+ )
1709
+ );
1710
+ }
1711
+ function validateCommitData(commitData) {
1712
+ if (!commitData) {
1713
+ console.warn("no commit data available");
1714
+ }
1715
+ }
1716
+ async function persistResult(reportPath, content) {
1717
+ return writeFile(reportPath, content).then(() => stat2(reportPath)).then((stats) => [reportPath, stats.size]).catch((error) => {
1718
+ console.warn(error);
1719
+ throw new PersistError(reportPath);
1720
+ });
1721
+ }
1722
+ function logPersistedResults(persistResults) {
1723
+ logMultipleFileResults(persistResults, "Generated reports");
1724
+ }
1725
+
1726
+ // packages/core/src/lib/normalize.ts
1727
+ var normalizePersistConfig = (cfg) => ({
1728
+ outputDir: PERSIST_OUTPUT_DIR,
1729
+ filename: PERSIST_FILENAME,
1730
+ format: PERSIST_FORMAT,
1731
+ ...cfg
1732
+ });
1733
+
1734
+ // packages/core/src/lib/collect-and-persist.ts
1735
+ async function collectAndPersistReports(options2) {
1736
+ const { exec } = verboseUtils(options2.verbose);
1737
+ const report = await collect(options2);
1738
+ const persist = normalizePersistConfig(options2.persist);
1739
+ const persistResults = await persistReport(report, persist);
1740
+ exec(() => {
1741
+ logPersistedResults(persistResults);
1742
+ });
1743
+ report.plugins.forEach((plugin) => {
1744
+ pluginReportSchema.parse(plugin);
1745
+ });
1746
+ }
1747
+
1748
+ // packages/core/src/lib/implementation/read-rc-file.ts
1749
+ import { join as join4 } from "node:path";
1750
+ var ConfigPathError = class extends Error {
1751
+ constructor(configPath) {
1752
+ super(`Provided path '${configPath}' is not valid.`);
1753
+ }
1754
+ };
1755
+ async function readRcByPath(filepath) {
1756
+ if (filepath.length === 0) {
1757
+ throw new Error("The path to the configuration file is empty.");
1758
+ }
1759
+ if (!await fileExists(filepath)) {
1760
+ throw new ConfigPathError(filepath);
1761
+ }
1762
+ const cfg = await importEsmModule({ filepath });
1763
+ return coreConfigSchema.parse(cfg);
1764
+ }
1765
+ async function autoloadRc() {
1766
+ let ext = "";
1767
+ for (const extension of SUPPORTED_CONFIG_FILE_FORMATS) {
1768
+ const path = `${CONFIG_FILE_NAME}.${extension}`;
1769
+ const exists2 = await fileExists(path);
1770
+ if (exists2) {
1771
+ ext = extension;
1772
+ break;
1773
+ }
1774
+ }
1775
+ if (!ext) {
1776
+ throw new Error(
1777
+ `No file ${CONFIG_FILE_NAME}.(${SUPPORTED_CONFIG_FILE_FORMATS.join(
1778
+ "|"
1779
+ )}) present in ${process.cwd()}`
1780
+ );
1781
+ }
1782
+ return readRcByPath(join4(process.cwd(), `${CONFIG_FILE_NAME}.${ext}`));
1783
+ }
1784
+
1724
1785
  // packages/core/src/lib/upload.ts
1725
1786
  import { uploadToPortal } from "@code-pushup/portal-client";
1726
1787
 
@@ -1810,14 +1871,6 @@ function transformSeverity(severity) {
1810
1871
  }
1811
1872
  }
1812
1873
 
1813
- // packages/core/src/lib/normalize.ts
1814
- var normalizePersistConfig = (cfg) => ({
1815
- outputDir: PERSIST_OUTPUT_DIR,
1816
- filename: PERSIST_FILENAME,
1817
- format: PERSIST_FORMAT,
1818
- ...cfg
1819
- });
1820
-
1821
1874
  // packages/core/src/lib/upload.ts
1822
1875
  async function upload(options2, uploadFn = uploadToPortal) {
1823
1876
  const persist = normalizePersistConfig(options2.persist);
@@ -1842,43 +1895,43 @@ async function upload(options2, uploadFn = uploadToPortal) {
1842
1895
  return uploadFn({ apiKey, server, data, timeout });
1843
1896
  }
1844
1897
 
1845
- // packages/core/src/lib/collect-and-persist.ts
1846
- async function collectAndPersistReports(options2) {
1847
- const { exec } = verboseUtils(options2.verbose);
1848
- const report = await collect(options2);
1849
- const persist = normalizePersistConfig(options2.persist);
1850
- const persistResults = await persistReport(report, persist);
1851
- exec(() => {
1852
- logPersistedResults(persistResults);
1853
- });
1854
- report.plugins.forEach((plugin) => {
1855
- pluginReportSchema.parse(plugin);
1856
- });
1857
- }
1858
-
1859
- // packages/core/src/lib/implementation/read-code-pushup-config.ts
1860
- var ConfigPathError = class extends Error {
1861
- constructor(configPath) {
1862
- super(`Provided path '${configPath}' is not valid.`);
1863
- }
1864
- };
1865
- async function readCodePushupConfig(filepath) {
1866
- if (!await fileExists(filepath)) {
1867
- throw new ConfigPathError(filepath);
1868
- }
1869
- return coreConfigSchema.parse(await importEsmModule({ filepath }));
1870
- }
1871
-
1872
1898
  // packages/cli/src/lib/constants.ts
1873
1899
  var CLI_NAME = "Code PushUp CLI";
1874
1900
  var CLI_SCRIPT_NAME = "code-pushup";
1875
1901
 
1902
+ // packages/cli/src/lib/implementation/global.utils.ts
1903
+ function filterKebabCaseKeys(obj) {
1904
+ return Object.entries(obj).filter(([key]) => !key.includes("-")).reduce(
1905
+ (acc, [key, value]) => typeof value === "string" || typeof value === "object" && Array.isArray(obj[key]) ? { ...acc, [key]: value } : typeof value === "object" && !Array.isArray(value) && value != null ? {
1906
+ ...acc,
1907
+ [key]: filterKebabCaseKeys(value)
1908
+ } : { ...acc, [key]: value },
1909
+ {}
1910
+ );
1911
+ }
1912
+ function logErrorBeforeThrow(fn) {
1913
+ return async (...args) => {
1914
+ try {
1915
+ return await fn(...args);
1916
+ } catch (error) {
1917
+ console.error(error);
1918
+ await new Promise((resolve) => process.stdout.write("", resolve));
1919
+ throw error;
1920
+ }
1921
+ };
1922
+ }
1923
+ function coerceArray(param = []) {
1924
+ return [
1925
+ ...new Set(toArray(param).flatMap((f) => f.split(",")) || [])
1926
+ ];
1927
+ }
1928
+
1876
1929
  // packages/cli/src/lib/implementation/only-plugins.options.ts
1877
1930
  var onlyPluginsOption = {
1878
1931
  describe: "List of plugins to run. If not set all plugins are run.",
1879
1932
  type: "array",
1880
1933
  default: [],
1881
- coerce: (arg) => arg.flatMap((v) => v.split(","))
1934
+ coerce: coerceArray
1882
1935
  };
1883
1936
  function yargsOnlyPluginsOptionsDefinition() {
1884
1937
  return {
@@ -1933,28 +1986,6 @@ function yargsCollectCommandObject() {
1933
1986
  };
1934
1987
  }
1935
1988
 
1936
- // packages/cli/src/lib/implementation/global.utils.ts
1937
- function filterKebabCaseKeys(obj) {
1938
- return Object.entries(obj).filter(([key]) => !key.includes("-")).reduce(
1939
- (acc, [key, value]) => typeof value === "string" || typeof value === "object" && Array.isArray(obj[key]) ? { ...acc, [key]: value } : typeof value === "object" && !Array.isArray(value) && value != null ? {
1940
- ...acc,
1941
- [key]: filterKebabCaseKeys(value)
1942
- } : { ...acc, [key]: value },
1943
- {}
1944
- );
1945
- }
1946
- function logErrorBeforeThrow(fn) {
1947
- return async (...args) => {
1948
- try {
1949
- return await fn(...args);
1950
- } catch (error) {
1951
- console.error(error);
1952
- await new Promise((resolve) => process.stdout.write("", resolve));
1953
- throw error;
1954
- }
1955
- };
1956
- }
1957
-
1958
1989
  // packages/cli/src/lib/print-config/print-config-command.ts
1959
1990
  function yargsConfigCommandObject() {
1960
1991
  const command = "print-config";
@@ -2012,12 +2043,12 @@ async function coreConfigMiddleware(processArgs) {
2012
2043
  upload: cliUpload,
2013
2044
  ...remainingCliOptions
2014
2045
  } = args;
2015
- const rcOptions = await readCodePushupConfig(config);
2046
+ const importedRc = config ? await readRcByPath(config) : await autoloadRc();
2016
2047
  const {
2017
2048
  persist: rcPersist,
2018
2049
  upload: rcUpload,
2019
2050
  ...remainingRcConfig
2020
- } = rcOptions;
2051
+ } = importedRc;
2021
2052
  const parsedProcessArgs = {
2022
2053
  config,
2023
2054
  ...remainingRcConfig,
@@ -2161,9 +2192,8 @@ function yargsGlobalOptionsDefinition() {
2161
2192
  default: false
2162
2193
  },
2163
2194
  config: {
2164
- describe: "Path the the config file, e.g. code-pushup.config.js",
2165
- type: "string",
2166
- default: "code-pushup.config.js"
2195
+ describe: "Path the the config file, e.g. code-pushup.config.ts. By default it loads code-pushup.config.(ts|mjs|js).",
2196
+ type: "string"
2167
2197
  }
2168
2198
  };
2169
2199
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-pushup/cli",
3
- "version": "0.10.7",
3
+ "version": "0.11.1",
4
4
  "license": "MIT",
5
5
  "bin": {
6
6
  "code-pushup": "index.js"