"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const find_up_1 = __importDefault(require("find-up")); const locate_path_1 = __importDefault(require("locate-path")); const path_1 = __importDefault(require("path")); const fs_1 = __importDefault(require("fs")); const util_1 = __importDefault(require("util")); const ignore_1 = __importDefault(require("ignore")); const cross_spawn_1 = __importDefault(require("cross-spawn")); let readFile = util_1.default.promisify(fs_1.default.readFile); /** * Parse a CODEOWNERS file into an array of entries (will be in reverse order * of the file). */ function parse(str) { let entries = []; let lines = str.split("\n"); for (let line of lines) { let [content, comment] = line.split("#"); let trimmed = content.trim(); if (trimmed === "") continue; let [pattern, ...owners] = trimmed.split(/\s+/); entries.push({ pattern, owners }); } return entries.reverse(); } exports.parse = parse; /** * Standard locations to search for the CODEOWNERS file in priority order * (Note: This comes from GitHub). */ exports.CODEOWNERS_PATHS = [ ".github/CODEOWNERS", "docs/CODEOWNERS", "CODEOWNERS", ]; /** * Find the path of the CODEOWNERS file from the current working directory. */ async function findOwnersPath(cwd) { let git = await find_up_1.default(".git/", { cwd, type: "directory" }); if (!git) return null; let root = path_1.default.dirname(git); let paths = exports.CODEOWNERS_PATHS.map(part => path_1.default.join(root, part)); let codeowners = await locate_path_1.default(paths, { cwd }); return codeowners || null; } exports.findOwnersPath = findOwnersPath; /** * Find, load, and parse the CODEOWNERS file (if it exists) from the current * working directory. */ async function loadOwners(cwd) { let file = await findOwnersPath(cwd); if (!file) return null; let contents = await readFile(file, "utf-8"); let entries = parse(contents); return entries; } exports.loadOwners = loadOwners; /** * Match a filename against a glob pattern (while respecting .gitignore rules) */ function matchPattern(filename, pattern) { return ignore_1.default() .add(pattern) .ignores(filename); } exports.matchPattern = matchPattern; /** * Match a filename against CODEOWNERS entries to determine which (if any) it * matches. */ function matchFile(filename, entries) { for (let entry of entries) { if (matchPattern(filename, entry.pattern)) { return entry; } } return null; } exports.matchFile = matchFile; /** * Given a set of files and CODEOWNERS entries, return the set of files which * are not matched to any CODEOWNERS entries. */ function filterUnmatchedFiles(files, entries) { return files.filter(file => !matchFile(file, entries)); } exports.filterUnmatchedFiles = filterUnmatchedFiles; /** * Spawn a child process and convert it into a promise. * @internal */ function spawn(cmd, args, opts, onData) { return new Promise((resolve, reject) => { let proc = cross_spawn_1.default(cmd, args, opts); proc.stdout.on("data", onData); proc.on("error", reject); proc.on("close", code => { if (code !== 0) { reject(new Error(`"${cmd} ${args.join(" ")}" exited with non-zero exit code: ${code}`)); // prettier-ignore } else { resolve(); } }); }); } /** * Use git to list all files in a repository. * @internal */ async function lsFiles(cwd, onFiles) { await spawn("git", ["ls-files", "--others", "--exclude-standard"], { cwd, stdio: ["ignore", "pipe", "inherit"] }, data => { let files = data .toString() .trim() .split("\n"); onFiles(files); }); } /** * Find all of the files in a git repository which are not matched by any code * owners using a set of CODEOWNERS entries. */ async function findUnmatchedFilesFromEntries(entries, cwd) { let unmatched = []; await lsFiles(cwd, files => { unmatched = unmatched.concat(filterUnmatchedFiles(files, entries)); }); return unmatched; } exports.findUnmatchedFilesFromEntries = findUnmatchedFilesFromEntries; /** * Find all of the files in a git repository which are not matched by any code * owners. */ async function findUnmatchedFiles(cwd) { let entries = await loadOwners(cwd); if (!entries) return null; let unmatched = await findUnmatchedFilesFromEntries(entries, cwd); return unmatched; } exports.findUnmatchedFiles = findUnmatchedFiles; //# sourceMappingURL=codeowners-utils.js.map