UNPKG

@backstage/cli

Version:

CLI for developing Backstage plugins and apps

93 lines (87 loc) 3.32 kB
'use strict'; var fs = require('fs-extra'); var path = require('path'); var paths = require('../paths.cjs.js'); function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; } var fs__default = /*#__PURE__*/_interopDefaultCompat(fs); var path__default = /*#__PURE__*/_interopDefaultCompat(path); const TEAM_ID_RE = /^@[-\w]+\/[-\w]+$/; const USER_ID_RE = /^@[-\w]+$/; const EMAIL_RE = /^[^@]+@[-.\w]+\.[-\w]+$/i; const DEFAULT_OWNER = "@backstage/maintainers"; async function getCodeownersFilePath(rootDir) { const possiblePaths = [ path__default.default.join(rootDir, ".github", "CODEOWNERS"), path__default.default.join(rootDir, ".gitlab", "CODEOWNERS"), path__default.default.join(rootDir, "docs", "CODEOWNERS"), path__default.default.join(rootDir, "CODEOWNERS") ]; for (const p of possiblePaths) { if (await fs__default.default.pathExists(p)) { return p; } } return void 0; } function isValidSingleOwnerId(id) { if (!id || typeof id !== "string") { return false; } return TEAM_ID_RE.test(id) || USER_ID_RE.test(id) || EMAIL_RE.test(id); } function parseOwnerIds(spaceSeparatedOwnerIds) { if (!spaceSeparatedOwnerIds || typeof spaceSeparatedOwnerIds !== "string") { return void 0; } const ids = spaceSeparatedOwnerIds.split(" ").filter(Boolean); if (!ids.every(isValidSingleOwnerId)) { return void 0; } return ids; } async function addCodeownersEntry(ownedPath, ownerStr, codeownersFilePath) { const ownerIds = parseOwnerIds(ownerStr); if (!ownerIds || ownerIds.length === 0) { return false; } let filePath = codeownersFilePath; if (!filePath) { filePath = await getCodeownersFilePath(paths.paths.targetRoot); if (!filePath) { return false; } } const allLines = (await fs__default.default.readFile(filePath, "utf8")).split("\n"); const commentLines = []; for (const line of allLines) { if (line[0] !== "#") { break; } commentLines.push(line); } const oldDeclarationEntries = allLines.filter((line) => line[0] !== "#").map((line) => line.split(/\s+/).filter(Boolean)).filter((tokens) => tokens.length >= 2).map((tokens) => ({ ownedPath: tokens[0], ownerIds: tokens.slice(1) })); const newDeclarationEntries = oldDeclarationEntries.filter((entry) => entry.ownedPath !== "*").concat([{ ownedPath, ownerIds }]).sort((l1, l2) => l1.ownedPath.localeCompare(l2.ownedPath)); newDeclarationEntries.unshift({ ownedPath: "*", ownerIds: [DEFAULT_OWNER] }); const longestOwnedPath = newDeclarationEntries.reduce( (length, entry) => Math.max(length, entry.ownedPath.length), 0 ); const newDeclarationLines = newDeclarationEntries.map((entry) => { const entryPath = entry.ownedPath + " ".repeat(longestOwnedPath - entry.ownedPath.length); return [entryPath, ...entry.ownerIds].join(" "); }); const newLines = [...commentLines, "", ...newDeclarationLines, ""]; await fs__default.default.writeFile(filePath, newLines.join("\n"), "utf8"); return true; } exports.addCodeownersEntry = addCodeownersEntry; exports.getCodeownersFilePath = getCodeownersFilePath; exports.isValidSingleOwnerId = isValidSingleOwnerId; exports.parseOwnerIds = parseOwnerIds; //# sourceMappingURL=codeowners.cjs.js.map