Files
renovate/lib/workers/repository/onboarding/pr/package-files.ts
Jamie Tanna bcd44b991f feat(onboarding): add a summary for detected package files (#44258)
* refactor(onboarding): extract a function for calculating packageFiles

As part of a future change, we'll introduce a "summary" view for larger
repositories, and having a function extracted makes intent clearer.

Co-authored-by: Claude Sonnet 4.6 <jamie.tanna+claude-code@mend.io>

* refactor(onboarding): add a summary for detected package files

As part of future changes in #41502, we're introducing a
Platform-limit-aware onboarding/reconfigure flow that will provide a
summary where appropriate.

Before we do so, we can introduce the new functionality - but not
integrate it right now - to incrementally add support.

As a slightly better interface when we have a large list of detected
package files, we can provide a summary per Manager.

Co-authored-by: Claude Sonnet 4.6 <jamie.tanna+claude-code@mend.io>

* refactor(onboarding): group 3+ files under a directory as a list

As it's a more readable summary, especially with i.e. GitHub Actions,
where all package files commonly share the same directory.

The use of `3` as the lower bound was chosen without any research or too much
thought put into it.

Co-authored-by: Claude Sonnet 4.6 <jamie.tanna+claude-code@mend.io>

---------

Co-authored-by: Claude Sonnet 4.6 <jamie.tanna+claude-code@mend.io>
2026-06-27 15:14:00 +00:00

63 lines
1.8 KiB
TypeScript

import type { PackageFile } from '../../../../modules/manager/types.ts';
const GROUP_THRESHOLD = 3;
function formatManagerFiles(files: PackageFile[]): string {
const byDir = new Map<string, string[]>();
for (const { packageFile } of files) {
const lastSlash = packageFile.lastIndexOf('/');
const dir = lastSlash >= 0 ? packageFile.slice(0, lastSlash + 1) : '';
const name =
lastSlash >= 0 ? packageFile.slice(lastSlash + 1) : packageFile;
const existing = byDir.get(dir);
if (existing) {
existing.push(name);
} else {
byDir.set(dir, [name]);
}
}
const lines: string[] = [];
for (const [dir, names] of byDir) {
if (dir && names.length >= GROUP_THRESHOLD) {
lines.push(` * \`${dir}\``);
for (const name of names) {
lines.push(` * \`${name}\``);
}
} else {
for (const name of names) {
lines.push(` * \`${dir}${name}\``);
}
}
}
return lines.join('\n');
}
export function getPackageFilesSummary(
packageFiles: Record<string, PackageFile[]> | null,
): string {
if (!packageFiles || !Object.entries(packageFiles).length) {
return '';
}
const sections: string[] = [];
for (const [manager, managerFiles] of Object.entries(packageFiles)) {
sections.push(`#### ${manager}\n\n${formatManagerFiles(managerFiles)}`);
}
return sections.join('\n\n');
}
export function getPackageFilesDesc(
packageFiles: Record<string, PackageFile[]> | null,
): string {
if (!packageFiles || !Object.entries(packageFiles).length) {
return '';
}
let files: string[] = [];
for (const [manager, managerFiles] of Object.entries(packageFiles)) {
files = files.concat(
managerFiles.map((file) => ` * \`${file.packageFile}\` (${manager})`),
);
}
return `### Detected Package Files\n\n${files.join('\n')}`;
}