UNPKG

radashi-helper

Version:
364 lines (325 loc) 13.1 kB
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _chunkQJPNUX4Pcjs = require('./chunk-QJPNUX4P.cjs'); var _chunkZTBV44GEcjs = require('./chunk-ZTBV44GE.cjs'); require('./chunk-BCKUBJLJ.cjs'); var _chunk7UCE7HEGcjs = require('./chunk-7UCE7HEG.cjs'); var _chunk3OOKBKZBcjs = require('./chunk-3OOKBKZB.cjs'); var _chunkWVUG42ZOcjs = require('./chunk-WVUG42ZO.cjs'); require('./chunk-27XA2ZBL.cjs'); var _chunkDNQVKCXJcjs = require('./chunk-DNQVKCXJ.cjs'); require('./chunk-IWXG7YVC.cjs'); var _chunk4WZBZWYDcjs = require('./chunk-4WZBZWYD.cjs'); var _chunkZP624W2Acjs = require('./chunk-ZP624W2A.cjs'); var _chunkST3J6QTNcjs = require('./chunk-ST3J6QTN.cjs'); var _chunk5R2KEZLQcjs = require('./chunk-5R2KEZLQ.cjs'); // ../../node_modules/.pnpm/glob-regex@0.3.2/node_modules/glob-regex/index.js var require_glob_regex = _chunk5R2KEZLQcjs.__commonJS.call(void 0, { "../../node_modules/.pnpm/glob-regex@0.3.2/node_modules/glob-regex/index.js"(exports, module) { "use strict"; var dotRE = /\./g; var dotPattern = "\\."; var restRE = /\*\*$/g; var restPattern = "(.+)"; var globRE = /(?:\*\*\/|\*\*|\*)/g; var globPatterns = { "*": "([^/]+)", // no backslashes "**": "(.+/)?([^/]+)", // short for "**/*" "**/": "(.+/)?" // one or more directories }; function mapToPattern(str) { return globPatterns[str]; } function replace(glob) { return glob.replace(dotRE, dotPattern).replace(restRE, restPattern).replace(globRE, mapToPattern); } function join3(globs) { return "((" + globs.map(replace).join(")|(") + "))"; } function globRegex2(glob) { return new RegExp("^" + (Array.isArray(glob) ? join3 : replace)(glob) + "$"); } globRegex2.replace = replace; Object.defineProperty(globRegex2, "default", { value: globRegex2 }); module.exports = globRegex2; } }); // src/pr-import.ts var import_glob_regex = _chunk5R2KEZLQcjs.__toESM.call(void 0, require_glob_regex(), 1); var _colors = require('kleur/colors'); var _fs = require('fs'); var _promises = require('fs/promises'); var _promises2 = _interopRequireDefault(_promises); var _path = require('path'); // src/rewired/undoRewire.ts async function undoRewire(funcPath, env) { _chunkZP624W2Acjs.debug.call(void 0, `Removing rewired file for "${funcPath}"`); const rewiredFile = _path.join.call(void 0, env.overrideDir, "rewired", funcPath + ".ts"); await _promises2.default.rm(rewiredFile); const rewired = await _chunk7UCE7HEGcjs.loadRewired.call(void 0, env); const newRewired = rewired.filter((path) => path !== funcPath); await _promises.writeFile.call(void 0, rewiredFile, JSON.stringify(newRewired, null, 2)); } // src/util/checkCommand.ts var _child_process = require('child_process'); async function checkCommand(cmd) { return new Promise((resolve) => { _child_process.exec.call(void 0, `command -v ${cmd}`, (error) => { resolve(!error); }); }); } // src/pr-import.ts async function importPullRequest(prNumber, options = {}) { if (Number.isNaN(+prNumber)) { throw new (0, _chunkST3J6QTNcjs.RadashiError)(`Invalid PR number "${prNumber}"`); } if (!await checkCommand("gh")) { throw new (0, _chunkST3J6QTNcjs.RadashiError)( _chunkQJPNUX4Pcjs.dedent` gh command is not installed. You can install it using Homebrew: brew install gh Or using the official website: https://cli.github.com/ ` ); } const env = _nullishCoalesce(options.env, () => ( _chunkZP624W2Acjs.getEnv.call(void 0, options.dir))); if (!env.radashiDir) { throw new (0, _chunkST3J6QTNcjs.RadashiError)("No upstream repository exists"); } await _chunkZTBV44GEcjs.assertRepoClean.call(void 0, env.root); await _chunk3OOKBKZBcjs.pullRadashi.call(void 0, env); await _chunkST3J6QTNcjs.exec.call(void 0, "git", ["branch", "-D", "pr-" + prNumber], { cwd: env.radashiDir, reject: false }); _chunkST3J6QTNcjs.log.call(void 0, "Checking out PR..."); await _chunkST3J6QTNcjs.exec.call(void 0, "gh", ["pr", "checkout", prNumber, "-b", "pr-" + prNumber], { cwd: env.radashiDir }).catch((error) => { _chunkST3J6QTNcjs.log.error(error.stderr); let reason = ""; if (error.message.includes("Could not resolve")) { reason = `Could not find any PR with number ${prNumber}.`; } else if (error.message.includes("couldn't find remote ref")) { reason = "The author appears to have deleted the PR branch."; } throw new (0, _chunkST3J6QTNcjs.RadashiError)( "Failed to checkout PR" + (reason ? `: ${reason}` : "") ); }); const targetBranch = await getTargetBranch(env); _chunkZP624W2Acjs.debug.call(void 0, "Target branch of the PR:", targetBranch); await _chunkST3J6QTNcjs.exec.call(void 0, "git", ["fetch"].concat( targetBranch.includes("/") ? targetBranch.split("/") : ["origin", targetBranch] ), { cwd: env.radashiDir } ).catch(_chunkST3J6QTNcjs.forwardStderrAndRethrow); const baseCommit = await _chunkST3J6QTNcjs.exec.call(void 0, "git", ["merge-base", "HEAD", targetBranch], { cwd: env.radashiDir }).then((r) => r.stdout); _chunkZP624W2Acjs.debug.call(void 0, "Base commit of the PR:", baseCommit); const changes = await parseGitDiff(baseCommit, { cwd: env.radashiDir }); _chunkZP624W2Acjs.debug.call(void 0, "Parsed changes from git diff:", changes); const pathsIn = await _chunkDNQVKCXJcjs.findSources.call(void 0, env); const srcGlob = (0, import_glob_regex.default)("src/*/*.ts"); changes.sort((a, b) => { return srcGlob.test(a.file) && !srcGlob.test(b.file) ? -1 : srcGlob.test(b.file) && !srcGlob.test(a.file) ? 1 : a.file.localeCompare(b.file); }); const addedFiles = []; const modifiedFiles = []; for (const change of changes) { const file = _path.basename.call(void 0, change.file, _path.extname.call(void 0, change.file)); if (options.files && !options.files.includes(file)) { continue; } if (change.status === "A") { addedFiles.push(change.file); if (change.file.startsWith("src/")) { const srcPath = _path.join.call(void 0, env.root, change.file); if (pathsIn.src.includes(srcPath)) { throw new (0, _chunkST3J6QTNcjs.RadashiError)( `Cannot import PR. File named "${change.file}" is already a source file created by you.` ); } } } else if (change.status === "M" && change.file !== "src/mod.ts") { modifiedFiles.push(change.file); if (change.file.startsWith("src/")) { const overridePath = _path.join.call(void 0, env.root, change.file.replace("src/", "overrides/src/") ); if (pathsIn.overrides.includes(overridePath)) { throw new (0, _chunkST3J6QTNcjs.RadashiError)( `Cannot import PR. File named "${change.file}" already exists in the overrides folder.` ); } const funcPath = _path.relative.call(void 0, env.overrideDir, overridePath).slice(0, -3); const rewiredPath = overridePath.replace("/src/", "/rewired/"); if (pathsIn.rewired.includes(rewiredPath)) { await undoRewire(funcPath, env); } await _chunkZTBV44GEcjs.addOverride.call(void 0, funcPath, { env, exactMatch: true, fromBranch: baseCommit }); } } } for (const file of addedFiles) { _chunkZP624W2Acjs.debug.call(void 0, `Adding "${file}" to project`); await tryCopyFile(_path.join.call(void 0, env.radashiDir, file), _path.join.call(void 0, env.root, file)); } for (const file of modifiedFiles) { _chunkZP624W2Acjs.debug.call(void 0, `Modifying "${file}" override in project`); await tryCopyFile( _path.join.call(void 0, env.radashiDir, file), _path.join.call(void 0, env.root, "overrides", file) ); } let prTitle = await _chunkST3J6QTNcjs.exec.call(void 0, "gh", ["pr", "view", "--json", "title", "--jq", ".title"], { cwd: env.radashiDir } ).then((result) => result.stdout.trim()); const validTitleRE = /^(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test)(\([^):]+\))?: /; if (!validTitleRE.test(prTitle)) { _chunkST3J6QTNcjs.log.error(""); _chunkST3J6QTNcjs.log.error( _colors.yellow.call(void 0, "ATTN"), "The PR title does not follow the Conventional Commits format." ); _chunkST3J6QTNcjs.log.error("Please select the type of change this PR introduces:\n"); const type = await _chunk4WZBZWYDcjs.prompt.call(void 0, { type: "autocomplete", name: "type", message: "Select the type of change:", choices: getConventionalCommitTypes() }); if (!type) { throw new (0, _chunkST3J6QTNcjs.EarlyExitError)("No change type selected. Exiting..."); } const description = await _chunk4WZBZWYDcjs.prompt.call(void 0, { type: "text", name: "description", message: "Enter a short description of the change:" }); if (!description) { throw new (0, _chunkST3J6QTNcjs.EarlyExitError)("No description provided. Exiting..."); } prTitle = `${type}: ${description}`; } const { default: build } = await Promise.resolve().then(() => _interopRequireWildcard(require("./build-D32K7VSY.cjs"))); await build({ env }); _chunkST3J6QTNcjs.log.call(void 0, ""); await _chunkWVUG42ZOcjs.botCommit.call(void 0, prTitle, { cwd: env.root, add: ["-A"] }); } async function tryCopyFile(src, dst) { if (_fs.existsSync.call(void 0, src)) { try { await _promises.mkdir.call(void 0, _path.dirname.call(void 0, dst), { recursive: true }); await _promises.copyFile.call(void 0, src, dst); return true; } catch (e) { } } return false; } async function parseGitDiff(ref, opts) { const { stdout: nameStatus } = await _chunkST3J6QTNcjs.exec.call(void 0, "git", ["diff", ref, "--name-status"], opts ); return nameStatus.trim().split("\n").map((line) => { const [status, file] = line.split(" "); return { status, file }; }); } async function getTargetBranch(env) { const { stdout } = await _chunkST3J6QTNcjs.exec.call(void 0, "gh", ["pr", "view", "--json", "baseRefName", "--jq", ".baseRefName"], { cwd: env.radashiDir } ); const targetBranch = _nullishCoalesce(_optionalChain([stdout, 'optionalAccess', _ => _.trim, 'call', _2 => _2()]), () => ( "main")); const radashiRef = await env.radashiRef; if (_chunkZP624W2Acjs.isPreReleaseRadashiTag.call(void 0, radashiRef)) { return "radashi/" + targetBranch; } return targetBranch; } function getConventionalCommitTypes() { return [ { title: "feat", description: "A new feature", value: "feat" }, { title: "fix", description: "A bug fix", value: "fix" }, { title: "docs", description: "Documentation only changes", value: "docs" }, { title: "style", description: "Changes that do not affect the meaning of the code", value: "style" }, { title: "refactor", description: "A code change that neither fixes a bug nor adds a feature", value: "refactor" }, { title: "perf", description: "A code change that improves performance", value: "perf" }, { title: "test", description: "Adding missing tests or correcting existing tests", value: "test" }, { title: "build", description: "Changes that affect the build system or external dependencies", value: "build" }, { title: "ci", description: "Changes to our CI configuration files and scripts", value: "ci" }, { title: "chore", description: "Other changes that don't modify src or test files", value: "chore" }, { title: "revert", description: "Reverts a previous commit", value: "revert" } ]; } exports.importPullRequest = importPullRequest;