From 26fde4761ff6b968ab243dc9fe76ceb5845448c3 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Sat, 18 Feb 2023 22:26:51 -0500 Subject: [PATCH 1/4] fix(typescript-estree): check for relative/root paths in printing file path errors --- .../create-program/createProjectProgram.ts | 17 +- .../src/create-program/describeFilePath.ts | 31 ++++ .../describeFilePath.test.ts.snap | 169 ++++++++++++++++++ .../tests/lib/describeFilePath.test.ts | 41 +++++ 4 files changed, 246 insertions(+), 12 deletions(-) create mode 100644 packages/typescript-estree/src/create-program/describeFilePath.ts create mode 100644 packages/typescript-estree/tests/lib/__snapshots__/describeFilePath.test.ts.snap create mode 100644 packages/typescript-estree/tests/lib/describeFilePath.test.ts diff --git a/packages/typescript-estree/src/create-program/createProjectProgram.ts b/packages/typescript-estree/src/create-program/createProjectProgram.ts index 77a3bec2141d..329765245ea8 100644 --- a/packages/typescript-estree/src/create-program/createProjectProgram.ts +++ b/packages/typescript-estree/src/create-program/createProjectProgram.ts @@ -4,6 +4,7 @@ import * as ts from 'typescript'; import { firstDefined } from '../node-utils'; import type { ParseSettings } from '../parseSettings'; +import { describeFilePath } from './describeFilePath'; import { getWatchProgramsForProjects } from './getWatchProgramsForProjects'; import type { ASTAndProgram } from './shared'; import { getAstFromProgram } from './shared'; @@ -40,19 +41,11 @@ function createProjectProgram( return astAndProgram; } - const describeFilePath = (filePath: string): string => { - const relative = path.relative( - parseSettings.tsconfigRootDir || process.cwd(), - filePath, - ); - if (parseSettings.tsconfigRootDir) { - return `/${relative}`; - } - return `/${relative}`; - }; + const describeProjectFilePath = (projectFile: string): string => + describeFilePath(projectFile, parseSettings.tsconfigRootDir); - const describedFilePath = describeFilePath(parseSettings.filePath); - const relativeProjects = parseSettings.projects.map(describeFilePath); + const describedFilePath = describeProjectFilePath(parseSettings.filePath); + const relativeProjects = parseSettings.projects.map(describeProjectFilePath); const describedPrograms = relativeProjects.length === 1 ? relativeProjects[0] diff --git a/packages/typescript-estree/src/create-program/describeFilePath.ts b/packages/typescript-estree/src/create-program/describeFilePath.ts new file mode 100644 index 000000000000..83e1338d91fb --- /dev/null +++ b/packages/typescript-estree/src/create-program/describeFilePath.ts @@ -0,0 +1,31 @@ +import path from 'path'; + +export function describeFilePath( + filePath: string, + tsconfigRootDir: string, +): string { + // If the TSConfig root dir is a parent of the filePath, use + // `` as a prefix for the path. + const relative = path.relative(tsconfigRootDir, filePath); + if (relative && !relative.startsWith('..') && !path.isAbsolute(relative)) { + return `/${relative}`; + } + + // Root-like Mac/Linux (~/*, ~*) or Windows (C:/*, /) paths that aren't + // relative to the TSConfig root dir should be fully described. + // This avoids strings like /../../../../repo/file.ts. + // https://github.com/typescript-eslint/typescript-eslint/issues/6289 + if (/^[(\w+:)\\/~]/.test(filePath)) { + return filePath; + } + + // Similarly, if the relative path would contain a lot of ../.., then + // ignore it and print the file path directly. + if (/\.\.[/\\]\.\./.test(relative)) { + return filePath; + } + + // Lastly, since we've eliminated all special cases, we know the cleanest + // path to print is probably the prefixed relative one. + return `/${relative}`; +} diff --git a/packages/typescript-estree/tests/lib/__snapshots__/describeFilePath.test.ts.snap b/packages/typescript-estree/tests/lib/__snapshots__/describeFilePath.test.ts.snap new file mode 100644 index 000000000000..f830ace694ea --- /dev/null +++ b/packages/typescript-estree/tests/lib/__snapshots__/describeFilePath.test.ts.snap @@ -0,0 +1,169 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`describeFilePath tsconfigRootDir ./repos/repo filePath ./elsewhere/repo/file.ts 1`] = `"./elsewhere/repo/file.ts"`; + +exports[`describeFilePath tsconfigRootDir ./repos/repo filePath ./elsewhere/repo/nested/file.ts 1`] = `"./elsewhere/repo/nested/file.ts"`; + +exports[`describeFilePath tsconfigRootDir ./repos/repo filePath ./repos/file.ts 1`] = `"/../file.ts"`; + +exports[`describeFilePath tsconfigRootDir ./repos/repo filePath ./repos/other/file.ts 1`] = `"/../other/file.ts"`; + +exports[`describeFilePath tsconfigRootDir ./repos/repo filePath ./repos/repo/file.ts 1`] = `"/file.ts"`; + +exports[`describeFilePath tsconfigRootDir ./repos/repo filePath ./repos/repo/nested/file.ts 1`] = `"/nested/file.ts"`; + +exports[`describeFilePath tsconfigRootDir ./repos/repo filePath /elsewhere/repo/file.ts 1`] = `"/elsewhere/repo/file.ts"`; + +exports[`describeFilePath tsconfigRootDir ./repos/repo filePath /elsewhere/repo/nested/file.ts 1`] = `"/elsewhere/repo/nested/file.ts"`; + +exports[`describeFilePath tsconfigRootDir ./repos/repo filePath /file.ts 1`] = `"/file.ts"`; + +exports[`describeFilePath tsconfigRootDir ./repos/repo filePath /nested/file.ts 1`] = `"/nested/file.ts"`; + +exports[`describeFilePath tsconfigRootDir ./repos/repo filePath /repos/repo/file.ts 1`] = `"/repos/repo/file.ts"`; + +exports[`describeFilePath tsconfigRootDir ./repos/repo filePath /repos/repo/nested/file.ts 1`] = `"/repos/repo/nested/file.ts"`; + +exports[`describeFilePath tsconfigRootDir ./repos/repo filePath ~/file.ts 1`] = `"~/file.ts"`; + +exports[`describeFilePath tsconfigRootDir ./repos/repo filePath ~/nested/file.ts 1`] = `"~/nested/file.ts"`; + +exports[`describeFilePath tsconfigRootDir ./repos/repo filePath ~/nested/file.ts 2`] = `"~/nested/file.ts"`; + +exports[`describeFilePath tsconfigRootDir ./repos/repo filePath ~/other/nested/path/to/file.ts 1`] = `"~/other/nested/path/to/file.ts"`; + +exports[`describeFilePath tsconfigRootDir ./repos/repo filePath ~/other/repo/file.ts 1`] = `"~/other/repo/file.ts"`; + +exports[`describeFilePath tsconfigRootDir ./repos/repo filePath ~/repos/file.ts 1`] = `"~/repos/file.ts"`; + +exports[`describeFilePath tsconfigRootDir ./repos/repo filePath ~/repos/other/file.ts 1`] = `"~/repos/other/file.ts"`; + +exports[`describeFilePath tsconfigRootDir ./repos/repo filePath ~/repos/other/nested/file.ts 1`] = `"~/repos/other/nested/file.ts"`; + +exports[`describeFilePath tsconfigRootDir ./repos/repo filePath ~/repos/repo/file.ts 1`] = `"~/repos/repo/file.ts"`; + +exports[`describeFilePath tsconfigRootDir ./repos/repo filePath ~/repos/repo/nestedfile.ts 1`] = `"~/repos/repo/nestedfile.ts"`; + +exports[`describeFilePath tsconfigRootDir ./repos/repo filePath A:/file.ts 1`] = `"A:/file.ts"`; + +exports[`describeFilePath tsconfigRootDir ./repos/repo filePath A:/nested/file.ts 1`] = `"A:/nested/file.ts"`; + +exports[`describeFilePath tsconfigRootDir ./repos/repo filePath ABC:/file.ts 1`] = `"ABC:/file.ts"`; + +exports[`describeFilePath tsconfigRootDir ./repos/repo filePath C:/file.ts 1`] = `"C:/file.ts"`; + +exports[`describeFilePath tsconfigRootDir ./repos/repo filePath file.ts 1`] = `"file.ts"`; + +exports[`describeFilePath tsconfigRootDir ./repos/repo filePath nested/file.ts 1`] = `"nested/file.ts"`; + +exports[`describeFilePath tsconfigRootDir /repos/repo filePath ./elsewhere/repo/file.ts 1`] = `"./elsewhere/repo/file.ts"`; + +exports[`describeFilePath tsconfigRootDir /repos/repo filePath ./elsewhere/repo/nested/file.ts 1`] = `"./elsewhere/repo/nested/file.ts"`; + +exports[`describeFilePath tsconfigRootDir /repos/repo filePath ./repos/file.ts 1`] = `"./repos/file.ts"`; + +exports[`describeFilePath tsconfigRootDir /repos/repo filePath ./repos/other/file.ts 1`] = `"./repos/other/file.ts"`; + +exports[`describeFilePath tsconfigRootDir /repos/repo filePath ./repos/repo/file.ts 1`] = `"./repos/repo/file.ts"`; + +exports[`describeFilePath tsconfigRootDir /repos/repo filePath ./repos/repo/nested/file.ts 1`] = `"./repos/repo/nested/file.ts"`; + +exports[`describeFilePath tsconfigRootDir /repos/repo filePath /elsewhere/repo/file.ts 1`] = `"/elsewhere/repo/file.ts"`; + +exports[`describeFilePath tsconfigRootDir /repos/repo filePath /elsewhere/repo/nested/file.ts 1`] = `"/elsewhere/repo/nested/file.ts"`; + +exports[`describeFilePath tsconfigRootDir /repos/repo filePath /file.ts 1`] = `"/file.ts"`; + +exports[`describeFilePath tsconfigRootDir /repos/repo filePath /nested/file.ts 1`] = `"/nested/file.ts"`; + +exports[`describeFilePath tsconfigRootDir /repos/repo filePath /repos/repo/file.ts 1`] = `"/file.ts"`; + +exports[`describeFilePath tsconfigRootDir /repos/repo filePath /repos/repo/nested/file.ts 1`] = `"/nested/file.ts"`; + +exports[`describeFilePath tsconfigRootDir /repos/repo filePath ~/file.ts 1`] = `"~/file.ts"`; + +exports[`describeFilePath tsconfigRootDir /repos/repo filePath ~/nested/file.ts 1`] = `"~/nested/file.ts"`; + +exports[`describeFilePath tsconfigRootDir /repos/repo filePath ~/nested/file.ts 2`] = `"~/nested/file.ts"`; + +exports[`describeFilePath tsconfigRootDir /repos/repo filePath ~/other/nested/path/to/file.ts 1`] = `"~/other/nested/path/to/file.ts"`; + +exports[`describeFilePath tsconfigRootDir /repos/repo filePath ~/other/repo/file.ts 1`] = `"~/other/repo/file.ts"`; + +exports[`describeFilePath tsconfigRootDir /repos/repo filePath ~/repos/file.ts 1`] = `"~/repos/file.ts"`; + +exports[`describeFilePath tsconfigRootDir /repos/repo filePath ~/repos/other/file.ts 1`] = `"~/repos/other/file.ts"`; + +exports[`describeFilePath tsconfigRootDir /repos/repo filePath ~/repos/other/nested/file.ts 1`] = `"~/repos/other/nested/file.ts"`; + +exports[`describeFilePath tsconfigRootDir /repos/repo filePath ~/repos/repo/file.ts 1`] = `"~/repos/repo/file.ts"`; + +exports[`describeFilePath tsconfigRootDir /repos/repo filePath ~/repos/repo/nestedfile.ts 1`] = `"~/repos/repo/nestedfile.ts"`; + +exports[`describeFilePath tsconfigRootDir /repos/repo filePath A:/file.ts 1`] = `"A:/file.ts"`; + +exports[`describeFilePath tsconfigRootDir /repos/repo filePath A:/nested/file.ts 1`] = `"A:/nested/file.ts"`; + +exports[`describeFilePath tsconfigRootDir /repos/repo filePath ABC:/file.ts 1`] = `"ABC:/file.ts"`; + +exports[`describeFilePath tsconfigRootDir /repos/repo filePath C:/file.ts 1`] = `"C:/file.ts"`; + +exports[`describeFilePath tsconfigRootDir /repos/repo filePath file.ts 1`] = `"file.ts"`; + +exports[`describeFilePath tsconfigRootDir /repos/repo filePath nested/file.ts 1`] = `"nested/file.ts"`; + +exports[`describeFilePath tsconfigRootDir ~/repos/repo filePath ./elsewhere/repo/file.ts 1`] = `"./elsewhere/repo/file.ts"`; + +exports[`describeFilePath tsconfigRootDir ~/repos/repo filePath ./elsewhere/repo/nested/file.ts 1`] = `"./elsewhere/repo/nested/file.ts"`; + +exports[`describeFilePath tsconfigRootDir ~/repos/repo filePath ./repos/file.ts 1`] = `"./repos/file.ts"`; + +exports[`describeFilePath tsconfigRootDir ~/repos/repo filePath ./repos/other/file.ts 1`] = `"./repos/other/file.ts"`; + +exports[`describeFilePath tsconfigRootDir ~/repos/repo filePath ./repos/repo/file.ts 1`] = `"./repos/repo/file.ts"`; + +exports[`describeFilePath tsconfigRootDir ~/repos/repo filePath ./repos/repo/nested/file.ts 1`] = `"./repos/repo/nested/file.ts"`; + +exports[`describeFilePath tsconfigRootDir ~/repos/repo filePath /elsewhere/repo/file.ts 1`] = `"/elsewhere/repo/file.ts"`; + +exports[`describeFilePath tsconfigRootDir ~/repos/repo filePath /elsewhere/repo/nested/file.ts 1`] = `"/elsewhere/repo/nested/file.ts"`; + +exports[`describeFilePath tsconfigRootDir ~/repos/repo filePath /file.ts 1`] = `"/file.ts"`; + +exports[`describeFilePath tsconfigRootDir ~/repos/repo filePath /nested/file.ts 1`] = `"/nested/file.ts"`; + +exports[`describeFilePath tsconfigRootDir ~/repos/repo filePath /repos/repo/file.ts 1`] = `"/repos/repo/file.ts"`; + +exports[`describeFilePath tsconfigRootDir ~/repos/repo filePath /repos/repo/nested/file.ts 1`] = `"/repos/repo/nested/file.ts"`; + +exports[`describeFilePath tsconfigRootDir ~/repos/repo filePath ~/file.ts 1`] = `"~/file.ts"`; + +exports[`describeFilePath tsconfigRootDir ~/repos/repo filePath ~/nested/file.ts 1`] = `"~/nested/file.ts"`; + +exports[`describeFilePath tsconfigRootDir ~/repos/repo filePath ~/nested/file.ts 2`] = `"~/nested/file.ts"`; + +exports[`describeFilePath tsconfigRootDir ~/repos/repo filePath ~/other/nested/path/to/file.ts 1`] = `"~/other/nested/path/to/file.ts"`; + +exports[`describeFilePath tsconfigRootDir ~/repos/repo filePath ~/other/repo/file.ts 1`] = `"~/other/repo/file.ts"`; + +exports[`describeFilePath tsconfigRootDir ~/repos/repo filePath ~/repos/file.ts 1`] = `"~/repos/file.ts"`; + +exports[`describeFilePath tsconfigRootDir ~/repos/repo filePath ~/repos/other/file.ts 1`] = `"~/repos/other/file.ts"`; + +exports[`describeFilePath tsconfigRootDir ~/repos/repo filePath ~/repos/other/nested/file.ts 1`] = `"~/repos/other/nested/file.ts"`; + +exports[`describeFilePath tsconfigRootDir ~/repos/repo filePath ~/repos/repo/file.ts 1`] = `"/file.ts"`; + +exports[`describeFilePath tsconfigRootDir ~/repos/repo filePath ~/repos/repo/nestedfile.ts 1`] = `"/nestedfile.ts"`; + +exports[`describeFilePath tsconfigRootDir ~/repos/repo filePath A:/file.ts 1`] = `"A:/file.ts"`; + +exports[`describeFilePath tsconfigRootDir ~/repos/repo filePath A:/nested/file.ts 1`] = `"A:/nested/file.ts"`; + +exports[`describeFilePath tsconfigRootDir ~/repos/repo filePath ABC:/file.ts 1`] = `"ABC:/file.ts"`; + +exports[`describeFilePath tsconfigRootDir ~/repos/repo filePath C:/file.ts 1`] = `"C:/file.ts"`; + +exports[`describeFilePath tsconfigRootDir ~/repos/repo filePath file.ts 1`] = `"file.ts"`; + +exports[`describeFilePath tsconfigRootDir ~/repos/repo filePath nested/file.ts 1`] = `"nested/file.ts"`; diff --git a/packages/typescript-estree/tests/lib/describeFilePath.test.ts b/packages/typescript-estree/tests/lib/describeFilePath.test.ts new file mode 100644 index 000000000000..6f2f2b7b0a21 --- /dev/null +++ b/packages/typescript-estree/tests/lib/describeFilePath.test.ts @@ -0,0 +1,41 @@ +import { describeFilePath } from '../../src/create-program/describeFilePath'; + +describe('describeFilePath', () => { + describe.each(['./repos/repo', '/repos/repo', '~/repos/repo'])( + 'tsconfigRootDir %s', + tsconfigRootDir => { + test.each([ + './elsewhere/repo/file.ts', + './elsewhere/repo/nested/file.ts', + './repos/file.ts', + './repos/other/file.ts', + './repos/repo/file.ts', + './repos/repo/nested/file.ts', + '/elsewhere/repo/file.ts', + '/elsewhere/repo/nested/file.ts', + '/file.ts', + '/nested/file.ts', + '/repos/repo/file.ts', + '/repos/repo/nested/file.ts', + '~/file.ts', + '~/nested/file.ts', + '~/nested/file.ts', + '~/other/nested/path/to/file.ts', + '~/other/repo/file.ts', + '~/repos/file.ts', + '~/repos/other/file.ts', + '~/repos/other/nested/file.ts', + '~/repos/repo/file.ts', + '~/repos/repo/nestedfile.ts', + 'A:/file.ts', + 'A:/nested/file.ts', + 'ABC:/file.ts', + 'C:/file.ts', + 'file.ts', + 'nested/file.ts', + ])('filePath %s', filePath => { + expect(describeFilePath(filePath, tsconfigRootDir)).toMatchSnapshot(); + }); + }, + ); +}); From f002e90bfb31ec931ad7547ab57e68fe4f72e02a Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Sat, 18 Feb 2023 22:34:05 -0500 Subject: [PATCH 2/4] Missing slash in a test case --- .../tests/lib/__snapshots__/describeFilePath.test.ts.snap | 6 +++--- .../typescript-estree/tests/lib/describeFilePath.test.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/typescript-estree/tests/lib/__snapshots__/describeFilePath.test.ts.snap b/packages/typescript-estree/tests/lib/__snapshots__/describeFilePath.test.ts.snap index f830ace694ea..702bde4b5e74 100644 --- a/packages/typescript-estree/tests/lib/__snapshots__/describeFilePath.test.ts.snap +++ b/packages/typescript-estree/tests/lib/__snapshots__/describeFilePath.test.ts.snap @@ -42,7 +42,7 @@ exports[`describeFilePath tsconfigRootDir ./repos/repo filePath ~/repos/other/ne exports[`describeFilePath tsconfigRootDir ./repos/repo filePath ~/repos/repo/file.ts 1`] = `"~/repos/repo/file.ts"`; -exports[`describeFilePath tsconfigRootDir ./repos/repo filePath ~/repos/repo/nestedfile.ts 1`] = `"~/repos/repo/nestedfile.ts"`; +exports[`describeFilePath tsconfigRootDir ./repos/repo filePath ~/repos/repo/nested/file.ts 1`] = `"~/repos/repo/nested/file.ts"`; exports[`describeFilePath tsconfigRootDir ./repos/repo filePath A:/file.ts 1`] = `"A:/file.ts"`; @@ -98,7 +98,7 @@ exports[`describeFilePath tsconfigRootDir /repos/repo filePath ~/repos/other/nes exports[`describeFilePath tsconfigRootDir /repos/repo filePath ~/repos/repo/file.ts 1`] = `"~/repos/repo/file.ts"`; -exports[`describeFilePath tsconfigRootDir /repos/repo filePath ~/repos/repo/nestedfile.ts 1`] = `"~/repos/repo/nestedfile.ts"`; +exports[`describeFilePath tsconfigRootDir /repos/repo filePath ~/repos/repo/nested/file.ts 1`] = `"~/repos/repo/nested/file.ts"`; exports[`describeFilePath tsconfigRootDir /repos/repo filePath A:/file.ts 1`] = `"A:/file.ts"`; @@ -154,7 +154,7 @@ exports[`describeFilePath tsconfigRootDir ~/repos/repo filePath ~/repos/other/ne exports[`describeFilePath tsconfigRootDir ~/repos/repo filePath ~/repos/repo/file.ts 1`] = `"/file.ts"`; -exports[`describeFilePath tsconfigRootDir ~/repos/repo filePath ~/repos/repo/nestedfile.ts 1`] = `"/nestedfile.ts"`; +exports[`describeFilePath tsconfigRootDir ~/repos/repo filePath ~/repos/repo/nested/file.ts 1`] = `"/nested/file.ts"`; exports[`describeFilePath tsconfigRootDir ~/repos/repo filePath A:/file.ts 1`] = `"A:/file.ts"`; diff --git a/packages/typescript-estree/tests/lib/describeFilePath.test.ts b/packages/typescript-estree/tests/lib/describeFilePath.test.ts index 6f2f2b7b0a21..0a23ddf8af30 100644 --- a/packages/typescript-estree/tests/lib/describeFilePath.test.ts +++ b/packages/typescript-estree/tests/lib/describeFilePath.test.ts @@ -26,7 +26,7 @@ describe('describeFilePath', () => { '~/repos/other/file.ts', '~/repos/other/nested/file.ts', '~/repos/repo/file.ts', - '~/repos/repo/nestedfile.ts', + '~/repos/repo/nested/file.ts', 'A:/file.ts', 'A:/nested/file.ts', 'ABC:/file.ts', From bbb883ebd06917774bb92e6764d097cad9d49c3c Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Tue, 21 Feb 2023 14:37:30 -0500 Subject: [PATCH 3/4] Update packages/typescript-estree/src/create-program/createProjectProgram.ts Co-authored-by: Armano --- .../src/create-program/createProjectProgram.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/typescript-estree/src/create-program/createProjectProgram.ts b/packages/typescript-estree/src/create-program/createProjectProgram.ts index 329765245ea8..adab51a02c03 100644 --- a/packages/typescript-estree/src/create-program/createProjectProgram.ts +++ b/packages/typescript-estree/src/create-program/createProjectProgram.ts @@ -44,7 +44,7 @@ function createProjectProgram( const describeProjectFilePath = (projectFile: string): string => describeFilePath(projectFile, parseSettings.tsconfigRootDir); - const describedFilePath = describeProjectFilePath(parseSettings.filePath); + const describedFilePath = describeFilePath(parseSettings.filePath, parseSettings.tsconfigRootDir); const relativeProjects = parseSettings.projects.map(describeProjectFilePath); const describedPrograms = relativeProjects.length === 1 From cc7164910d4b10d12aa5d06898c22eaf59168acd Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Tue, 21 Feb 2023 14:45:29 -0500 Subject: [PATCH 4/4] Post-suggestion format --- .../src/create-program/createProjectProgram.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/typescript-estree/src/create-program/createProjectProgram.ts b/packages/typescript-estree/src/create-program/createProjectProgram.ts index adab51a02c03..f60ae9cbfd5c 100644 --- a/packages/typescript-estree/src/create-program/createProjectProgram.ts +++ b/packages/typescript-estree/src/create-program/createProjectProgram.ts @@ -44,7 +44,10 @@ function createProjectProgram( const describeProjectFilePath = (projectFile: string): string => describeFilePath(projectFile, parseSettings.tsconfigRootDir); - const describedFilePath = describeFilePath(parseSettings.filePath, parseSettings.tsconfigRootDir); + const describedFilePath = describeFilePath( + parseSettings.filePath, + parseSettings.tsconfigRootDir, + ); const relativeProjects = parseSettings.projects.map(describeProjectFilePath); const describedPrograms = relativeProjects.length === 1