@backstage/cli
Version:
CLI for developing Backstage plugins and apps
93 lines (87 loc) • 3.32 kB
JavaScript
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
;