diff --git a/.changeset/new-pandas-perform.md b/.changeset/new-pandas-perform.md new file mode 100644 index 0000000000..797f34d6df --- /dev/null +++ b/.changeset/new-pandas-perform.md @@ -0,0 +1,5 @@ +--- +'@backstage/repo-tools': minor +--- + +Fix invalid path and malformed flags bugs in api-reports.ts diff --git a/packages/repo-tools/src/commands/api-reports/api-reports.test.ts b/packages/repo-tools/src/commands/api-reports/api-reports.test.ts index 955720c52e..94ae42d715 100644 --- a/packages/repo-tools/src/commands/api-reports/api-reports.test.ts +++ b/packages/repo-tools/src/commands/api-reports/api-reports.test.ts @@ -323,6 +323,24 @@ describe('buildApiReports', () => { expect(buildDocs).not.toHaveBeenCalled(); }); + it('should throw an error if a path does not exist', async () => { + const paths = ['packages/package-a', 'packages/package-c']; + const opts = {}; + + await expect(buildApiReports(paths, opts)).rejects.toThrow( + 'Invalid paths provided: packages/package-c', + ); + }); + it('should throw an error if an option is malformed', async () => { + const paths = ['ae-undocumented']; + const opts = { + omitMessages: 'ae-wrong-input-file-type,', + }; + + await expect(buildApiReports(paths, opts)).rejects.toThrow( + 'Invalid paths provided: ae-undocumented', + ); + }); }); describe('allowWarnings', () => { it('should accept single path value', async () => { diff --git a/packages/repo-tools/src/commands/api-reports/api-reports.ts b/packages/repo-tools/src/commands/api-reports/api-reports.ts index 637cd86671..4e568102d9 100644 --- a/packages/repo-tools/src/commands/api-reports/api-reports.ts +++ b/packages/repo-tools/src/commands/api-reports/api-reports.ts @@ -48,6 +48,7 @@ export const buildApiReports = async (paths: string[] = [], opts: Options) => { const omitMessages = parseArrayOption(opts.omitMessages); const isAllPackages = !paths?.length; + const selectedPackageDirs = await resolvePackagePaths({ paths, include: opts.include, @@ -130,5 +131,10 @@ export const buildApiReports = async (paths: string[] = [], opts: Options) => { * // returns [] */ function parseArrayOption(value: string | undefined) { - return value ? value.split(',').map(s => s.trim()) : []; + return value + ? value + .split(',') + .map(s => s.trim()) + .filter(Boolean) + : []; } diff --git a/packages/repo-tools/src/lib/paths.ts b/packages/repo-tools/src/lib/paths.ts index 96fc92f035..0dcec32ff1 100644 --- a/packages/repo-tools/src/lib/paths.ts +++ b/packages/repo-tools/src/lib/paths.ts @@ -36,6 +36,23 @@ export async function resolvePackagePaths( const { paths: providedPaths, include, exclude } = options; let packages = await PackageGraph.listTargetPackages(); + if (providedPaths && providedPaths.length > 0) { + const invalidPaths: string[] = []; + for (const path of providedPaths) { + const matches = packages.some( + ({ dir }) => + new Minimatch(path).match(relativePath(paths.targetRoot, dir)) || + isChildPath(dir, path), + ); + if (!matches) { + invalidPaths.push(path); + } + } + if (invalidPaths.length > 0) { + throw new Error(`Invalid paths provided: ${invalidPaths.join(', ')}`); + } + } + if (providedPaths && providedPaths.length > 0) { packages = packages.filter(({ dir }) => providedPaths.some(