typescript-assistant
Version:
Combines and integrates professional Typescript tools into your project
178 lines (154 loc) • 5.41 kB
text/typescript
import * as fs from "fs";
import { compile as handlebarsCompile } from "handlebars";
import { Logger } from "../logger";
import { Command } from "./command";
export function createInitCommand(dependencies: {
logger: Logger;
}): Command<boolean> {
function log(msg: string) {
return dependencies.logger.log("init", msg);
}
function addLinesToFile(
filePath: string,
linesToAdd: { line: string; ifNotExists: RegExp }[]
) {
let lines: string[] = [];
if (fs.existsSync(filePath)) {
lines = fs.readFileSync(filePath, { encoding: "utf-8" }).split("\n");
}
let count = 0;
linesToAdd.forEach((lineToAdd) => {
if (lines.every((line) => !lineToAdd.ifNotExists.test(line))) {
count++;
lines.push(lineToAdd.line);
}
});
if (count > 0) {
fs.writeFileSync(filePath, lines.join("\n"), { encoding: "utf-8" });
log(`Added ${count} instructions to '${filePath}'`);
}
}
function addPackageJsonScripts(scripts: { [index: string]: string }): void {
let packageJson = fs.readFileSync("package.json", { encoding: "utf-8" });
let data = JSON.parse(packageJson);
data.scripts = data.scripts || {};
let count = 0;
for (let scriptName of Object.keys(scripts)) {
if (!data.scripts[scriptName]) {
data.scripts[scriptName] = scripts[scriptName];
count++;
}
}
if (count > 0) {
fs.writeFileSync("package.json", JSON.stringify(data, undefined, 2), {
encoding: "utf-8",
});
log(`Added ${count} script entries to package.json`);
}
}
function addPackageJsonSectionFromTemplate(
sectionName: string,
templateData: any
): void {
let packageJson = fs.readFileSync("package.json", { encoding: "utf-8" });
let data = JSON.parse(packageJson);
if (!data[sectionName]) {
let template = fs.readFileSync(
`${__dirname}/../../templates/package-json/${sectionName}.hbs`,
{ encoding: "utf-8" }
);
data[sectionName] = JSON.parse(handlebarsCompile(template)(templateData));
fs.writeFileSync("package.json", JSON.stringify(data, undefined, 2), {
encoding: "utf-8",
});
log(`Added section ${sectionName} to package.json`);
}
}
function writeFromTemplateIfNotExists(filePath: string, info: any) {
if (fs.existsSync(filePath)) {
return;
}
let template = fs.readFileSync(
`${__dirname}/../../templates/${filePath.replace(/\//, "-")}.hbs`,
{ encoding: "utf-8" }
);
let result = handlebarsCompile(template)(info);
fs.writeFileSync(filePath, result, { encoding: "utf-8" });
log(`Wrote '${filePath}'`);
}
return {
execute(library: boolean) {
addLinesToFile(".gitignore", [
{ line: "/build", ifNotExists: /\/?build/ },
{ line: "/dist", ifNotExists: /\/?dist/ },
{ line: "node_modules", ifNotExists: /\/?node_modules/ },
{ line: "/.idea", ifNotExists: /\/?.idea/ },
{ line: "/.vscode", ifNotExists: /\/?.vscode/ },
]);
addLinesToFile(".gitattributes", [
{ line: "* text eol=lf", ifNotExists: /.*eol=lf.*/ },
]);
addLinesToFile(".editorconfig", [
{
line: `[*]
indent_style = space
indent_size = 2
charset = utf-8
end_of_line = lf
trim_trailing_whitespace = true
insert_final_newline = true`,
ifNotExists: /.*indent_style.*/,
},
]);
let templateData = {
library,
// eslint-disable-next-line @typescript-eslint/no-var-requires
typescriptAssistantVersion: require("../../package.json").version,
};
writeFromTemplateIfNotExists("package.json", templateData);
if (library) {
addLinesToFile(".npmignore", [
{
line: `/**/*
!/dist/**/*
!/README.md`,
ifNotExists: /.*dist.*/,
},
]);
}
addPackageJsonScripts({
prepublishOnly: "tsa clean && npm -s run dist",
assist: "tsa assist",
release: "tsa release",
fix: "tsa fix",
clean: "tsa clean",
dist: "tsc -p ./src/tsconfig.json",
ci: "tsa ci",
test: "tsa ci",
"coverage-show": "open-cli build/coverage/index.html",
precommit: "tsa pre-commit",
prepush: "npm run dist && tsa pre-push",
postcheckout: "tsa post-checkout || exit 0",
postmerge: "tsa post-merge || exit 0",
});
addPackageJsonSectionFromTemplate("nyc", templateData);
if (!fs.existsSync("src")) {
fs.mkdirSync("src");
writeFromTemplateIfNotExists("src/example.ts", templateData);
}
if (!fs.existsSync("test")) {
fs.mkdirSync("test");
writeFromTemplateIfNotExists("test/example-tests.ts", templateData);
}
writeFromTemplateIfNotExists(".eslintignore", templateData);
writeFromTemplateIfNotExists(".eslintrc.js", templateData);
writeFromTemplateIfNotExists(".prettierignore", templateData);
writeFromTemplateIfNotExists(".prettierrc.json", templateData);
writeFromTemplateIfNotExists("tsconfig.json", templateData);
writeFromTemplateIfNotExists("src/tsconfig.json", templateData);
writeFromTemplateIfNotExists("tslint.json", templateData);
writeFromTemplateIfNotExists("tslint.editor.json", templateData);
return Promise.resolve(true);
},
};
}