1 | "use strict";
|
2 | const child_process_1 = require("child_process");
|
3 | const cli_ux_1 = require("cli-ux");
|
4 | const json = require("comment-json");
|
5 | const fs = require("fs");
|
6 | const lodash_1 = require("lodash");
|
7 | const path = require("path");
|
8 | const util = require("util");
|
9 | const spawnPromise = util.promisify(child_process_1.exec);
|
10 | const command_1 = require("@oclif/command");
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 | class BearerPackageInit extends command_1.Command {
|
20 | async run() {
|
21 | const { flags } = this.parse(BearerPackageInit);
|
22 | this.cwd = path.resolve(flags.path);
|
23 | this.force = flags.force;
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 |
|
38 |
|
39 |
|
40 |
|
41 |
|
42 |
|
43 |
|
44 |
|
45 |
|
46 |
|
47 |
|
48 |
|
49 |
|
50 |
|
51 |
|
52 |
|
53 |
|
54 |
|
55 |
|
56 |
|
57 |
|
58 |
|
59 |
|
60 |
|
61 |
|
62 |
|
63 |
|
64 | const dependencies = [
|
65 | 'typescript',
|
66 | 'husky',
|
67 | 'lint-staged',
|
68 | 'commitlint',
|
69 | '@commitlint/config-conventional',
|
70 | '@commitlint/cli',
|
71 | 'cz-conventional-changelog',
|
72 | 'tslint',
|
73 | BEARER_TSLINT,
|
74 | BEARER_TSCONFIG,
|
75 | 'tslint-config-prettier',
|
76 | 'prettier',
|
77 | 'jest',
|
78 | 'ts-jest',
|
79 | '@types/jest'
|
80 | ];
|
81 | try {
|
82 | await this.installDependencies(dependencies);
|
83 | await this.initTypescriptProject();
|
84 | await this.addHooksAndScripts();
|
85 | await this.addTsLintConfig();
|
86 | await this.setupJest();
|
87 | }
|
88 | catch (e) {
|
89 | cli_ux_1.cli.action.stop();
|
90 | return this.error(e);
|
91 | }
|
92 |
|
93 |
|
94 | }
|
95 | async installDependencies(dependencies) {
|
96 | return this.withLoader(`Installing depenencies:\n * ${dependencies.join('\n * ')}`, () => this.runCommand(`yarn add -D ${dependencies.join(' ')}`));
|
97 | }
|
98 | async addHooksAndScripts() {
|
99 | const packageFile = path.join(this.cwd, 'package.json');
|
100 | try {
|
101 | cli_ux_1.cli.action.start('Adding hooks');
|
102 | const projectPackage = JSON.parse(fs.readFileSync(packageFile, { encoding: 'utf8' }));
|
103 | if (!lodash_1.get(projectPackage, LINT_STAGED_KEY)) {
|
104 | lodash_1.set(projectPackage, LINT_STAGED_KEY, LINT_STAGED);
|
105 | }
|
106 | else {
|
107 | this.log('lint-staged already setup, skipping');
|
108 | }
|
109 | if (!lodash_1.get(projectPackage, COMMIT_LINT_CONFIG_KEY)) {
|
110 | lodash_1.set(projectPackage, COMMIT_LINT_CONFIG_KEY, COMMIT_LINT_CONFIG);
|
111 | }
|
112 | else {
|
113 | this.log('lint-staged already setup, skipping');
|
114 | }
|
115 | if (!lodash_1.get(projectPackage, LINT_STAGED_HOOK)) {
|
116 | lodash_1.set(projectPackage, LINT_STAGED_HOOK, LINT_STAGED_HOOK_VALUE);
|
117 | }
|
118 | else {
|
119 | this.log('lint-staged hook already setup, skipping');
|
120 | }
|
121 | if (!lodash_1.get(projectPackage, COMMIT_LINT_HOOK)) {
|
122 | lodash_1.set(projectPackage, COMMIT_LINT_HOOK, COMMIT_LINT_HOOK_VALUE);
|
123 | }
|
124 | else {
|
125 | this.log('commitlint hook already setup, skipping');
|
126 | }
|
127 | lodash_1.set(projectPackage, 'scripts.start', 'tsc --watch');
|
128 | lodash_1.set(projectPackage, 'scripts.build', 'tsc -p tsconfig.json');
|
129 | lodash_1.set(projectPackage, 'scripts.clean', 'rm -rf lib');
|
130 | lodash_1.set(projectPackage, 'scripts.prepack', 'yarn clean && yarn build');
|
131 | lodash_1.set(projectPackage, 'scripts.test', 'jest');
|
132 | lodash_1.set(projectPackage, 'scripts.test:ci', 'jest --coverage');
|
133 | fs.writeFileSync(packageFile, JSON.stringify(projectPackage, null, 2));
|
134 | fs.writeFileSync(path.join(this.cwd, 'commitlint.config.js'), "module.exports = { extends: ['@commitlint/config-conventional'] }");
|
135 | cli_ux_1.cli.action.stop();
|
136 | }
|
137 | catch (e) {
|
138 | throw e;
|
139 | }
|
140 | }
|
141 | async initTypescriptProject() {
|
142 | return this.withLoader('Init Typescript stuff', async () => {
|
143 | await this.runCommand('yarn tsc --init');
|
144 | const configFile = path.join(this.cwd, 'tsconfig.json');
|
145 | const src = path.join(this.cwd, 'src');
|
146 | const config = json.parse(fs.readFileSync(configFile, { encoding: 'utf8' }), undefined, true);
|
147 | lodash_1.set(config, 'extends', BEARER_TSCONFIG);
|
148 | fs.writeFileSync(configFile, json.stringify(config, null, 2));
|
149 | if (!fs.existsSync(src)) {
|
150 | fs.mkdirSync(src);
|
151 | fs.writeFileSync(path.join(src, 'index.ts'), '');
|
152 | }
|
153 | });
|
154 | }
|
155 | async addTsLintConfig() {
|
156 | return this.withLoader('Init TSlint stuff', async () => {
|
157 | const configFile = path.join(this.cwd, 'tslint.json');
|
158 | if (!fs.existsSync(configFile)) {
|
159 | await this.runCommand('yarn tslint --init');
|
160 | }
|
161 | const config = json.parse(fs.readFileSync(configFile, { encoding: 'utf8' }), undefined, true);
|
162 |
|
163 | lodash_1.set(config, 'extends', BEARER_TSLINT);
|
164 | fs.writeFileSync(configFile, json.stringify(config, null, 2));
|
165 | fs.writeFileSync(path.join(this.cwd, '.prettierrc'), json.stringify(prettierConfig, null, 2));
|
166 | });
|
167 | }
|
168 | async setupJest() {
|
169 |
|
170 | if (!fs.existsSync(path.join(this.cwd, 'jest.config.js'))) {
|
171 | return this.withLoader('Init Jest stuff', async () => {
|
172 | await this.runCommand('yarn ts-jest config:init');
|
173 | });
|
174 | }
|
175 | }
|
176 | async withLoader(title, block) {
|
177 | try {
|
178 | cli_ux_1.cli.action.start(title);
|
179 | await block();
|
180 | cli_ux_1.cli.action.stop();
|
181 | }
|
182 | catch (e) {
|
183 | if (this.force) {
|
184 | console.error('Error on ', title, '\n', e.toString());
|
185 | }
|
186 | else {
|
187 | throw e;
|
188 | }
|
189 | }
|
190 | }
|
191 | async runCommand(command) {
|
192 | await spawnPromise(command, {
|
193 | cwd: this.cwd
|
194 | });
|
195 | }
|
196 | }
|
197 | BearerPackageInit.description = 'describe the command here';
|
198 | BearerPackageInit.flags = {
|
199 | path: command_1.flags.string({ char: 'p', default: process.cwd() }),
|
200 | force: command_1.flags.boolean({ char: 'f', default: false })
|
201 | };
|
202 | BearerPackageInit.args = [{ name: 'file' }];
|
203 | const COMMIT_LINT_HOOK = 'husky.hooks.commit-msg';
|
204 | const COMMIT_LINT_HOOK_VALUE = 'commitlint -E HUSKY_GIT_PARAMS';
|
205 | const COMMIT_LINT_CONFIG = './node_modules/cz-conventional-changelog';
|
206 | const COMMIT_LINT_CONFIG_KEY = 'config.commitizen.path';
|
207 | const LINT_STAGED_HOOK = 'husky.hooks.pre-commit';
|
208 | const LINT_STAGED_HOOK_VALUE = 'lint-staged';
|
209 | const LINT_STAGED_KEY = 'lint-staged';
|
210 | const LINT_STAGED = {
|
211 | '*.{css,md,tsx,ts}': ['prettier --write', 'tslint -c tslint.json --fix', 'git add']
|
212 | };
|
213 | const BEARER_TSLINT = '@bearer/tslint-config';
|
214 | const BEARER_TSCONFIG = '@bearer/tsconfig';
|
215 | const prettierConfig = {
|
216 | semi: false,
|
217 | singleQuote: true,
|
218 | printWidth: 120,
|
219 | tabWidth: 2
|
220 | };
|
221 | module.exports = BearerPackageInit;
|