@code-pushup/create-cli 0.115.0 → 0.117.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-pushup/create-cli",
3
- "version": "0.115.0",
3
+ "version": "0.117.0",
4
4
  "license": "MIT",
5
5
  "bin": "index.js",
6
6
  "homepage": "https://github.com/code-pushup/cli/tree/main/packages/create-cli#readme",
@@ -26,8 +26,8 @@
26
26
  },
27
27
  "type": "module",
28
28
  "dependencies": {
29
- "@code-pushup/models": "0.115.0",
30
- "@code-pushup/utils": "0.115.0",
29
+ "@code-pushup/models": "0.117.0",
30
+ "@code-pushup/utils": "0.117.0",
31
31
  "@inquirer/prompts": "^8.0.0",
32
32
  "yargs": "^17.7.2"
33
33
  },
package/src/index.js CHANGED
@@ -1,8 +1,11 @@
1
1
  #! /usr/bin/env node
2
2
  import yargs from 'yargs';
3
3
  import { hideBin } from 'yargs/helpers';
4
- import { CONFIG_FILE_FORMATS } from './lib/setup/types.js';
4
+ import { parsePluginSlugs, validatePluginSlugs } from './lib/setup/plugins.js';
5
+ import { CONFIG_FILE_FORMATS, SETUP_MODES, } from './lib/setup/types.js';
5
6
  import { runSetupWizard } from './lib/setup/wizard.js';
7
+ // TODO: create, import and pass plugin bindings (eslint, coverage, lighthouse, typescript, js-packages, jsdocs, axe)
8
+ const bindings = [];
6
9
  const argv = await yargs(hideBin(process.argv))
7
10
  .option('dry-run', {
8
11
  type: 'boolean',
@@ -19,8 +22,21 @@ const argv = await yargs(hideBin(process.argv))
19
22
  type: 'string',
20
23
  choices: CONFIG_FILE_FORMATS,
21
24
  describe: 'Config file format (default: auto-detected from project)',
25
+ })
26
+ .option('plugins', {
27
+ type: 'string',
28
+ describe: 'Comma-separated plugin slugs to include (e.g. eslint,coverage)',
29
+ coerce: parsePluginSlugs,
30
+ })
31
+ .option('mode', {
32
+ type: 'string',
33
+ choices: SETUP_MODES,
34
+ describe: 'Setup mode (default: auto-detected from project)',
35
+ })
36
+ .check(parsed => {
37
+ validatePluginSlugs(bindings, parsed.plugins);
38
+ return true;
22
39
  })
23
40
  .parse();
24
- // TODO: #1244 — provide plugin bindings from registry
25
- await runSetupWizard([], argv);
41
+ await runSetupWizard(bindings, argv);
26
42
  //# sourceMappingURL=index.js.map
package/src/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;KAC5C,MAAM,CAAC,SAAS,EAAE;IACjB,IAAI,EAAE,SAAS;IACf,OAAO,EAAE,KAAK;IACd,QAAQ,EAAE,uCAAuC;CAClD,CAAC;KACD,MAAM,CAAC,KAAK,EAAE;IACb,KAAK,EAAE,GAAG;IACV,IAAI,EAAE,SAAS;IACf,OAAO,EAAE,KAAK;IACd,QAAQ,EAAE,+BAA+B;CAC1C,CAAC;KACD,MAAM,CAAC,eAAe,EAAE;IACvB,IAAI,EAAE,QAAQ;IACd,OAAO,EAAE,mBAAmB;IAC5B,QAAQ,EAAE,0DAA0D;CACrE,CAAC;KACD,KAAK,EAAE,CAAC;AAEX,sDAAsD;AACtD,MAAM,cAAc,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC/E,OAAO,EACL,mBAAmB,EAEnB,WAAW,GACZ,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD,qHAAqH;AACrH,MAAM,QAAQ,GAAyB,EAAE,CAAC;AAE1C,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;KAC5C,MAAM,CAAC,SAAS,EAAE;IACjB,IAAI,EAAE,SAAS;IACf,OAAO,EAAE,KAAK;IACd,QAAQ,EAAE,uCAAuC;CAClD,CAAC;KACD,MAAM,CAAC,KAAK,EAAE;IACb,KAAK,EAAE,GAAG;IACV,IAAI,EAAE,SAAS;IACf,OAAO,EAAE,KAAK;IACd,QAAQ,EAAE,+BAA+B;CAC1C,CAAC;KACD,MAAM,CAAC,eAAe,EAAE;IACvB,IAAI,EAAE,QAAQ;IACd,OAAO,EAAE,mBAAmB;IAC5B,QAAQ,EAAE,0DAA0D;CACrE,CAAC;KACD,MAAM,CAAC,SAAS,EAAE;IACjB,IAAI,EAAE,QAAQ;IACd,QAAQ,EAAE,gEAAgE;IAC1E,MAAM,EAAE,gBAAgB;CACzB,CAAC;KACD,MAAM,CAAC,MAAM,EAAE;IACd,IAAI,EAAE,QAAQ;IACd,OAAO,EAAE,WAAW;IACpB,QAAQ,EAAE,kDAAkD;CAC7D,CAAC;KACD,KAAK,CAAC,MAAM,CAAC,EAAE;IACd,mBAAmB,CAAC,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAC9C,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;KACD,KAAK,EAAE,CAAC;AAEX,MAAM,cAAc,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC"}
@@ -1,2 +1,5 @@
1
1
  import type { ConfigFileFormat, PluginCodegenResult } from './types.js';
2
2
  export declare function generateConfigSource(plugins: PluginCodegenResult[], format: ConfigFileFormat): string;
3
+ export declare function generatePresetSource(plugins: PluginCodegenResult[], format: ConfigFileFormat): string;
4
+ export declare function generateProjectSource(projectName: string, presetImportPath: string): string;
5
+ export declare function computeRelativePresetImport(projectRelativeDir: string, presetFilename: string): string;
@@ -1,3 +1,5 @@
1
+ import path from 'node:path';
2
+ import { toUnixPath } from '@code-pushup/utils';
1
3
  const CORE_CONFIG_IMPORT = {
2
4
  moduleSpecifier: '@code-pushup/models',
3
5
  namedImports: ['CoreConfig'],
@@ -20,6 +22,43 @@ class CodeBuilder {
20
22
  return `${this.lines.join('\n')}\n`;
21
23
  }
22
24
  }
25
+ export function generateConfigSource(plugins, format) {
26
+ const builder = new CodeBuilder();
27
+ addImports(builder, collectImports(plugins, format));
28
+ if (format === 'ts') {
29
+ builder.addLine('export default {');
30
+ addPlugins(builder, plugins);
31
+ builder.addLine('} satisfies CoreConfig;');
32
+ }
33
+ else {
34
+ builder.addLine("/** @type {import('@code-pushup/models').CoreConfig} */");
35
+ builder.addLine('export default {');
36
+ addPlugins(builder, plugins);
37
+ builder.addLine('};');
38
+ }
39
+ return builder.toString();
40
+ }
41
+ export function generatePresetSource(plugins, format) {
42
+ const builder = new CodeBuilder();
43
+ addImports(builder, collectImports(plugins, format));
44
+ addPresetExport(builder, plugins, format);
45
+ return builder.toString();
46
+ }
47
+ export function generateProjectSource(projectName, presetImportPath) {
48
+ const builder = new CodeBuilder();
49
+ builder.addLine(formatImport({
50
+ moduleSpecifier: presetImportPath,
51
+ namedImports: ['createConfig'],
52
+ }));
53
+ builder.addEmptyLine();
54
+ builder.addLine(`export default await createConfig('${projectName}');`);
55
+ return builder.toString();
56
+ }
57
+ export function computeRelativePresetImport(projectRelativeDir, presetFilename) {
58
+ const relativePath = path.relative(projectRelativeDir, presetFilename);
59
+ const importPath = toUnixPath(relativePath).replace(/\.ts$/, '.js');
60
+ return importPath.startsWith('.') ? importPath : `./${importPath}`;
61
+ }
23
62
  function formatImport({ moduleSpecifier, defaultImport, namedImports, isTypeOnly, }) {
24
63
  const named = namedImports?.length ? `{ ${namedImports.join(', ')} }` : '';
25
64
  const bindings = [defaultImport, named].filter(Boolean).join(', ');
@@ -27,53 +66,55 @@ function formatImport({ moduleSpecifier, defaultImport, namedImports, isTypeOnly
27
66
  const type = isTypeOnly ? 'type ' : '';
28
67
  return `import ${type}${from}'${moduleSpecifier}';`;
29
68
  }
30
- function collectTsImports(plugins) {
31
- return [
32
- CORE_CONFIG_IMPORT,
33
- ...plugins.flatMap(({ imports }) => imports),
34
- ].toSorted((a, b) => a.moduleSpecifier.localeCompare(b.moduleSpecifier));
69
+ function sortImports(imports) {
70
+ return imports.toSorted((a, b) => a.moduleSpecifier.localeCompare(b.moduleSpecifier));
35
71
  }
36
- function collectJsImports(plugins) {
37
- return plugins
38
- .flatMap(({ imports }) => imports)
39
- .map(({ isTypeOnly: _, ...rest }) => rest)
40
- .toSorted((a, b) => a.moduleSpecifier.localeCompare(b.moduleSpecifier));
72
+ function collectImports(plugins, format) {
73
+ const pluginImports = plugins.flatMap(({ imports }) => imports);
74
+ if (format === 'ts') {
75
+ return sortImports([CORE_CONFIG_IMPORT, ...pluginImports]);
76
+ }
77
+ return sortImports(pluginImports.map(({ isTypeOnly: _, ...rest }) => rest));
78
+ }
79
+ function addImports(builder, imports) {
80
+ if (imports.length > 0) {
81
+ builder.addLines(imports.map(formatImport));
82
+ builder.addEmptyLine();
83
+ }
41
84
  }
42
- function addPlugins(builder, plugins) {
85
+ function addPlugins(builder, plugins, depth = 1) {
86
+ builder.addLine('plugins: [', depth);
43
87
  if (plugins.length === 0) {
44
- builder.addLine('plugins: [],', 1);
88
+ builder.addLine('// TODO: register some plugins', depth + 1);
45
89
  }
46
90
  else {
47
- builder.addLine('plugins: [', 1);
48
- builder.addLines(plugins.map(({ pluginInit }) => `${pluginInit},`), 2);
49
- builder.addLine('],', 1);
91
+ builder.addLines(plugins.map(({ pluginInit }) => `${pluginInit},`), depth + 1);
50
92
  }
93
+ builder.addLine('],', depth);
51
94
  }
52
- export function generateConfigSource(plugins, format) {
53
- return format === 'ts'
54
- ? generateTsConfig(plugins)
55
- : generateJsConfig(plugins);
56
- }
57
- function generateTsConfig(plugins) {
58
- const builder = new CodeBuilder();
59
- builder.addLines(collectTsImports(plugins).map(formatImport));
60
- builder.addEmptyLine();
61
- builder.addLine('export default {');
62
- addPlugins(builder, plugins);
63
- builder.addLine('} satisfies CoreConfig;');
64
- return builder.toString();
65
- }
66
- function generateJsConfig(plugins) {
67
- const builder = new CodeBuilder();
68
- const pluginImports = collectJsImports(plugins);
69
- if (pluginImports.length > 0) {
70
- builder.addLines(pluginImports.map(formatImport));
71
- builder.addEmptyLine();
95
+ function addPresetExport(builder, plugins, format) {
96
+ if (format === 'ts') {
97
+ builder.addLines([
98
+ '/**',
99
+ ' * Creates a Code PushUp config for a project.',
100
+ ' * @param project Project name',
101
+ ' */',
102
+ 'export async function createConfig(project: string): Promise<CoreConfig> {',
103
+ ]);
72
104
  }
73
- builder.addLine("/** @type {import('@code-pushup/models').CoreConfig} */");
74
- builder.addLine('export default {');
75
- addPlugins(builder, plugins);
76
- builder.addLine('};');
77
- return builder.toString();
105
+ else {
106
+ builder.addLines([
107
+ '/**',
108
+ ' * Creates a Code PushUp config for a project.',
109
+ ' * @param {string} project Project name',
110
+ " * @returns {Promise<import('@code-pushup/models').CoreConfig>}",
111
+ ' */',
112
+ 'export async function createConfig(project) {',
113
+ ]);
114
+ }
115
+ builder.addLine('return {', 1);
116
+ addPlugins(builder, plugins, 2);
117
+ builder.addLine('};', 1);
118
+ builder.addLine('}');
78
119
  }
79
120
  //# sourceMappingURL=codegen.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"codegen.js","sourceRoot":"","sources":["../../../../src/lib/setup/codegen.ts"],"names":[],"mappings":"AAMA,MAAM,kBAAkB,GAA+B;IACrD,eAAe,EAAE,qBAAqB;IACtC,YAAY,EAAE,CAAC,YAAY,CAAC;IAC5B,UAAU,EAAE,IAAI;CACjB,CAAC;AAEF,MAAM,WAAW;IACP,KAAK,GAAa,EAAE,CAAC;IAE7B,OAAO,CAAC,IAAY,EAAE,KAAK,GAAG,CAAC;QAC7B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC;IAClD,CAAC;IAED,QAAQ,CAAC,KAAe,EAAE,KAAK,GAAG,CAAC;QACjC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;YACnB,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC5B,CAAC,CAAC,CAAC;IACL,CAAC;IAED,YAAY;QACV,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACtB,CAAC;IAED,QAAQ;QACN,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;IACtC,CAAC;CACF;AAED,SAAS,YAAY,CAAC,EACpB,eAAe,EACf,aAAa,EACb,YAAY,EACZ,UAAU,GACiB;IAC3B,MAAM,KAAK,GAAG,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3E,MAAM,QAAQ,GAAG,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnE,MAAM,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;IACjD,MAAM,IAAI,GAAG,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IACvC,OAAO,UAAU,IAAI,GAAG,IAAI,IAAI,eAAe,IAAI,CAAC;AACtD,CAAC;AAED,SAAS,gBAAgB,CACvB,OAA8B;IAE9B,OAAO;QACL,kBAAkB;QAClB,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC;KAC7C,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC;AAC3E,CAAC;AAED,SAAS,gBAAgB,CACvB,OAA8B;IAE9B,OAAO,OAAO;SACX,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC;SACjC,GAAG,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC;SACzC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC;AAC5E,CAAC;AAED,SAAS,UAAU,CACjB,OAAoB,EACpB,OAA8B;IAE9B,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC;IACrC,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;QACjC,OAAO,CAAC,QAAQ,CACd,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,GAAG,UAAU,GAAG,CAAC,EACjD,CAAC,CACF,CAAC;QACF,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAC3B,CAAC;AACH,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,OAA8B,EAC9B,MAAwB;IAExB,OAAO,MAAM,KAAK,IAAI;QACpB,CAAC,CAAC,gBAAgB,CAAC,OAAO,CAAC;QAC3B,CAAC,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;AAChC,CAAC;AAED,SAAS,gBAAgB,CAAC,OAA8B;IACtD,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;IAElC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC;IAC9D,OAAO,CAAC,YAAY,EAAE,CAAC;IACvB,OAAO,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACpC,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC7B,OAAO,CAAC,OAAO,CAAC,yBAAyB,CAAC,CAAC;IAE3C,OAAO,OAAO,CAAC,QAAQ,EAAE,CAAC;AAC5B,CAAC;AAED,SAAS,gBAAgB,CAAC,OAA8B;IACtD,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;IAElC,MAAM,aAAa,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAChD,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7B,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC;QAClD,OAAO,CAAC,YAAY,EAAE,CAAC;IACzB,CAAC;IAED,OAAO,CAAC,OAAO,CAAC,yDAAyD,CAAC,CAAC;IAC3E,OAAO,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACpC,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC7B,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtB,OAAO,OAAO,CAAC,QAAQ,EAAE,CAAC;AAC5B,CAAC"}
1
+ {"version":3,"file":"codegen.js","sourceRoot":"","sources":["../../../../src/lib/setup/codegen.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,5 @@ import type { PackageJson } from 'type-fest';
2
2
  import { type CliArgs, type ConfigFileFormat } from './types.js';
3
3
  /** Resolves config file format from CLI arg, auto-detection, or interactive prompt. */
4
4
  export declare function promptConfigFormat(targetDir: string, { 'config-format': format, yes }: CliArgs): Promise<ConfigFileFormat>;
5
- /** Returns `code-pushup.config.{ts,js,mjs}` based on format and ESM context. */
6
- export declare function resolveConfigFilename(format: ConfigFileFormat, isEsm: boolean): string;
5
+ export declare function resolveFilename(baseName: string, format: ConfigFileFormat, isEsm: boolean): string;
7
6
  export declare function readPackageJson(targetDir: string): Promise<PackageJson>;
@@ -22,15 +22,14 @@ export async function promptConfigFormat(targetDir, { 'config-format': format, y
22
22
  default: defaultFormat,
23
23
  });
24
24
  }
25
- /** Returns `code-pushup.config.{ts,js,mjs}` based on format and ESM context. */
26
- export function resolveConfigFilename(format, isEsm) {
25
+ export function resolveFilename(baseName, format, isEsm) {
27
26
  if (format === 'ts') {
28
- return 'code-pushup.config.ts';
27
+ return `${baseName}.ts`;
29
28
  }
30
29
  if (format === 'js' && isEsm) {
31
- return 'code-pushup.config.js';
30
+ return `${baseName}.js`;
32
31
  }
33
- return 'code-pushup.config.mjs';
32
+ return `${baseName}.mjs`;
34
33
  }
35
34
  export async function readPackageJson(targetDir) {
36
35
  const packageJsonPath = path.join(targetDir, 'package.json');
@@ -1 +1 @@
1
- {"version":3,"file":"config-format.js","sourceRoot":"","sources":["../../../../src/lib/setup/config-format.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EACL,mBAAmB,GAGpB,MAAM,YAAY,CAAC;AAEpB,MAAM,gBAAgB,GAAG,yBAAyB,CAAC;AAInD,uFAAuF;AACvF,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,SAAiB,EACjB,EAAE,eAAe,EAAE,MAAM,EAAE,GAAG,EAAW;IAEzC,IAAI,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC;QAC/B,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,MAAM,aAAa,GAAG,MAAM,mBAAmB,CAAC,SAAS,CAAC,CAAC;IAC3D,IAAI,GAAG,EAAE,CAAC;QACR,OAAO,aAAa,CAAC;IACvB,CAAC;IACD,OAAO,MAAM,CAAmB;QAC9B,OAAO,EAAE,qBAAqB;QAC9B,OAAO,EAAE;YACP,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,IAAI,EAAE;YACnC,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,IAAI,EAAE;SACpC;QACD,OAAO,EAAE,aAAa;KACvB,CAAC,CAAC;AACL,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,qBAAqB,CACnC,MAAwB,EACxB,KAAc;IAEd,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QACpB,OAAO,uBAAuB,CAAC;IACjC,CAAC;IACD,IAAI,MAAM,KAAK,IAAI,IAAI,KAAK,EAAE,CAAC;QAC7B,OAAO,uBAAuB,CAAC;IACjC,CAAC;IACD,OAAO,wBAAwB,CAAC;AAClC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,SAAiB;IACrD,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;IAC7D,IAAI,MAAM,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;QACtC,OAAO,YAAY,CAAc,eAAe,CAAC,CAAC;IACpD,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,KAAK,UAAU,mBAAmB,CAAC,SAAiB;IAClD,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,CAAC;IACvC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AACvE,CAAC;AAED,SAAS,kBAAkB,CACzB,KAAyB;IAEzB,MAAM,WAAW,GAAsB,mBAAmB,CAAC;IAC3D,OAAO,KAAK,IAAI,IAAI,IAAI,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AACtD,CAAC"}
1
+ {"version":3,"file":"config-format.js","sourceRoot":"","sources":["../../../../src/lib/setup/config-format.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EACL,mBAAmB,GAGpB,MAAM,YAAY,CAAC;AAEpB,MAAM,gBAAgB,GAAG,yBAAyB,CAAC;AAInD,uFAAuF;AACvF,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,SAAiB,EACjB,EAAE,eAAe,EAAE,MAAM,EAAE,GAAG,EAAW;IAEzC,IAAI,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC;QAC/B,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,MAAM,aAAa,GAAG,MAAM,mBAAmB,CAAC,SAAS,CAAC,CAAC;IAC3D,IAAI,GAAG,EAAE,CAAC;QACR,OAAO,aAAa,CAAC;IACvB,CAAC;IACD,OAAO,MAAM,CAAmB;QAC9B,OAAO,EAAE,qBAAqB;QAC9B,OAAO,EAAE;YACP,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,IAAI,EAAE;YACnC,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,IAAI,EAAE;SACpC;QACD,OAAO,EAAE,aAAa;KACvB,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,QAAgB,EAChB,MAAwB,EACxB,KAAc;IAEd,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QACpB,OAAO,GAAG,QAAQ,KAAK,CAAC;IAC1B,CAAC;IACD,IAAI,MAAM,KAAK,IAAI,IAAI,KAAK,EAAE,CAAC;QAC7B,OAAO,GAAG,QAAQ,KAAK,CAAC;IAC1B,CAAC;IACD,OAAO,GAAG,QAAQ,MAAM,CAAC;AAC3B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,SAAiB;IACrD,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;IAC7D,IAAI,MAAM,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;QACtC,OAAO,YAAY,CAAc,eAAe,CAAC,CAAC;IACpD,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,KAAK,UAAU,mBAAmB,CAAC,SAAiB;IAClD,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,CAAC;IACvC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AACvE,CAAC;AAED,SAAS,kBAAkB,CACzB,KAAyB;IAEzB,MAAM,WAAW,GAAsB,mBAAmB,CAAC;IAC3D,OAAO,KAAK,IAAI,IAAI,IAAI,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AACtD,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { Tree } from './types.js';
2
+ export declare function resolveGitignore(tree: Tree): Promise<void>;
@@ -0,0 +1,32 @@
1
+ const GITIGNORE_FILENAME = '.gitignore';
2
+ const REPORTS_DIR = '.code-pushup';
3
+ const REPORTS_DIR_ENTRIES = new Set([REPORTS_DIR, `**/${REPORTS_DIR}`]);
4
+ const REPORTS_SECTION = `# Code PushUp reports\n${REPORTS_DIR}\n`;
5
+ export async function resolveGitignore(tree) {
6
+ const content = await tree.read(GITIGNORE_FILENAME);
7
+ const updated = resolveGitignoreContent(content);
8
+ if (updated != null) {
9
+ await tree.write(GITIGNORE_FILENAME, updated);
10
+ }
11
+ }
12
+ function resolveGitignoreContent(content) {
13
+ if (content == null) {
14
+ return REPORTS_SECTION;
15
+ }
16
+ if (gitignoreContainsEntry(content)) {
17
+ return null;
18
+ }
19
+ const separator = content.endsWith('\n\n')
20
+ ? ''
21
+ : content.endsWith('\n')
22
+ ? '\n'
23
+ : '\n\n';
24
+ return `${content}${separator}${REPORTS_SECTION}`;
25
+ }
26
+ function gitignoreContainsEntry(content) {
27
+ return content.split('\n').some(raw => {
28
+ const line = raw.trim();
29
+ return (line !== '' && !line.startsWith('#') && REPORTS_DIR_ENTRIES.has(line));
30
+ });
31
+ }
32
+ //# sourceMappingURL=gitignore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gitignore.js","sourceRoot":"","sources":["../../../../src/lib/setup/gitignore.ts"],"names":[],"mappings":"AAEA,MAAM,kBAAkB,GAAG,YAAY,CAAC;AACxC,MAAM,WAAW,GAAG,cAAc,CAAC;AACnC,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,MAAM,WAAW,EAAE,CAAC,CAAC,CAAC;AACxE,MAAM,eAAe,GAAG,0BAA0B,WAAW,IAAI,CAAC;AAElE,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,IAAU;IAC/C,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IACpD,MAAM,OAAO,GAAG,uBAAuB,CAAC,OAAO,CAAC,CAAC;IAEjD,IAAI,OAAO,IAAI,IAAI,EAAE,CAAC;QACpB,MAAM,IAAI,CAAC,KAAK,CAAC,kBAAkB,EAAE,OAAO,CAAC,CAAC;IAChD,CAAC;AACH,CAAC;AAED,SAAS,uBAAuB,CAAC,OAAsB;IACrD,IAAI,OAAO,IAAI,IAAI,EAAE,CAAC;QACpB,OAAO,eAAe,CAAC;IACzB,CAAC;IACD,IAAI,sBAAsB,CAAC,OAAO,CAAC,EAAE,CAAC;QACpC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,SAAS,GAAG,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;QACxC,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;YACtB,CAAC,CAAC,IAAI;YACN,CAAC,CAAC,MAAM,CAAC;IAEb,OAAO,GAAG,OAAO,GAAG,SAAS,GAAG,eAAe,EAAE,CAAC;AACpD,CAAC;AAED,SAAS,sBAAsB,CAAC,OAAe;IAC7C,OAAO,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;QACpC,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;QACxB,OAAO,CACL,IAAI,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,mBAAmB,CAAC,GAAG,CAAC,IAAI,CAAC,CACtE,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { type MonorepoTool } from '@code-pushup/utils';
2
+ import type { CliArgs, ConfigContext, Tree, WizardProject } from './types.js';
3
+ export declare function promptSetupMode(targetDir: string, cliArgs: CliArgs): Promise<ConfigContext>;
4
+ export declare function listProjects(cwd: string, tool: MonorepoTool): Promise<WizardProject[]>;
5
+ export declare function addCodePushUpCommand(tree: Tree, project: WizardProject, tool: MonorepoTool | null): Promise<void>;
@@ -0,0 +1,134 @@
1
+ import { select } from '@inquirer/prompts';
2
+ import path from 'node:path';
3
+ import { MONOREPO_TOOL_DETECTORS, detectMonorepoTool, hasScript, listPackages, listWorkspaces, loadNxProjectGraph, logger, readPnpmWorkspacePatterns, toUnixPath, } from '@code-pushup/utils';
4
+ const TASK_NAME = 'code-pushup';
5
+ export async function promptSetupMode(targetDir, cliArgs) {
6
+ switch (cliArgs.mode) {
7
+ case 'standalone':
8
+ return toContext(cliArgs.mode, null);
9
+ case 'monorepo': {
10
+ const tool = await detectMonorepoTool(targetDir);
11
+ return toContext(cliArgs.mode, tool);
12
+ }
13
+ case undefined: {
14
+ const tool = await detectMonorepoTool(targetDir);
15
+ const mode = cliArgs.yes ? inferMode(tool) : await promptMode(tool);
16
+ return toContext(mode, tool);
17
+ }
18
+ }
19
+ }
20
+ async function promptMode(tool) {
21
+ return select({
22
+ message: 'Setup mode:',
23
+ choices: [
24
+ { name: 'Standalone (single config)', value: 'standalone' },
25
+ { name: 'Monorepo (per-project configs)', value: 'monorepo' },
26
+ ],
27
+ default: inferMode(tool),
28
+ });
29
+ }
30
+ function inferMode(tool) {
31
+ return tool ? 'monorepo' : 'standalone';
32
+ }
33
+ function toContext(mode, tool) {
34
+ if (mode === 'monorepo' && tool == null) {
35
+ logger.warn('No monorepo tool detected, falling back to standalone mode.');
36
+ return { mode: 'standalone', tool: null };
37
+ }
38
+ return { mode, tool };
39
+ }
40
+ export async function listProjects(cwd, tool) {
41
+ switch (tool) {
42
+ case 'nx':
43
+ return listNxProjects(cwd);
44
+ case 'pnpm':
45
+ return listPnpmProjects(cwd);
46
+ case 'turbo':
47
+ return listTurboProjects(cwd);
48
+ case 'yarn':
49
+ case 'npm':
50
+ return listWorkspaceProjects(cwd);
51
+ }
52
+ }
53
+ async function listNxProjects(cwd) {
54
+ const graph = await loadNxProjectGraph();
55
+ return Object.values(graph.nodes).map(({ name, data }) => ({
56
+ name,
57
+ directory: path.join(cwd, data.root),
58
+ relativeDir: toUnixPath(data.root),
59
+ }));
60
+ }
61
+ async function listPnpmProjects(cwd) {
62
+ const patterns = await readPnpmWorkspacePatterns(cwd);
63
+ const packages = await listPackages(cwd, patterns);
64
+ return packages.map(pkg => toProject(cwd, pkg));
65
+ }
66
+ async function listTurboProjects(cwd) {
67
+ if (await MONOREPO_TOOL_DETECTORS.pnpm(cwd)) {
68
+ return listPnpmProjects(cwd);
69
+ }
70
+ return listWorkspaceProjects(cwd);
71
+ }
72
+ async function listWorkspaceProjects(cwd) {
73
+ const { workspaces } = await listWorkspaces(cwd);
74
+ return workspaces.map(pkg => toProject(cwd, pkg));
75
+ }
76
+ export async function addCodePushUpCommand(tree, project, tool) {
77
+ if (tool === 'nx') {
78
+ const added = await addNxTarget(tree, project);
79
+ if (added) {
80
+ return;
81
+ }
82
+ }
83
+ await addPackageJsonScript(tree, project);
84
+ }
85
+ async function addNxTarget(tree, project) {
86
+ const filePath = toUnixPath(path.join(project.relativeDir, 'project.json'));
87
+ const raw = await tree.read(filePath);
88
+ if (raw == null) {
89
+ return false;
90
+ }
91
+ const config = JSON.parse(raw);
92
+ if (config.targets[TASK_NAME] != null) {
93
+ return true;
94
+ }
95
+ const updated = {
96
+ ...config,
97
+ targets: {
98
+ ...config.targets,
99
+ [TASK_NAME]: {
100
+ executor: 'nx:run-commands',
101
+ options: { command: 'npx code-pushup' },
102
+ },
103
+ },
104
+ };
105
+ await tree.write(filePath, `${JSON.stringify(updated, null, 2)}\n`);
106
+ return true;
107
+ }
108
+ async function addPackageJsonScript(tree, project) {
109
+ const filePath = toUnixPath(path.join(project.relativeDir, 'package.json'));
110
+ const raw = await tree.read(filePath);
111
+ if (raw == null) {
112
+ return;
113
+ }
114
+ const packageJson = JSON.parse(raw);
115
+ if (hasScript(packageJson, TASK_NAME)) {
116
+ return;
117
+ }
118
+ const updated = {
119
+ ...packageJson,
120
+ scripts: {
121
+ ...packageJson.scripts,
122
+ [TASK_NAME]: 'code-pushup',
123
+ },
124
+ };
125
+ await tree.write(filePath, `${JSON.stringify(updated, null, 2)}\n`);
126
+ }
127
+ function toProject(cwd, pkg) {
128
+ return {
129
+ name: pkg.name,
130
+ directory: pkg.directory,
131
+ relativeDir: toUnixPath(path.relative(cwd, pkg.directory)),
132
+ };
133
+ }
134
+ //# sourceMappingURL=monorepo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"monorepo.js","sourceRoot":"","sources":["../../../../src/lib/setup/monorepo.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { PluginSetupBinding } from './types.js';
2
+ /** Parses a comma-separated string of plugin slugs into a deduplicated array. */
3
+ export declare function parsePluginSlugs(value: string): string[];
4
+ /** Throws if any slug is not found in the available bindings. */
5
+ export declare function validatePluginSlugs(bindings: PluginSetupBinding[], plugins?: string[]): void;
@@ -0,0 +1,20 @@
1
+ /** Parses a comma-separated string of plugin slugs into a deduplicated array. */
2
+ export function parsePluginSlugs(value) {
3
+ return [
4
+ ...new Set(value
5
+ .split(',')
6
+ .map(s => s.trim())
7
+ .filter(Boolean)),
8
+ ];
9
+ }
10
+ /** Throws if any slug is not found in the available bindings. */
11
+ export function validatePluginSlugs(bindings, plugins) {
12
+ if (plugins == null || plugins.length === 0) {
13
+ return;
14
+ }
15
+ const unknown = plugins.filter(slug => !bindings.some(b => b.slug === slug));
16
+ if (unknown.length > 0) {
17
+ throw new TypeError(`Unknown plugin slugs: ${unknown.join(', ')}. Available: ${bindings.map(b => b.slug).join(', ')}`);
18
+ }
19
+ }
20
+ //# sourceMappingURL=plugins.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugins.js","sourceRoot":"","sources":["../../../../src/lib/setup/plugins.ts"],"names":[],"mappings":"AAEA,iFAAiF;AACjF,MAAM,UAAU,gBAAgB,CAAC,KAAa;IAC5C,OAAO;QACL,GAAG,IAAI,GAAG,CACR,KAAK;aACF,KAAK,CAAC,GAAG,CAAC;aACV,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;aAClB,MAAM,CAAC,OAAO,CAAC,CACnB;KACF,CAAC;AACJ,CAAC;AAED,iEAAiE;AACjE,MAAM,UAAU,mBAAmB,CACjC,QAA8B,EAC9B,OAAkB;IAElB,IAAI,OAAO,IAAI,IAAI,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5C,OAAO;IACT,CAAC;IACD,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC;IAC7E,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,SAAS,CACjB,yBAAyB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAClG,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -1,2 +1,11 @@
1
- import type { CliArgs, PluginPromptDescriptor } from './types.js';
1
+ import type { CliArgs, PluginPromptDescriptor, PluginSetupBinding } from './types.js';
2
+ /**
3
+ * Resolves which plugins to include in the generated config.
4
+ *
5
+ * Resolution order (first match wins):
6
+ * 1. `--plugins`: user-provided slugs
7
+ * 2. `--yes`: recommended plugins
8
+ * 3. Interactive: checkbox prompt with recommended plugins pre-checked
9
+ */
10
+ export declare function promptPluginSelection(bindings: PluginSetupBinding[], targetDir: string, { plugins, yes }: CliArgs): Promise<PluginSetupBinding[]>;
2
11
  export declare function promptPluginOptions(descriptors: PluginPromptDescriptor[], cliArgs: CliArgs): Promise<Record<string, string | string[]>>;
@@ -1,6 +1,49 @@
1
1
  import { checkbox, input, select } from '@inquirer/prompts';
2
2
  import { asyncSequential } from '@code-pushup/utils';
3
- // TODO: #1244 — add promptPluginSelection (multi-select prompt with pre-selection callbacks)
3
+ /**
4
+ * Resolves which plugins to include in the generated config.
5
+ *
6
+ * Resolution order (first match wins):
7
+ * 1. `--plugins`: user-provided slugs
8
+ * 2. `--yes`: recommended plugins
9
+ * 3. Interactive: checkbox prompt with recommended plugins pre-checked
10
+ */
11
+ export async function promptPluginSelection(bindings, targetDir, { plugins, yes }) {
12
+ if (bindings.length === 0) {
13
+ return [];
14
+ }
15
+ if (plugins != null && plugins.length > 0) {
16
+ return bindings.filter(b => plugins.includes(b.slug));
17
+ }
18
+ const recommended = await detectRecommended(bindings, targetDir);
19
+ if (yes) {
20
+ return bindings.filter(({ slug }) => recommended.has(slug));
21
+ }
22
+ const selected = await checkbox({
23
+ message: 'Plugins to include:',
24
+ required: true,
25
+ choices: bindings.map(({ title, slug }) => ({
26
+ name: title,
27
+ value: slug,
28
+ checked: recommended.has(slug),
29
+ })),
30
+ });
31
+ const selectedSet = new Set(selected);
32
+ return bindings.filter(({ slug }) => selectedSet.has(slug));
33
+ }
34
+ /**
35
+ * Calls each binding's `isRecommended` callback (if provided)
36
+ * and collects the slugs of bindings that returned `true`.
37
+ */
38
+ async function detectRecommended(bindings, targetDir) {
39
+ const recommended = new Set();
40
+ await Promise.all(bindings.map(async ({ slug, isRecommended }) => {
41
+ if (isRecommended && (await isRecommended(targetDir))) {
42
+ recommended.add(slug);
43
+ }
44
+ }));
45
+ return recommended;
46
+ }
4
47
  export async function promptPluginOptions(descriptors, cliArgs) {
5
48
  const fallback = cliArgs['yes']
6
49
  ? (descriptor) => descriptor.default
@@ -1 +1 @@
1
- {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../../../src/lib/setup/prompts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAGrD,6FAA6F;AAE7F,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,WAAqC,EACrC,OAAgB;IAEhB,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC;QAC7B,CAAC,CAAC,CAAC,UAAkC,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO;QAC5D,CAAC,CAAC,SAAS,CAAC;IAEd,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC,WAAW,EAAE,KAAK,EAAC,UAAU,EAAC,EAAE,CAAC;QACrE,UAAU,CAAC,GAAG;QACd,QAAQ,CAAC,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,CAAC,MAAM,QAAQ,CAAC,UAAU,CAAC,CAAC;KAClE,CAAC,CAAC;IACH,OAAO,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;AACrC,CAAC;AAED,SAAS,QAAQ,CAAC,GAAW,EAAE,OAAgB;IAC7C,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IAC3B,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AACvD,CAAC;AAED,KAAK,UAAU,SAAS,CACtB,UAAkC;IAElC,QAAQ,UAAU,CAAC,IAAI,EAAE,CAAC;QACxB,KAAK,OAAO;YACV,OAAO,KAAK,CAAC;gBACX,OAAO,EAAE,UAAU,CAAC,OAAO;gBAC3B,OAAO,EAAE,UAAU,CAAC,OAAO;aAC5B,CAAC,CAAC;QACL,KAAK,QAAQ;YACX,OAAO,MAAM,CAAC;gBACZ,OAAO,EAAE,UAAU,CAAC,OAAO;gBAC3B,OAAO,EAAE,CAAC,GAAG,UAAU,CAAC,OAAO,CAAC;aACjC,CAAC,CAAC;QACL,KAAK,UAAU;YACb,OAAO,QAAQ,CAAC;gBACd,OAAO,EAAE,UAAU,CAAC,OAAO;gBAC3B,OAAO,EAAE,CAAC,GAAG,UAAU,CAAC,OAAO,CAAC;aACjC,CAAC,CAAC;IACP,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../../../src/lib/setup/prompts.ts"],"names":[],"mappings":"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"}
@@ -1,44 +1,19 @@
1
1
  import type { PluginMeta } from '@code-pushup/models';
2
+ import type { MonorepoTool } from '@code-pushup/utils';
2
3
  export declare const CONFIG_FILE_FORMATS: readonly ["ts", "js", "mjs"];
3
4
  export type ConfigFileFormat = (typeof CONFIG_FILE_FORMATS)[number];
4
- /** Virtual file system that buffers writes in memory until flushed to disk. */
5
- export type Tree = {
6
- root: string;
7
- exists: (filePath: string) => Promise<boolean>;
8
- read: (filePath: string) => Promise<string | null>;
9
- write: (filePath: string, content: string) => Promise<void>;
10
- listChanges: () => FileChange[];
11
- flush: () => Promise<void>;
12
- };
13
- export type FileChange = {
14
- path: string;
15
- type: 'CREATE' | 'UPDATE';
16
- content: string;
17
- };
18
- export type FileSystemAdapter = {
19
- readFile: (path: string, encoding: 'utf8') => Promise<string>;
20
- writeFile: (path: string, content: string) => Promise<void>;
21
- exists: (path: string) => Promise<boolean>;
22
- mkdir: (path: string, options: {
23
- recursive: true;
24
- }) => Promise<string | undefined>;
25
- };
26
- export type PluginSetupBinding = {
27
- slug: PluginMeta['slug'];
28
- title: PluginMeta['title'];
29
- packageName: NonNullable<PluginMeta['packageName']>;
30
- prompts?: PluginPromptDescriptor[];
31
- generateConfig: (answers: Record<string, string | string[]>) => PluginCodegenResult;
32
- };
33
- export type ImportDeclarationStructure = {
34
- moduleSpecifier: string;
35
- defaultImport?: string;
36
- namedImports?: string[];
37
- isTypeOnly?: boolean;
38
- };
39
- export type PluginCodegenResult = {
40
- imports: ImportDeclarationStructure[];
41
- pluginInit: string;
5
+ export declare const SETUP_MODES: readonly ["standalone", "monorepo"];
6
+ export type SetupMode = (typeof SETUP_MODES)[number];
7
+ export declare const PLUGIN_SCOPES: readonly ["project", "root"];
8
+ export type PluginScope = (typeof PLUGIN_SCOPES)[number];
9
+ export type CliArgs = {
10
+ 'dry-run'?: boolean;
11
+ yes?: boolean;
12
+ 'config-format'?: string;
13
+ mode?: SetupMode;
14
+ plugins?: string[];
15
+ 'target-dir'?: string;
16
+ [key: string]: unknown;
42
17
  };
43
18
  type PromptBase = {
44
19
  key: string;
@@ -62,12 +37,79 @@ type CheckboxPrompt<T extends string = string> = PromptBase & {
62
37
  choices: PromptChoice<T>[];
63
38
  default: T[];
64
39
  };
40
+ /** Declarative prompt definition used to collect plugin-specific options. */
65
41
  export type PluginPromptDescriptor = InputPrompt | SelectPrompt | CheckboxPrompt;
66
- export type CliArgs = {
67
- 'dry-run'?: boolean;
68
- yes?: boolean;
69
- 'config-format'?: string;
70
- 'target-dir'?: string;
71
- [key: string]: unknown;
42
+ export type ImportDeclarationStructure = {
43
+ moduleSpecifier: string;
44
+ defaultImport?: string;
45
+ namedImports?: string[];
46
+ isTypeOnly?: boolean;
47
+ };
48
+ /** Import declarations and plugin initialization code produced by `generateConfig`. */
49
+ export type PluginCodegenResult = {
50
+ imports: ImportDeclarationStructure[];
51
+ pluginInit: string;
52
+ };
53
+ export type ScopedPluginResult = {
54
+ scope: PluginScope;
55
+ result: PluginCodegenResult;
56
+ };
57
+ /** Context describing the current setup mode, passed to plugin codegen. */
58
+ export type ConfigContext = {
59
+ mode: SetupMode;
60
+ tool: MonorepoTool | null;
61
+ };
62
+ /**
63
+ * Defines how a plugin integrates with the setup wizard.
64
+ *
65
+ * Each supported plugin provides a binding that controls:
66
+ * - Pre-selection: `isRecommended` detects if the plugin is relevant for the repository
67
+ * - Configuration: `prompts` collect plugin-specific options interactively
68
+ * - Code generation: `generateConfig` produces the import and initialization code
69
+ */
70
+ export type PluginSetupBinding = {
71
+ slug: PluginMeta['slug'];
72
+ title: PluginMeta['title'];
73
+ packageName: NonNullable<PluginMeta['packageName']>;
74
+ prompts?: PluginPromptDescriptor[];
75
+ scope?: PluginScope;
76
+ isRecommended?: (targetDir: string) => Promise<boolean>;
77
+ generateConfig: (answers: Record<string, string | string[]>, context: ConfigContext) => PluginCodegenResult;
78
+ };
79
+ /** A project discovered in a monorepo workspace. */
80
+ export type WizardProject = {
81
+ name: string;
82
+ directory: string;
83
+ relativeDir: string;
84
+ };
85
+ export type WriteContext = {
86
+ tree: Tree;
87
+ format: ConfigFileFormat;
88
+ configFilename: string;
89
+ isEsm: boolean;
90
+ };
91
+ /** A single file operation recorded by the virtual tree. */
92
+ export type FileChange = {
93
+ path: string;
94
+ type: 'CREATE' | 'UPDATE';
95
+ content: string;
96
+ };
97
+ /** Virtual file system that buffers writes in memory until flushed to disk. */
98
+ export type Tree = {
99
+ root: string;
100
+ exists: (filePath: string) => Promise<boolean>;
101
+ read: (filePath: string) => Promise<string | null>;
102
+ write: (filePath: string, content: string) => Promise<void>;
103
+ listChanges: () => FileChange[];
104
+ flush: () => Promise<void>;
105
+ };
106
+ /** Abstraction over `node:fs` used by the virtual tree for disk I/O. */
107
+ export type FileSystemAdapter = {
108
+ readFile: (path: string, encoding: 'utf8') => Promise<string>;
109
+ writeFile: (path: string, content: string) => Promise<void>;
110
+ exists: (path: string) => Promise<boolean>;
111
+ mkdir: (path: string, options: {
112
+ recursive: true;
113
+ }) => Promise<string | undefined>;
72
114
  };
73
115
  export {};
@@ -1,2 +1,4 @@
1
1
  export const CONFIG_FILE_FORMATS = ['ts', 'js', 'mjs'];
2
+ export const SETUP_MODES = ['standalone', 'monorepo'];
3
+ export const PLUGIN_SCOPES = ['project', 'root'];
2
4
  //# sourceMappingURL=types.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/lib/setup/types.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAU,CAAC"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/lib/setup/types.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAU,CAAC;AAGhE,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,YAAY,EAAE,UAAU,CAAU,CAAC;AAG/D,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,SAAS,EAAE,MAAM,CAAU,CAAC"}
@@ -1,3 +1,8 @@
1
1
  import type { CliArgs, PluginSetupBinding } from './types.js';
2
- /** Runs the interactive setup wizard that generates a Code PushUp config file. */
2
+ /**
3
+ * Runs the interactive setup wizard that generates a Code PushUp config file.
4
+ *
5
+ * All file changes are buffered in a virtual tree rooted at the git root,
6
+ * then flushed to disk in one step (or skipped on `--dry-run`).
7
+ */
3
8
  export declare function runSetupWizard(bindings: PluginSetupBinding[], cliArgs: CliArgs): Promise<void>;
@@ -1,40 +1,76 @@
1
- import { asyncSequential, formatAsciiTable, logger } from '@code-pushup/utils';
2
- import { generateConfigSource } from './codegen.js';
3
- import { promptConfigFormat, readPackageJson, resolveConfigFilename, } from './config-format.js';
4
- import { promptPluginOptions } from './prompts.js';
1
+ import path from 'node:path';
2
+ import { asyncSequential, formatAsciiTable, getGitRoot, logger, toUnixPath, } from '@code-pushup/utils';
3
+ import { computeRelativePresetImport, generateConfigSource, generatePresetSource, generateProjectSource, } from './codegen.js';
4
+ import { promptConfigFormat, readPackageJson, resolveFilename, } from './config-format.js';
5
+ import { resolveGitignore } from './gitignore.js';
6
+ import { addCodePushUpCommand, listProjects, promptSetupMode, } from './monorepo.js';
7
+ import { promptPluginOptions, promptPluginSelection } from './prompts.js';
5
8
  import { createTree } from './virtual-fs.js';
6
- /** Runs the interactive setup wizard that generates a Code PushUp config file. */
9
+ /**
10
+ * Runs the interactive setup wizard that generates a Code PushUp config file.
11
+ *
12
+ * All file changes are buffered in a virtual tree rooted at the git root,
13
+ * then flushed to disk in one step (or skipped on `--dry-run`).
14
+ */
7
15
  export async function runSetupWizard(bindings, cliArgs) {
8
16
  const targetDir = cliArgs['target-dir'] ?? process.cwd();
9
- // TODO: #1245 prompt for standalone vs monorepo mode
10
- // TODO: #1244 prompt user to select plugins from available bindings
17
+ const { mode, tool } = await promptSetupMode(targetDir, cliArgs);
18
+ const selectedBindings = await promptPluginSelection(bindings, targetDir, cliArgs);
11
19
  const format = await promptConfigFormat(targetDir, cliArgs);
12
20
  const packageJson = await readPackageJson(targetDir);
13
- const filename = resolveConfigFilename(format, packageJson.type === 'module');
14
- const pluginResults = await asyncSequential(bindings, binding => resolveBinding(binding, cliArgs));
15
- const tree = createTree(targetDir);
16
- await tree.write(filename, generateConfigSource(pluginResults, format));
17
- const changes = tree.listChanges();
21
+ const isEsm = packageJson.type === 'module';
22
+ const configFilename = resolveFilename('code-pushup.config', format, isEsm);
23
+ const resolved = await asyncSequential(selectedBindings, async (binding) => ({
24
+ scope: binding.scope ?? 'project',
25
+ result: await resolveBinding(binding, cliArgs, { mode, tool }),
26
+ }));
27
+ const gitRoot = await getGitRoot();
28
+ const tree = createTree(gitRoot);
29
+ const writeContext = { tree, format, configFilename, isEsm };
30
+ await (mode === 'monorepo' && tool != null
31
+ ? writeMonorepoConfigs(writeContext, resolved, targetDir, tool)
32
+ : writeStandaloneConfig(writeContext, resolved.map(r => r.result)));
33
+ await resolveGitignore(tree);
34
+ logChanges(tree.listChanges());
18
35
  if (cliArgs['dry-run']) {
19
- logChanges(changes);
20
36
  logger.info('Dry run — no files written.');
37
+ return;
21
38
  }
22
- else {
23
- await tree.flush();
24
- logChanges(changes);
25
- logger.info('Setup complete.');
26
- logger.newline();
27
- logNextSteps([
28
- ['npx code-pushup', 'Collect your first report'],
29
- ['https://github.com/code-pushup/cli#readme', 'Documentation'],
30
- ]);
31
- }
39
+ await tree.flush();
40
+ logger.info('Setup complete.');
41
+ logger.newline();
42
+ logNextSteps([
43
+ ['npx code-pushup', 'Collect your first report'],
44
+ ['https://github.com/code-pushup/cli#readme', 'Documentation'],
45
+ ]);
32
46
  }
33
- async function resolveBinding(binding, cliArgs) {
47
+ async function resolveBinding(binding, cliArgs, context) {
34
48
  const answers = binding.prompts
35
49
  ? await promptPluginOptions(binding.prompts, cliArgs)
36
50
  : {};
37
- return binding.generateConfig(answers);
51
+ return binding.generateConfig(answers, context);
52
+ }
53
+ async function writeStandaloneConfig({ tree, format, configFilename }, results) {
54
+ await tree.write(configFilename, generateConfigSource(results, format));
55
+ }
56
+ async function writeMonorepoConfigs({ tree, format, configFilename, isEsm }, resolved, targetDir, tool) {
57
+ const projectResults = resolved
58
+ .filter(r => r.scope === 'project')
59
+ .map(r => r.result);
60
+ const rootResults = resolved
61
+ .filter(r => r.scope === 'root')
62
+ .map(r => r.result);
63
+ const presetFilename = resolveFilename('code-pushup.preset', format, isEsm);
64
+ await tree.write(presetFilename, generatePresetSource(projectResults, format));
65
+ if (rootResults.length > 0) {
66
+ await tree.write(configFilename, generateConfigSource(rootResults, format));
67
+ }
68
+ const projects = await listProjects(targetDir, tool);
69
+ await Promise.all(projects.map(async (project) => {
70
+ const importPath = computeRelativePresetImport(project.relativeDir, presetFilename);
71
+ await tree.write(toUnixPath(path.join(project.relativeDir, configFilename)), generateProjectSource(project.name, importPath));
72
+ await addCodePushUpCommand(tree, project, tool);
73
+ }));
38
74
  }
39
75
  function logChanges(changes) {
40
76
  changes.forEach(change => {
@@ -1 +1 @@
1
- {"version":3,"file":"wizard.js","sourceRoot":"","sources":["../../../../src/lib/setup/wizard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC/E,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,qBAAqB,GACtB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAOnD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,kFAAkF;AAClF,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,QAA8B,EAC9B,OAAgB;IAEhB,MAAM,SAAS,GAAG,OAAO,CAAC,YAAY,CAAC,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAEzD,uDAAuD;IACvD,sEAAsE;IAEtE,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAC5D,MAAM,WAAW,GAAG,MAAM,eAAe,CAAC,SAAS,CAAC,CAAC;IACrD,MAAM,QAAQ,GAAG,qBAAqB,CAAC,MAAM,EAAE,WAAW,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;IAE9E,MAAM,aAAa,GAAG,MAAM,eAAe,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE,CAC9D,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,CACjC,CAAC;IAEF,MAAM,IAAI,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC;IACnC,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,oBAAoB,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC;IAExE,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IAEnC,IAAI,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;QACvB,UAAU,CAAC,OAAO,CAAC,CAAC;QACpB,MAAM,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;IAC7C,CAAC;SAAM,CAAC;QACN,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;QACnB,UAAU,CAAC,OAAO,CAAC,CAAC;QACpB,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAC/B,MAAM,CAAC,OAAO,EAAE,CAAC;QACjB,YAAY,CAAC;YACX,CAAC,iBAAiB,EAAE,2BAA2B,CAAC;YAChD,CAAC,2CAA2C,EAAE,eAAe,CAAC;SAC/D,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED,KAAK,UAAU,cAAc,CAC3B,OAA2B,EAC3B,OAAgB;IAEhB,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO;QAC7B,CAAC,CAAC,MAAM,mBAAmB,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC;QACrD,CAAC,CAAC,EAAE,CAAC;IACP,OAAO,OAAO,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;AACzC,CAAC;AAED,SAAS,UAAU,CAAC,OAAqB;IACvC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;QACvB,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,YAAY,CAAC,KAAyB;IAC7C,MAAM,CAAC,IAAI,CACT,gBAAgB,CACd;QACE,KAAK,EAAE,aAAa;QACpB,IAAI,EAAE,KAAK;KACZ,EACD,EAAE,UAAU,EAAE,IAAI,EAAE,CACrB,CACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"wizard.js","sourceRoot":"","sources":["../../../../src/lib/setup/wizard.ts"],"names":[],"mappings":"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"}