From 8a79173c4e01e0ab0d489098c5ad96bfa07df3ad Mon Sep 17 00:00:00 2001 From: Tre Date: Fri, 20 Sep 2024 14:16:08 +0100 Subject: [PATCH] [Test Owners] Add script to get owners for files (#193277) ## Summary Node script to report ownership of a given file in our repo. The script's source of truth is `.github/CODEOWNERS`, which is generated by `@kbn/generate` In order to reach the goal of have zero files without code ownership, this is one small step along the way. ### To Test #### Happy Path `node scripts/get_owners_for_file.js --file packages/kbn-ace/src/ace/modes/index.ts` ``` succ elastic/kibana-management ``` #### Unknown Path `node scripts/get_owners_for_file.js --file some-file.txt` ``` ERROR Ownership of file [some-file.txt] is UNKNOWN ``` #### Error Path `node scripts/get_owners_for_file.js` ``` ERROR Missing --flag argument node scripts/get_owners_for_file.js Report file ownership from GitHub CODEOWNERS file. Options: --file Required, path to the file to report owners for. --verbose, -v Log verbosely --debug Log debug messages (less than verbose) --quiet Only log errors --silent Don't log anything --help Show this message ``` ### Notes Along with this small pr, next will be to ensure owners are assigned to all ES and KBN Archives. See more info in the link below: Contributes to: https://github.com/elastic/kibana/issues/192979 --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- packages/kbn-code-owners/index.ts | 6 ++- .../kbn-code-owners/src/file_code_owner.ts | 40 +++++++++++++++++-- packages/kbn-code-owners/tsconfig.json | 3 +- scripts/get_owners_for_file.js | 11 +++++ 4 files changed, 54 insertions(+), 6 deletions(-) create mode 100644 scripts/get_owners_for_file.js diff --git a/packages/kbn-code-owners/index.ts b/packages/kbn-code-owners/index.ts index b4e83b6194c54..8966b92834089 100644 --- a/packages/kbn-code-owners/index.ts +++ b/packages/kbn-code-owners/index.ts @@ -8,4 +8,8 @@ */ export type { PathWithOwners } from './src/file_code_owner'; -export { getPathsWithOwnersReversed, getCodeOwnersForFile } from './src/file_code_owner'; +export { + getPathsWithOwnersReversed, + getCodeOwnersForFile, + runGetOwnersForFileCli, +} from './src/file_code_owner'; diff --git a/packages/kbn-code-owners/src/file_code_owner.ts b/packages/kbn-code-owners/src/file_code_owner.ts index 34f7970ca0d82..f413d7f975df0 100644 --- a/packages/kbn-code-owners/src/file_code_owner.ts +++ b/packages/kbn-code-owners/src/file_code_owner.ts @@ -8,9 +8,10 @@ */ import { REPO_ROOT } from '@kbn/repo-info'; -import { createFailError } from '@kbn/dev-cli-errors'; +import { createFailError, createFlagError } from '@kbn/dev-cli-errors'; import { join as joinPath } from 'path'; import { existsSync, readFileSync } from 'fs'; +import { run } from '@kbn/dev-cli-runner'; import type { Ignore } from 'ignore'; import ignore from 'ignore'; @@ -20,6 +21,10 @@ export interface PathWithOwners { teams: string; ignorePattern: Ignore; } +const existOrThrow = (targetFile: string) => { + if (existsSync(targetFile) === false) + throw createFailError(`Unable to determine code owners: file ${targetFile} Not Found`); +}; /** * Get the .github/CODEOWNERS entries, prepared for path matching. @@ -29,9 +34,7 @@ export interface PathWithOwners { */ export function getPathsWithOwnersReversed(): PathWithOwners[] { const codeownersPath = joinPath(REPO_ROOT, '.github', 'CODEOWNERS'); - if (existsSync(codeownersPath) === false) { - throw createFailError(`Unable to determine code owners: file ${codeownersPath} not found`); - } + existOrThrow(codeownersPath); const codeownersContent = readFileSync(codeownersPath, { encoding: 'utf8', flag: 'r' }); const codeownersLines = codeownersContent.split(/\r?\n/); const codeowners = codeownersLines @@ -66,3 +69,32 @@ export function getCodeOwnersForFile( return match?.teams; } + +/** + * Run the getCodeOwnersForFile() method above. + * Report back to the cli with either success and the owner(s), or a failure. + * + * This function depends on a --file param being passed on the cli, like this: + * $ node scripts/get_owners_for_file.js --file SOME-FILE + */ +export async function runGetOwnersForFileCli() { + run( + async ({ flags, log }) => { + const targetFile = flags.file as string; + if (!targetFile) throw createFlagError(`Missing --flag argument`); + existOrThrow(targetFile); // This call is duplicated in getPathsWithOwnersReversed(), so this is a short circuit + const result = getCodeOwnersForFile(targetFile); + if (result) log.success(result); + else log.error(`Ownership of file [${targetFile}] is UNKNOWN`); + }, + { + description: 'Report file ownership from GitHub CODEOWNERS file.', + flags: { + string: ['file'], + help: ` + --file Required, path to the file to report owners for. + `, + }, + } + ); +} diff --git a/packages/kbn-code-owners/tsconfig.json b/packages/kbn-code-owners/tsconfig.json index e97f927147d73..955d0568ca3ce 100644 --- a/packages/kbn-code-owners/tsconfig.json +++ b/packages/kbn-code-owners/tsconfig.json @@ -15,6 +15,7 @@ ], "kbn_references": [ "@kbn/repo-info", - "@kbn/dev-cli-errors" + "@kbn/dev-cli-errors", + "@kbn/dev-cli-runner" ] } diff --git a/scripts/get_owners_for_file.js b/scripts/get_owners_for_file.js new file mode 100644 index 0000000000000..f5a07b76ee04c --- /dev/null +++ b/scripts/get_owners_for_file.js @@ -0,0 +1,11 @@ +/* + * 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". + */ + +require('../src/setup_node_env'); +require('@kbn/code-owners').runGetOwnersForFileCli();