From 714ba675f78098c20271906a12f59da27c45cbf5 Mon Sep 17 00:00:00 2001 From: Clint Andrew Hall Date: Tue, 17 Dec 2024 05:07:34 -0600 Subject: [PATCH] [devx] Create script to stage files by CODEOWNER (#203940) --- scripts/stage_by_owner.js | 11 +++++ src/dev/stage_by_owner.ts | 96 +++++++++++++++++++++++++++++++++++++++ src/dev/tsconfig.json | 1 + 3 files changed, 108 insertions(+) create mode 100644 scripts/stage_by_owner.js create mode 100644 src/dev/stage_by_owner.ts diff --git a/scripts/stage_by_owner.js b/scripts/stage_by_owner.js new file mode 100644 index 0000000000000..0ac33b3901a04 --- /dev/null +++ b/scripts/stage_by_owner.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('../src/dev/stage_by_owner'); diff --git a/src/dev/stage_by_owner.ts b/src/dev/stage_by_owner.ts new file mode 100644 index 0000000000000..7987874da75fe --- /dev/null +++ b/src/dev/stage_by_owner.ts @@ -0,0 +1,96 @@ +/* + * 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 simpleGit from 'simple-git'; + +import { run } from '@kbn/dev-cli-runner'; +import { getOwningTeamsForPath, getCodeOwnersEntries, CodeOwnersEntry } from '@kbn/code-owners'; +import { asyncForEach } from '@kbn/std'; +import { inspect } from 'util'; + +const git = simpleGit(); + +interface File { + path: string; + staged: boolean; +} + +// Function to get the list of changed files +const getChangedFiles = async (): Promise => { + const { staged, files } = await git.status(); + return files.map((file) => ({ path: file.path, staged: staged.includes(file.path) })); +}; + +run( + async ({ flags, log }) => { + const { + _: [owner], + } = flags; + + const changedFiles = await getChangedFiles(); + const owners: { staged: Record; unstaged: Record } = { + staged: {}, + unstaged: {}, + }; + + let codeOwnersEntries: CodeOwnersEntry[] = []; + + try { + codeOwnersEntries = getCodeOwnersEntries(); + } catch (e) { + log.error('CODEOWNERS cannot be read.'); + process.exit(1); + } + + const getOwners = (file: string) => { + const teams = getOwningTeamsForPath(file, codeOwnersEntries); + + if (teams.length === 0) { + log.warning(`No owner found for ${file}`); + return []; + } + + return teams; + }; + + for (const file of changedFiles) { + const fileOwners = getOwners(file.path); + + if (fileOwners) { + await asyncForEach(fileOwners, async (fileOwner) => { + const loc = file.staged ? 'staged' : 'unstaged'; + + owners[loc][fileOwner] = [ + ...(owners[loc][fileOwner] || []), + file.path + (fileOwners.length > 1 ? ` (+${fileOwners.length - 1})` : ''), + ]; + + if (owner && fileOwner === owner) { + await git.add(file.path); + log.info(`Staged ${file.path}`); + } + }); + } + } + + if (!owner) { + log.info(inspect(owners, { colors: true, depth: null })); + } + + log.info('Done.'); + }, + { + usage: 'node src/dev/stage_by_owner.ts [owner]', + description: ` + This script stages files based on the CODEOWNERS file. + If an owner is provided, it stages the files owned by that owner. + Otherwise, it outputs changed files, grouped by owner. + `, + } +); diff --git a/src/dev/tsconfig.json b/src/dev/tsconfig.json index 87473c1e79e82..0e2e8e94c629b 100644 --- a/src/dev/tsconfig.json +++ b/src/dev/tsconfig.json @@ -44,5 +44,6 @@ "@kbn/core-test-helpers-kbn-server", "@kbn/dev-proc-runner", "@kbn/core-i18n-server-internal", + "@kbn/code-owners", ] }