diff --git a/packages/kbn-ts-type-check-cli/run_type_check_cli.ts b/packages/kbn-ts-type-check-cli/run_type_check_cli.ts index 6a45ef8110e2e..ceaf25335b713 100644 --- a/packages/kbn-ts-type-check-cli/run_type_check_cli.ts +++ b/packages/kbn-ts-type-check-cli/run_type_check_cli.ts @@ -21,6 +21,7 @@ import { archiveTSBuildArtifacts } from './src/archive/archive_ts_build_artifact import { restoreTSBuildArtifacts } from './src/archive/restore_ts_build_artifacts'; import { LOCAL_CACHE_ROOT } from './src/archive/constants'; import { isCiEnvironment } from './src/archive/utils'; +import { normalizeProjectPath } from './src/normalize_project_path'; const rel = (from: string, to: string) => { const path = Path.relative(from, to); @@ -133,7 +134,7 @@ run( log.verbose('Skipping TypeScript cache restore because --with-archive was not provided.'); } - const projectFilter = flagsReader.path('project'); + const projectFilter = normalizeProjectPath(flagsReader.path('project'), log); const projects = TS_PROJECTS.filter( (p) => !p.isTypeCheckDisabled() && (!projectFilter || p.path === projectFilter) diff --git a/packages/kbn-ts-type-check-cli/src/normalize_project_path.test.ts b/packages/kbn-ts-type-check-cli/src/normalize_project_path.test.ts new file mode 100644 index 0000000000000..2c12d601a94e1 --- /dev/null +++ b/packages/kbn-ts-type-check-cli/src/normalize_project_path.test.ts @@ -0,0 +1,41 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the "Elastic License + * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +import Path from 'path'; +import { REPO_ROOT } from '@kbn/repo-info'; + +import { normalizeProjectPath } from './normalize_project_path'; + +describe('normalizeProjectPath', () => { + it('returns undefined when project path is not set', () => { + const warning = jest.fn(); + expect(normalizeProjectPath(undefined, { warning })).toBeUndefined(); + expect(warning).not.toHaveBeenCalled(); + }); + + it('returns the same project path when tsconfig.json is passed', () => { + const warning = jest.fn(); + const projectPath = '/repo/packages/foo/tsconfig.json'; + + expect(normalizeProjectPath(projectPath, { warning })).toBe(projectPath); + expect(warning).not.toHaveBeenCalled(); + }); + + it('normalizes tsconfig.type_check.json to tsconfig.json and logs a warning', () => { + const warning = jest.fn(); + const projectPath = Path.resolve(REPO_ROOT, 'packages/foo/tsconfig.type_check.json'); + const normalizedProjectPath = Path.resolve(REPO_ROOT, 'packages/foo/tsconfig.json'); + + expect(normalizeProjectPath(projectPath, { warning })).toBe(normalizedProjectPath); + expect(warning).toHaveBeenCalledTimes(1); + expect(warning).toHaveBeenCalledWith( + `Received --project=packages/foo/tsconfig.type_check.json. tsconfig.type_check.json is generated by the type-check script; using packages/foo/tsconfig.json instead.` + ); + }); +}); diff --git a/packages/kbn-ts-type-check-cli/src/normalize_project_path.ts b/packages/kbn-ts-type-check-cli/src/normalize_project_path.ts new file mode 100644 index 0000000000000..c7ceab0338f78 --- /dev/null +++ b/packages/kbn-ts-type-check-cli/src/normalize_project_path.ts @@ -0,0 +1,54 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the "Elastic License + * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +import Path from 'path'; +import { REPO_ROOT } from '@kbn/repo-info'; +import type { SomeDevLog } from '@kbn/some-dev-log'; + +const TYPE_CHECK_CONFIG_FILENAME = 'tsconfig.type_check.json'; +const PROJECT_CONFIG_FILENAME = 'tsconfig.json'; + +const formatPathForLog = (path: string) => { + if (!Path.isAbsolute(path)) { + return path; + } + + const relativeToRepoRoot = Path.relative(REPO_ROOT, path); + if (!relativeToRepoRoot.startsWith('..') && !Path.isAbsolute(relativeToRepoRoot)) { + return relativeToRepoRoot; + } + + return path; +}; + +/** + * Normalizes the `--project` value passed to `scripts/type_check`. + * + * The type-check CLI expects a source `tsconfig.json`. If a generated + * `tsconfig.type_check.json` path is passed instead, this rewrites it to the + * sibling `tsconfig.json` and logs a warning explaining the correction. + */ +export const normalizeProjectPath = ( + projectPath: string | undefined, + log: Pick +) => { + if (!projectPath || Path.basename(projectPath) !== TYPE_CHECK_CONFIG_FILENAME) { + return projectPath; + } + + const normalizedPath = Path.resolve(Path.dirname(projectPath), PROJECT_CONFIG_FILENAME); + const formattedProjectPath = formatPathForLog(projectPath); + const formattedNormalizedPath = formatPathForLog(normalizedPath); + + log.warning( + `Received --project=${formattedProjectPath}. ${TYPE_CHECK_CONFIG_FILENAME} is generated by the type-check script; using ${formattedNormalizedPath} instead.` + ); + + return normalizedPath; +};