carpent
Version:
Bootstrap and configure any project using its template
186 lines • 6.94 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.LICENSES = exports.getLicenseText = exports.carpent = void 0;
const slugify_1 = __importDefault(require("@sindresorhus/slugify"));
const child_process_1 = require("child_process");
const fs_extra_1 = require("fs-extra");
const got_1 = __importDefault(require("got"));
const inquirer_1 = __importDefault(require("inquirer"));
const ora_1 = __importDefault(require("ora"));
const path_1 = require("path");
/**
* Bootstrap a new project with Carpent
* @param defaultAnswers - Object containing values
*/
exports.carpent = async (defaultAnswers = {}) => {
// Ask input name
if (!defaultAnswers.repo || !defaultAnswers.dir) {
defaultAnswers = await inquirer_1.default.prompt([
{
name: "repo",
type: "input",
message: "Git repository URL",
default: defaultAnswers.repo,
},
{
name: "dir",
type: "input",
message: "Folder name",
default: "carpent",
},
]);
}
// Clone the repo
const spinner = ora_1.default("Cloning git repository").start();
const slug = slugify_1.default(defaultAnswers.dir);
await exec(`git clone ${defaultAnswers.repo} ${slug}`);
const path = path_1.join(".", slug);
// Find .carpentrc
let config = DEFAULT;
if (await fs_extra_1.pathExists(path_1.join(path, ".carpentrc")))
config = await fs_extra_1.readJson(path_1.join(path, ".carpentrc"));
// Run pre scripts
spinner.text = "Running scripts";
for await (const script of config.beforeAll ?? []) {
await exec(script);
}
// Ask questions
spinner.stop();
const allQuestions = [
...(config.questions ?? []),
{
name: "license",
type: "list",
message: "License",
default: "MIT License",
choices: Object.values(exports.LICENSES),
},
{
name: "licenseName",
type: "input",
message: "Name in license (usually full name)",
default: slug,
},
{
name: "initializeNewRepo",
type: "confirm",
message: "Initialize new git repository?",
},
];
const answers = Object.keys(defaultAnswers).length > 2
? defaultAnswers
: await inquirer_1.default.prompt(allQuestions);
// Run pre scripts
spinner.text = "Running scripts";
spinner.start();
for await (const script of config.beforeAll ?? []) {
await exec(script);
}
// Update values
spinner.text = "Updating values";
for await (const question of allQuestions) {
const VAL = question.replace
? question.replace.replace(new RegExp("$VALUE", "g"), answers[question.name])
: answers[question.name];
// Update each file
for await (const file of question.files ?? []) {
if (await fs_extra_1.pathExists(path_1.join(slug, file))) {
let fileContents = await fs_extra_1.readFile(path_1.join(slug, file), "utf8");
if (question.find)
fileContents = fileContents.replace(new RegExp(question.find, "g"), VAL);
// Support JSON key changes
if (question.jsonKey) {
const jsonContent = JSON.parse(fileContents);
jsonContent[question.jsonKey] = VAL;
fileContents = JSON.stringify(jsonContent, null, 2);
}
await fs_extra_1.writeFile(path_1.join(slug, file), fileContents);
}
}
// Update license
spinner.text = "Updating license";
if (question.name === "license") {
const SPDX = (Object.entries(exports.LICENSES).find((pair) => pair[1] === VAL) ?? [""])[0];
const licenseText = await exports.getLicenseText(SPDX);
// Create LICENSE file
await fs_extra_1.writeFile(path_1.join(slug, "LICENSE"), licenseText
.replace("$NAME", answers.licenseName)
.replace("$YEAR", new Date().getFullYear().toString()));
// Update license in package.json
if (await fs_extra_1.pathExists(path_1.join(slug, "package.json"))) {
let packageJson = await fs_extra_1.readJson(path_1.join(slug, "package.json"));
packageJson.license = SPDX;
if (SPDX === "UNLICENSED")
packageJson.private = true;
await fs_extra_1.writeFile(path_1.join(slug, "package.json"), JSON.stringify(packageJson, null, 2));
}
}
}
// Delete files
spinner.text = "Deleting files";
for await (const file of config.deleteFiles ?? []) {
await fs_extra_1.remove(path_1.join(slug, file));
}
// Set up git repository
spinner.text = "Setting up git repository";
if (answers.initializeNewRepo) {
await exec(`cd ${path} && rm -rf .git && git init && cd ..`);
}
// Run post scripts
spinner.text = "Running scripts";
for await (const script of config.afterAll ?? []) {
await exec(script);
}
// Return the result
spinner.succeed(`Project is ready in ./${path}`);
return { path };
};
/**
* Get the text for a license
* @param SPDX - License SPDX identifier
*/
exports.getLicenseText = async (SPDX) => {
return (await got_1.default(`https://raw.githubusercontent.com/AnandChowdhary/carpent/master/assets/licenses/${SPDX}.txt`)).body;
};
/**
* Promise polyfill for `child_process.exec`
* @param command - Command to execute
*/
const exec = (command) => new Promise((resolve, reject) => {
child_process_1.exec(command, (error, stdout) => {
if (error)
return reject(error);
resolve(stdout);
});
});
const DEFAULT = {
deleteFiles: [".carpentrc"],
questions: [
{
name: "name",
type: "input",
message: "Project name",
files: ["package.json"],
jsonKey: "name",
},
],
};
/** Licenses (SPDX to name map) */
exports.LICENSES = {
"Apache-2.0": "Apache 2.0",
"BSD-3-Clause": "BSD 3-clause",
"CC-BY-SA-4.0": "Creative Commons Attribution Share-Alike (CC BY SA 4.0)",
"GPL-3.0": "GPL 3.0",
MIT: "MIT License",
UNLICENSED: "No open-source license (private and proprietary)",
"BSD-2-Clause": "BSD 2-clause",
"CC-BY-4.0": "Creative Commons Attribution (CC BY 4.0)",
"CC0-1.0": "Creative Commons Zero (CC0)",
ISC: "ISC License",
"MPL-2.0": "Mozilla Public License 2.0",
Unlicense: "The Unlicense",
};
//# sourceMappingURL=index.js.map