UNPKG

@gabortorma/mwm

Version:

Multi-repo Workspace Manager

292 lines (276 loc) 8.44 kB
'use strict'; const git = require('simple-git'); const path = require('node:path'); const consola = require('consola'); const config = require('./mwm.b-NRmH8L.cjs'); const args = require('./mwm.Bc81aV-e.cjs'); const rest = require('@octokit/rest'); const pkgTypes = require('pkg-types'); const replaceInFile = require('replace-in-file'); const changeCase = require('change-case'); function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; } const git__default = /*#__PURE__*/_interopDefaultCompat(git); const path__default = /*#__PURE__*/_interopDefaultCompat(path); async function sleep(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); } function getRepoUrl({ owner: { id, token }, name }) { return `https://${id}:${token}@github.com/${id}/${name}.git`; } async function cloneRepo(repo) { const repoUrl = getRepoUrl(repo); return git__default().clone(repoUrl, repo.path); } async function selectOwner(owner, owners) { if (!owners) { throw new Error("No owners found! Please add owners to the config file"); } const ownersWithToken = {}; for (const key of Object.keys(owners)) { if (owners[key].token) ownersWithToken[key] = owners[key]; } const options = Object.keys(ownersWithToken); if (options.length === 0) { throw new Error("No owners with token found! Please add owners with token to the config file"); } if (!ownersWithToken[owner]) { owner = await consola.consola.prompt("Select Owner", { type: "select", options }); args.checkCancel(owner); } return { id: owner, ...ownersWithToken[owner] }; } async function getName(name) { return args.getStringArg(name, "Enter the name of the new repo"); } async function getDescription(description) { return args.getStringArg(description, "Enter the description of the new repo"); } async function getPath(dir, name, template) { if (dir) { return dir; } const repoPath = path__default.join(template.path, name); const result = consola.consola.prompt("Set the path of the new repo", { type: "text", placeholder: repoPath, default: repoPath }); args.checkCancel(result); return result; } async function getPrivate(arg) { return args.getBoolArg(arg, "Create a private repository?"); } async function getClone(arg) { return args.getBoolArg(arg, "Clone the repo instead of submodule?"); } async function getAddRemoteTemplate(arg) { return args.getBoolArg(arg, "Add remote template repository?"); } async function getFixReplacements(arg) { return args.getBoolArg(arg, "Fix replacements?"); } function getKeywords(arg) { if (typeof arg === "string") return arg.split(",").map((keyword) => keyword.trim()); } async function getRepo(args, template) { const { config: config$1 } = await config.loadConfig(); const name = await getName(args.name); return { owner: await selectOwner(args.owner, config$1.owners), name, description: await getDescription(args.description), path: await getPath(args.dir, name, template), private: await getPrivate(args.private), keywords: getKeywords(args.keywords) }; } async function generateGitHubRepo(template, repo) { const octokit = new rest.Octokit({ auth: repo.owner.token }); await octokit.request(`POST /repos/${template.owner}/${template.repo}/generate`, { owner: repo.owner.id, name: repo.name, description: repo.description, private: repo.private, include_all_branches: false, headers: { "X-GitHub-Api-Version": "2022-11-28" } }); } async function fixReplacements(replacements, repo) { for (const replacement of replacements) { if (replacement.type === "replace") { let files = replacement.files; if (!Array.isArray(files)) { files = [files]; } replacement.files = files.map((file) => path.join(".", repo.path, file)); await replaceInFile.replaceInFile(replacement); } else if (replacement.type === "pkg") { const file = path.resolve(".", repo.path, "package.json"); const packageJson = await pkgTypes.readPackageJSON(file); await pkgTypes.writePackageJSON(file, replacement.replace(packageJson, repo)); } } } const packageReplacement = { type: "pkg", replace: (packageJson, repo) => { const fullRepo = `${repo.owner.id}/${repo.name}`; packageJson.name = `@${repo.owner.id.toLowerCase()}/${repo.name}`; packageJson.author = repo.owner.name || repo.owner.id; packageJson.description = repo.description; packageJson.version = "0.0.1"; packageJson.repository = { type: "github", url: `git+ssh://git@github.com/${fullRepo}.git` }; if (repo.keywords) packageJson.keywords = repo.keywords; if (packageJson.homepage) packageJson.homepage = `https://github.com/${fullRepo}`; if (packageJson.bugs) packageJson.bugs = `https://github.com/${fullRepo}/issues`; return packageJson; } }; function getReadmeReplacement(template, repo) { return { type: "replace", files: ["README.md"], from: [ new RegExp(template.owner, "gi"), new RegExp(template.repo, "g"), new RegExp(changeCase.camelCase(template.repo), "g"), new RegExp(changeCase.pascalCase(template.repo), "g"), "_description_" ], to: [ repo.owner.id.toLowerCase(), repo.name, changeCase.camelCase(repo.name), changeCase.pascalCase(repo.name), repo.description ] }; } const nitroPluginTemplate = { path: "releases", owner: "GaborTorma", repo: "mwm-nitro-plugin-template", branch: "main", getReplacements(repo) { return [ packageReplacement, getReadmeReplacement(this, repo) ]; } }; const nuxtLayerTemplate = { path: "layers", owner: "GaborTorma", repo: "mwm-nuxt-layer-template", branch: "main", getReplacements(repo) { return [ packageReplacement, getReadmeReplacement(this, repo) ]; } }; const nuxtModuleTemplate = { path: "modules", owner: "GaborTorma", repo: "mwm-nuxt-module-template", branch: "main", getReplacements(repo) { return [ packageReplacement, getReadmeReplacement(this, repo), { // configKey type: "replace", files: [ "playground/nuxt.config.ts", "src/module.ts" ], from: new RegExp(changeCase.camelCase(this.repo), "g"), to: changeCase.camelCase(repo.name) }, { // module name type: "replace", files: [ "src/module.ts", "src/runtime/plugin.ts" ], from: new RegExp(this.repo, "g"), to: repo.name } ]; } }; const templateTypes = ["nuxt-layer", "nuxt-module", "nitro-plugin"]; const templates = { "nuxt-layer": nuxtLayerTemplate, "nuxt-module": nuxtModuleTemplate, "nitro-plugin": nitroPluginTemplate }; async function selectTemplate(template) { if (!templates[template]) { template = await consola.consola.prompt("Select template", { type: "select", options: templateTypes }); args.checkCancel(template); } return templates[template]; } async function getGit(repo) { return git__default({ baseDir: path__default.resolve(repo.path) }); } async function addRemoteTemplate(template, repo) { const git = await getGit(repo); await git.addRemote("template", `git@github.com:${template.owner}/${template.repo}.git`); await git.fetch("template", "main"); await git.merge([`template/${template.branch}`, "--allow-unrelated-histories", "--message=Merge template"]); } async function commitInitChanges(repo) { const git = await getGit(repo); await git.add("."); await git.commit("Customize template"); } async function pushChanges(repo) { const git = await getGit(repo); await git.push("origin", "main"); } exports.addRemoteTemplate = addRemoteTemplate; exports.cloneRepo = cloneRepo; exports.commitInitChanges = commitInitChanges; exports.fixReplacements = fixReplacements; exports.generateGitHubRepo = generateGitHubRepo; exports.getAddRemoteTemplate = getAddRemoteTemplate; exports.getClone = getClone; exports.getFixReplacements = getFixReplacements; exports.getRepo = getRepo; exports.getRepoUrl = getRepoUrl; exports.packageReplacement = packageReplacement; exports.pushChanges = pushChanges; exports.selectTemplate = selectTemplate; exports.sleep = sleep;