cmyr-template-cli 1.6.0 → 1.7.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1 -1
- package/dist/plopfile.js +298 -18
- package/package.json +1 -1
- package/templates/.editorconfig +26 -0
- package/templates/.github/workflows/release.yml +32 -0
- package/templates/.github/workflows/test.yml +25 -0
- package/templates/.husky/commit-msg +4 -0
- package/templates/.husky/pre-commit +4 -0
- package/templates/.releaserc.js +34 -0
- package/templates/CONTRIBUTING.md +13 -14
- package/templates/LICENSE +21 -0
- package/templates/README.md +16 -2
- package/templates/commitlint.config.js +20 -0
package/dist/index.js
CHANGED
|
@@ -13,7 +13,7 @@ var path__default = /*#__PURE__*/_interopDefaultLegacy(path);
|
|
|
13
13
|
|
|
14
14
|
const program = new commander.Command('ct')
|
|
15
15
|
.description('草梅项目创建器');
|
|
16
|
-
program.version("1.
|
|
16
|
+
program.version("1.7.2" , '-v, --version');
|
|
17
17
|
const args = process.argv.slice(2);
|
|
18
18
|
if (args.length === 0) {
|
|
19
19
|
args.push('create');
|
package/dist/plopfile.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
var path = require('path');
|
|
5
4
|
var fs = require('fs-extra');
|
|
5
|
+
var path = require('path');
|
|
6
6
|
var ora = require('ora');
|
|
7
7
|
var download = require('download-git-repo');
|
|
8
8
|
var axios = require('axios');
|
|
@@ -32,8 +32,8 @@ function _interopNamespace(e) {
|
|
|
32
32
|
return Object.freeze(n);
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
var path__default = /*#__PURE__*/_interopDefaultLegacy(path);
|
|
36
35
|
var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs);
|
|
36
|
+
var path__default = /*#__PURE__*/_interopDefaultLegacy(path);
|
|
37
37
|
var ora__default = /*#__PURE__*/_interopDefaultLegacy(ora);
|
|
38
38
|
var download__default = /*#__PURE__*/_interopDefaultLegacy(download);
|
|
39
39
|
var axios__default = /*#__PURE__*/_interopDefaultLegacy(axios);
|
|
@@ -106,8 +106,16 @@ async function asyncExec(cmd, options) {
|
|
|
106
106
|
});
|
|
107
107
|
});
|
|
108
108
|
}
|
|
109
|
+
async function initProject(answers) {
|
|
110
|
+
const { name, template } = answers;
|
|
111
|
+
const projectPath = path__default["default"].join(process.cwd(), name);
|
|
112
|
+
await downloadGitRepo(`CaoMeiYouRen/${template}`, projectPath);
|
|
113
|
+
await init(projectPath, answers);
|
|
114
|
+
return '- 下载项目模板成功!';
|
|
115
|
+
}
|
|
109
116
|
async function init(projectPath, answers) {
|
|
110
|
-
|
|
117
|
+
var _a;
|
|
118
|
+
const { isOpenSource, isRemoveDependabot, gitRemoteUrl, isInitReadme, isInitContributing, isInitHusky, isInitSemanticRelease } = answers;
|
|
111
119
|
try {
|
|
112
120
|
await asyncExec('git --version', {
|
|
113
121
|
cwd: projectPath,
|
|
@@ -134,7 +142,13 @@ async function init(projectPath, answers) {
|
|
|
134
142
|
await fs__default["default"].remove(mergifyPath);
|
|
135
143
|
}
|
|
136
144
|
}
|
|
137
|
-
await initProjectJson(projectPath, answers);
|
|
145
|
+
const newPkg = await initProjectJson(projectPath, answers);
|
|
146
|
+
if (isInitSemanticRelease) {
|
|
147
|
+
await initSemanticRelease(projectPath);
|
|
148
|
+
}
|
|
149
|
+
if (isInitHusky) {
|
|
150
|
+
await initHusky(projectPath);
|
|
151
|
+
}
|
|
138
152
|
if (isOpenSource) {
|
|
139
153
|
const info = await getProjectInfo(projectPath, answers);
|
|
140
154
|
if (info) {
|
|
@@ -144,14 +158,17 @@ async function init(projectPath, answers) {
|
|
|
144
158
|
if (isInitContributing) {
|
|
145
159
|
await initContributing(projectPath, info);
|
|
146
160
|
}
|
|
161
|
+
if (info.licenseName === 'MIT') {
|
|
162
|
+
await initLicense(projectPath, info);
|
|
163
|
+
}
|
|
147
164
|
}
|
|
165
|
+
await initGithubWorkflows(projectPath, answers);
|
|
148
166
|
}
|
|
167
|
+
await initConfig(projectPath);
|
|
168
|
+
await sortProjectJson(projectPath);
|
|
149
169
|
await asyncExec('git add .', {
|
|
150
170
|
cwd: projectPath,
|
|
151
171
|
});
|
|
152
|
-
await asyncExec('git commit -m "chore: init"', {
|
|
153
|
-
cwd: projectPath,
|
|
154
|
-
});
|
|
155
172
|
const loading = ora__default["default"]('正在安装依赖……').start();
|
|
156
173
|
try {
|
|
157
174
|
await asyncExec(`${PACKAGE_MANAGER} i`, {
|
|
@@ -161,17 +178,29 @@ async function init(projectPath, answers) {
|
|
|
161
178
|
}
|
|
162
179
|
catch (error) {
|
|
163
180
|
loading.fail('依赖安装失败!');
|
|
181
|
+
process.exit(1);
|
|
164
182
|
}
|
|
165
183
|
await asyncExec('git add .', {
|
|
166
184
|
cwd: projectPath,
|
|
167
185
|
});
|
|
186
|
+
if ((_a = newPkg === null || newPkg === void 0 ? void 0 : newPkg.scripts) === null || _a === void 0 ? void 0 : _a.lint) {
|
|
187
|
+
await asyncExec(`${PACKAGE_MANAGER} run lint`, {
|
|
188
|
+
cwd: projectPath,
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
await asyncExec('git add .', {
|
|
192
|
+
cwd: projectPath,
|
|
193
|
+
});
|
|
194
|
+
await asyncExec('git commit -m "chore: init"', {
|
|
195
|
+
cwd: projectPath,
|
|
196
|
+
});
|
|
168
197
|
}
|
|
169
198
|
catch (error) {
|
|
170
199
|
console.error(error);
|
|
171
200
|
}
|
|
172
201
|
}
|
|
173
202
|
async function getGitUserName() {
|
|
174
|
-
const username = (await asyncExec('git config user.name'));
|
|
203
|
+
const username = (await asyncExec('git config user.name')) || '';
|
|
175
204
|
return username.trim();
|
|
176
205
|
}
|
|
177
206
|
async function initProjectJson(projectPath, answers) {
|
|
@@ -182,7 +211,7 @@ async function initProjectJson(projectPath, answers) {
|
|
|
182
211
|
const homepage = `${repositoryUrl}#readme`;
|
|
183
212
|
const issuesUrl = `${repositoryUrl}/issues`;
|
|
184
213
|
const gitUrl = `git+${repositoryUrl}.git`;
|
|
185
|
-
const nodeVersion = await getLtsNodeVersion() || '
|
|
214
|
+
const nodeVersion = await getLtsNodeVersion() || '16';
|
|
186
215
|
const node = Number(nodeVersion) - 4;
|
|
187
216
|
const pkgPath = path__default["default"].join(projectPath, 'package.json');
|
|
188
217
|
const pkg = await fs__default["default"].readJSON(pkgPath);
|
|
@@ -193,8 +222,13 @@ async function initProjectJson(projectPath, answers) {
|
|
|
193
222
|
private: !isPublishToNpm,
|
|
194
223
|
license: 'UNLICENSED',
|
|
195
224
|
engines: {
|
|
225
|
+
...(pkg === null || pkg === void 0 ? void 0 : pkg.engines) || {},
|
|
196
226
|
node: `>=${node}`,
|
|
197
227
|
},
|
|
228
|
+
devDependencies: {
|
|
229
|
+
...pkg === null || pkg === void 0 ? void 0 : pkg.devDependencies,
|
|
230
|
+
'eslint-config-cmyr': `^${await getNpmPackageVersion('eslint-config-cmyr')}`,
|
|
231
|
+
},
|
|
198
232
|
};
|
|
199
233
|
let extData = {};
|
|
200
234
|
if (isOpenSource) {
|
|
@@ -208,11 +242,15 @@ async function initProjectJson(projectPath, answers) {
|
|
|
208
242
|
bugs: {
|
|
209
243
|
url: issuesUrl,
|
|
210
244
|
},
|
|
245
|
+
changelog: {
|
|
246
|
+
language: 'zh',
|
|
247
|
+
},
|
|
211
248
|
};
|
|
212
249
|
}
|
|
213
250
|
const newPkg = Object.assign({}, pkg, pkgData, extData);
|
|
214
251
|
await fs__default["default"].writeFile(pkgPath, JSON.stringify(newPkg, null, 2));
|
|
215
252
|
loading.succeed('package.json 初始化成功!');
|
|
253
|
+
return newPkg;
|
|
216
254
|
}
|
|
217
255
|
catch (error) {
|
|
218
256
|
console.error(error);
|
|
@@ -221,7 +259,7 @@ async function initProjectJson(projectPath, answers) {
|
|
|
221
259
|
}
|
|
222
260
|
const cleanText = (text) => text.replace(/-/g, '--').replace(/_/g, '__');
|
|
223
261
|
async function getProjectInfo(projectPath, answers) {
|
|
224
|
-
var _a, _b, _c, _d, _e;
|
|
262
|
+
var _a, _b, _c, _d, _e, _f;
|
|
225
263
|
const loading = ora__default["default"]('正在获取项目信息 ……').start();
|
|
226
264
|
try {
|
|
227
265
|
const { name, author, description, isOpenSource, isPublishToNpm } = answers;
|
|
@@ -237,6 +275,7 @@ async function getProjectInfo(projectPath, answers) {
|
|
|
237
275
|
const buildCommand = ((_c = pkg === null || pkg === void 0 ? void 0 : pkg.scripts) === null || _c === void 0 ? void 0 : _c.build) && `${packageManager} run build`;
|
|
238
276
|
const testCommand = ((_d = pkg === null || pkg === void 0 ? void 0 : pkg.scripts) === null || _d === void 0 ? void 0 : _d.test) && `${packageManager} run test`;
|
|
239
277
|
const lintCommand = ((_e = pkg === null || pkg === void 0 ? void 0 : pkg.scripts) === null || _e === void 0 ? void 0 : _e.lint) && `${packageManager} run lint`;
|
|
278
|
+
const commitCommand = ((_f = pkg === null || pkg === void 0 ? void 0 : pkg.scripts) === null || _f === void 0 ? void 0 : _f.commit) && `${packageManager} run commit`;
|
|
240
279
|
const repositoryUrl = `https://github.com/${author}/${name}`;
|
|
241
280
|
const issuesUrl = `${repositoryUrl}/issues`;
|
|
242
281
|
const contributingUrl = `${repositoryUrl}/blob/master/CONTRIBUTING.md`;
|
|
@@ -249,6 +288,7 @@ async function getProjectInfo(projectPath, answers) {
|
|
|
249
288
|
const discussionsUrl = `${repositoryUrl}/discussions`;
|
|
250
289
|
const pullRequestsUrl = `${repositoryUrl}/pulls`;
|
|
251
290
|
const projectInfos = {
|
|
291
|
+
...answers,
|
|
252
292
|
currentYear: new Date().getFullYear(),
|
|
253
293
|
name,
|
|
254
294
|
description,
|
|
@@ -275,6 +315,7 @@ async function getProjectInfo(projectPath, answers) {
|
|
|
275
315
|
buildCommand,
|
|
276
316
|
testCommand,
|
|
277
317
|
lintCommand,
|
|
318
|
+
commitCommand,
|
|
278
319
|
isJSProject: true,
|
|
279
320
|
packageManager,
|
|
280
321
|
isProjectOnNpm: isPublishToNpm,
|
|
@@ -343,6 +384,203 @@ async function initContributing(projectPath, projectInfos) {
|
|
|
343
384
|
console.error(error);
|
|
344
385
|
}
|
|
345
386
|
}
|
|
387
|
+
async function initLicense(projectPath, projectInfos) {
|
|
388
|
+
const loading = ora__default["default"]('正在初始化 LICENSE ……').start();
|
|
389
|
+
try {
|
|
390
|
+
const templatePath = path__default["default"].join(__dirname, '../templates/LICENSE');
|
|
391
|
+
const template = (await fs__default["default"].readFile(templatePath, 'utf8')).toString();
|
|
392
|
+
const newReadmePath = path__default["default"].join(projectPath, 'LICENSE');
|
|
393
|
+
const readmeContent = await ejs__default["default"].render(template, projectInfos, {
|
|
394
|
+
debug: false,
|
|
395
|
+
async: true,
|
|
396
|
+
});
|
|
397
|
+
if (await fs__default["default"].pathExists(newReadmePath)) {
|
|
398
|
+
await fs__default["default"].remove(newReadmePath);
|
|
399
|
+
}
|
|
400
|
+
await fs__default["default"].writeFile(newReadmePath, lodash.unescape(readmeContent));
|
|
401
|
+
loading.succeed('LICENSE 初始化成功!');
|
|
402
|
+
}
|
|
403
|
+
catch (error) {
|
|
404
|
+
loading.fail('LICENSE 初始化失败!');
|
|
405
|
+
console.error(error);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
async function initConfig(projectPath) {
|
|
409
|
+
try {
|
|
410
|
+
const files = ['.editorconfig', 'commitlint.config.js'];
|
|
411
|
+
files.forEach(async (file) => {
|
|
412
|
+
const templatePath = path__default["default"].join(__dirname, '../templates/', file);
|
|
413
|
+
const newPath = path__default["default"].join(projectPath, file);
|
|
414
|
+
if (await fs__default["default"].pathExists(newPath)) {
|
|
415
|
+
await fs__default["default"].remove(newPath);
|
|
416
|
+
}
|
|
417
|
+
await fs__default["default"].copyFile(templatePath, newPath);
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
catch (error) {
|
|
421
|
+
console.error(error);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
async function initGithubWorkflows(projectPath, answers) {
|
|
425
|
+
const loading = ora__default["default"]('正在初始化 Github Workflows ……').start();
|
|
426
|
+
try {
|
|
427
|
+
const { isInitSemanticRelease } = answers;
|
|
428
|
+
const files = ['.github/workflows/test.yml'];
|
|
429
|
+
const dir = path__default["default"].join(projectPath, '.github/workflows');
|
|
430
|
+
if (!await fs__default["default"].pathExists(dir)) {
|
|
431
|
+
await fs__default["default"].mkdirp(dir);
|
|
432
|
+
}
|
|
433
|
+
const releaseYml = '.github/workflows/release.yml';
|
|
434
|
+
if (isInitSemanticRelease) {
|
|
435
|
+
files.push(releaseYml);
|
|
436
|
+
}
|
|
437
|
+
else {
|
|
438
|
+
const oldReleaseYml = path__default["default"].join(projectPath, releaseYml);
|
|
439
|
+
if (await fs__default["default"].pathExists(oldReleaseYml)) {
|
|
440
|
+
await fs__default["default"].remove(oldReleaseYml);
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
const oldReleaseYml = path__default["default"].join(projectPath, '.github/release.yml');
|
|
444
|
+
if (await fs__default["default"].pathExists(oldReleaseYml)) {
|
|
445
|
+
await fs__default["default"].remove(oldReleaseYml);
|
|
446
|
+
}
|
|
447
|
+
files.forEach(async (file) => {
|
|
448
|
+
const templatePath = path__default["default"].join(__dirname, '../templates/', file);
|
|
449
|
+
const newPath = path__default["default"].join(projectPath, file);
|
|
450
|
+
if (await fs__default["default"].pathExists(newPath)) {
|
|
451
|
+
await fs__default["default"].remove(newPath);
|
|
452
|
+
}
|
|
453
|
+
await fs__default["default"].copyFile(templatePath, newPath);
|
|
454
|
+
});
|
|
455
|
+
loading.succeed('Github Workflows 初始化成功!');
|
|
456
|
+
}
|
|
457
|
+
catch (error) {
|
|
458
|
+
loading.fail('Github Workflows 初始化失败!');
|
|
459
|
+
console.error(error);
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
async function initSemanticRelease(projectPath) {
|
|
463
|
+
const loading = ora__default["default"]('正在初始化 semantic-release ……').start();
|
|
464
|
+
try {
|
|
465
|
+
const files = ['.releaserc.js'];
|
|
466
|
+
files.forEach(async (file) => {
|
|
467
|
+
const templatePath = path__default["default"].join(__dirname, '../templates/', file);
|
|
468
|
+
const newPath = path__default["default"].join(projectPath, file);
|
|
469
|
+
if (await fs__default["default"].pathExists(newPath)) {
|
|
470
|
+
await fs__default["default"].remove(newPath);
|
|
471
|
+
}
|
|
472
|
+
await fs__default["default"].copyFile(templatePath, newPath);
|
|
473
|
+
});
|
|
474
|
+
const pkgPath = path__default["default"].join(projectPath, 'package.json');
|
|
475
|
+
const pkg = await fs__default["default"].readJSON(pkgPath);
|
|
476
|
+
const devDependencies = {
|
|
477
|
+
'@semantic-release/changelog': '^6.0.1',
|
|
478
|
+
'@semantic-release/git': '^10.0.1',
|
|
479
|
+
'conventional-changelog-cli': '^2.1.1',
|
|
480
|
+
'semantic-release': '^18.0.1',
|
|
481
|
+
};
|
|
482
|
+
const pkgData = {
|
|
483
|
+
scripts: {
|
|
484
|
+
release: 'semantic-release',
|
|
485
|
+
...pkg === null || pkg === void 0 ? void 0 : pkg.scripts,
|
|
486
|
+
},
|
|
487
|
+
devDependencies: {
|
|
488
|
+
...devDependencies,
|
|
489
|
+
...pkg === null || pkg === void 0 ? void 0 : pkg.devDependencies,
|
|
490
|
+
'conventional-changelog-cmyr-config': `^${await getNpmPackageVersion('conventional-changelog-cmyr-config')}`,
|
|
491
|
+
},
|
|
492
|
+
};
|
|
493
|
+
const newPkg = Object.assign({}, pkg, pkgData);
|
|
494
|
+
await fs__default["default"].writeFile(pkgPath, JSON.stringify(newPkg, null, 2));
|
|
495
|
+
loading.succeed('semantic-release 初始化成功!');
|
|
496
|
+
}
|
|
497
|
+
catch (error) {
|
|
498
|
+
loading.fail('semantic-release 初始化失败!');
|
|
499
|
+
console.error(error);
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
async function initHusky(projectPath) {
|
|
503
|
+
var _a, _b;
|
|
504
|
+
const loading = ora__default["default"]('正在初始化 husky ……').start();
|
|
505
|
+
try {
|
|
506
|
+
const files = ['.husky/commit-msg', '.husky/pre-commit'];
|
|
507
|
+
const dir = path__default["default"].join(projectPath, '.husky');
|
|
508
|
+
if (!await fs__default["default"].pathExists(dir)) {
|
|
509
|
+
await fs__default["default"].mkdirp(dir);
|
|
510
|
+
}
|
|
511
|
+
files.forEach(async (file) => {
|
|
512
|
+
const templatePath = path__default["default"].join(__dirname, '../templates/', file);
|
|
513
|
+
const newPath = path__default["default"].join(projectPath, file);
|
|
514
|
+
if (await fs__default["default"].pathExists(newPath)) {
|
|
515
|
+
await fs__default["default"].remove(newPath);
|
|
516
|
+
}
|
|
517
|
+
await fs__default["default"].copyFile(templatePath, newPath);
|
|
518
|
+
});
|
|
519
|
+
const extnames = ['js', 'ts'];
|
|
520
|
+
const pkgPath = path__default["default"].join(projectPath, 'package.json');
|
|
521
|
+
const pkg = await fs__default["default"].readJSON(pkgPath);
|
|
522
|
+
if ((_a = pkg === null || pkg === void 0 ? void 0 : pkg.dependencies) === null || _a === void 0 ? void 0 : _a.vue) {
|
|
523
|
+
extnames.push('vue');
|
|
524
|
+
}
|
|
525
|
+
if ((_b = pkg === null || pkg === void 0 ? void 0 : pkg.dependencies) === null || _b === void 0 ? void 0 : _b.react) {
|
|
526
|
+
extnames.push('jsx', 'tsx');
|
|
527
|
+
}
|
|
528
|
+
const keyname = `*.{${extnames.join(',')}}`;
|
|
529
|
+
const devDependencies = {
|
|
530
|
+
'@commitlint/cli': '^15.0.0',
|
|
531
|
+
'@commitlint/config-conventional': '^15.0.0',
|
|
532
|
+
commitizen: '^4.2.3',
|
|
533
|
+
'cz-conventional-changelog': '^3.3.0',
|
|
534
|
+
husky: '^7.0.4',
|
|
535
|
+
'lint-staged': '^12.1.2',
|
|
536
|
+
};
|
|
537
|
+
const pkgData = {
|
|
538
|
+
scripts: {
|
|
539
|
+
commit: 'cz',
|
|
540
|
+
...pkg === null || pkg === void 0 ? void 0 : pkg.scripts,
|
|
541
|
+
prepare: 'husky install',
|
|
542
|
+
},
|
|
543
|
+
devDependencies: {
|
|
544
|
+
...devDependencies,
|
|
545
|
+
...pkg === null || pkg === void 0 ? void 0 : pkg.devDependencies,
|
|
546
|
+
},
|
|
547
|
+
husky: undefined,
|
|
548
|
+
config: {
|
|
549
|
+
commitizen: {
|
|
550
|
+
path: 'cz-conventional-changelog',
|
|
551
|
+
},
|
|
552
|
+
},
|
|
553
|
+
'lint-staged': {
|
|
554
|
+
[keyname]: [
|
|
555
|
+
'npm run lint',
|
|
556
|
+
'git add',
|
|
557
|
+
],
|
|
558
|
+
},
|
|
559
|
+
};
|
|
560
|
+
const newPkg = Object.assign({}, pkg, pkgData);
|
|
561
|
+
await fs__default["default"].writeFile(pkgPath, JSON.stringify(newPkg, null, 2));
|
|
562
|
+
loading.succeed('husky 初始化成功!');
|
|
563
|
+
}
|
|
564
|
+
catch (error) {
|
|
565
|
+
loading.fail('husky 初始化失败!');
|
|
566
|
+
console.error(error);
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
async function sortProjectJson(projectPath) {
|
|
570
|
+
try {
|
|
571
|
+
const pkgPath = path__default["default"].join(projectPath, 'package.json');
|
|
572
|
+
const pkg = await fs__default["default"].readJSON(pkgPath);
|
|
573
|
+
const pkgData = {
|
|
574
|
+
dependencies: sortKey((pkg === null || pkg === void 0 ? void 0 : pkg.dependencies) || {}),
|
|
575
|
+
devDependencies: sortKey((pkg === null || pkg === void 0 ? void 0 : pkg.devDependencies) || {}),
|
|
576
|
+
};
|
|
577
|
+
const newPkg = Object.assign({}, pkg, pkgData);
|
|
578
|
+
await fs__default["default"].writeFile(pkgPath, JSON.stringify(newPkg, null, 2));
|
|
579
|
+
}
|
|
580
|
+
catch (error) {
|
|
581
|
+
console.error(error);
|
|
582
|
+
}
|
|
583
|
+
}
|
|
346
584
|
async function getAuthorWebsiteFromGithubAPI(githubUsername) {
|
|
347
585
|
try {
|
|
348
586
|
const userData = (await axios__default["default"].get(`${GITHUB_API_URL}/users/${githubUsername}`)).data;
|
|
@@ -366,6 +604,10 @@ async function getLtsNodeVersion() {
|
|
|
366
604
|
return '';
|
|
367
605
|
}
|
|
368
606
|
}
|
|
607
|
+
async function getNpmPackageVersion(name) {
|
|
608
|
+
const version = (await asyncExec(`${PACKAGE_MANAGER} view ${name} version`)) || '';
|
|
609
|
+
return version.trim();
|
|
610
|
+
}
|
|
369
611
|
function lintMd(markdown) {
|
|
370
612
|
const rules = {
|
|
371
613
|
'no-empty-code': 0,
|
|
@@ -377,15 +619,17 @@ function lintMd(markdown) {
|
|
|
377
619
|
const fixed = core.fix(markdown, rules);
|
|
378
620
|
return fixed;
|
|
379
621
|
}
|
|
622
|
+
function sortKey(obj) {
|
|
623
|
+
const keys = Object.keys(obj).sort((a, b) => a.localeCompare(b));
|
|
624
|
+
const obj2 = {};
|
|
625
|
+
keys.forEach((e) => {
|
|
626
|
+
obj2[e] = obj[e];
|
|
627
|
+
});
|
|
628
|
+
return obj2;
|
|
629
|
+
}
|
|
380
630
|
|
|
381
631
|
module.exports = function (plop) {
|
|
382
|
-
plop.setActionType('initProject',
|
|
383
|
-
const { name, template } = answers;
|
|
384
|
-
const projectPath = path__default["default"].join(process.cwd(), name);
|
|
385
|
-
await downloadGitRepo(`CaoMeiYouRen/${template}`, projectPath);
|
|
386
|
-
await init(projectPath, answers);
|
|
387
|
-
return '- 下载项目模板成功!';
|
|
388
|
-
});
|
|
632
|
+
plop.setActionType('initProject', initProject);
|
|
389
633
|
plop.setGenerator('create', {
|
|
390
634
|
description: '草梅项目创建器',
|
|
391
635
|
async prompts(inquirer) {
|
|
@@ -484,6 +728,30 @@ module.exports = function (plop) {
|
|
|
484
728
|
return answers.isOpenSource;
|
|
485
729
|
},
|
|
486
730
|
},
|
|
731
|
+
{
|
|
732
|
+
type: 'confirm',
|
|
733
|
+
name: 'isInitSemanticRelease',
|
|
734
|
+
message: '是否初始化 semantic-release?',
|
|
735
|
+
default(answers) {
|
|
736
|
+
const { isPublishToNpm } = answers;
|
|
737
|
+
return isPublishToNpm;
|
|
738
|
+
},
|
|
739
|
+
when(answers) {
|
|
740
|
+
return answers.isOpenSource;
|
|
741
|
+
},
|
|
742
|
+
},
|
|
743
|
+
{
|
|
744
|
+
type: 'confirm',
|
|
745
|
+
name: 'isInitHusky',
|
|
746
|
+
message: '是否初始化 husky?',
|
|
747
|
+
default(answers) {
|
|
748
|
+
const { isPublishToNpm } = answers;
|
|
749
|
+
return isPublishToNpm;
|
|
750
|
+
},
|
|
751
|
+
when(answers) {
|
|
752
|
+
return answers.isOpenSource;
|
|
753
|
+
},
|
|
754
|
+
},
|
|
487
755
|
{
|
|
488
756
|
type: 'confirm',
|
|
489
757
|
name: 'isInitReadme',
|
|
@@ -497,7 +765,10 @@ module.exports = function (plop) {
|
|
|
497
765
|
type: 'confirm',
|
|
498
766
|
name: 'isInitContributing',
|
|
499
767
|
message: '是否初始化 贡献指南(CONTRIBUTING.md) ?',
|
|
500
|
-
default
|
|
768
|
+
default(answers) {
|
|
769
|
+
const { isPublishToNpm } = answers;
|
|
770
|
+
return isPublishToNpm;
|
|
771
|
+
},
|
|
501
772
|
when(answers) {
|
|
502
773
|
return answers.isOpenSource;
|
|
503
774
|
},
|
|
@@ -511,6 +782,15 @@ module.exports = function (plop) {
|
|
|
511
782
|
return answers.isOpenSource;
|
|
512
783
|
},
|
|
513
784
|
},
|
|
785
|
+
{
|
|
786
|
+
type: 'confirm',
|
|
787
|
+
name: 'isEnableAfdian',
|
|
788
|
+
message: '是否启用爱发电 ?',
|
|
789
|
+
default: false,
|
|
790
|
+
when(answers) {
|
|
791
|
+
return answers.isOpenSource;
|
|
792
|
+
},
|
|
793
|
+
},
|
|
514
794
|
];
|
|
515
795
|
return inquirer.prompt(questions);
|
|
516
796
|
},
|
package/package.json
CHANGED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# http://editorconfig.org
|
|
2
|
+
#启用编辑器配置
|
|
3
|
+
root = true
|
|
4
|
+
# 对所有文件生效
|
|
5
|
+
[*]
|
|
6
|
+
#编码方式
|
|
7
|
+
charset = utf-8
|
|
8
|
+
#缩进格式
|
|
9
|
+
indent_style = space
|
|
10
|
+
indent_size = 4
|
|
11
|
+
#换行符
|
|
12
|
+
end_of_line = lf
|
|
13
|
+
#插入最终换行符
|
|
14
|
+
insert_final_newline = true
|
|
15
|
+
#修剪尾随空格
|
|
16
|
+
trim_trailing_whitespace = true
|
|
17
|
+
# 对后缀名为 md 的文件生效
|
|
18
|
+
[*.md]
|
|
19
|
+
trim_trailing_whitespace = false
|
|
20
|
+
[*.sh]
|
|
21
|
+
#换行符
|
|
22
|
+
end_of_line = lf
|
|
23
|
+
[package.json]
|
|
24
|
+
indent_size = 2
|
|
25
|
+
[*.yml]
|
|
26
|
+
indent_size = 2
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
on:
|
|
3
|
+
push:
|
|
4
|
+
branches:
|
|
5
|
+
- master
|
|
6
|
+
jobs:
|
|
7
|
+
release:
|
|
8
|
+
name: Release
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
steps:
|
|
11
|
+
- uses: actions/checkout@v2
|
|
12
|
+
- name: Setup Node.js environment
|
|
13
|
+
uses: actions/setup-node@v2
|
|
14
|
+
with:
|
|
15
|
+
node-version: "lts/*"
|
|
16
|
+
cache: "yarn"
|
|
17
|
+
- name: Cache multiple paths
|
|
18
|
+
uses: actions/cache@v2
|
|
19
|
+
with:
|
|
20
|
+
path: |
|
|
21
|
+
~/.npm
|
|
22
|
+
~/cache
|
|
23
|
+
!~/cache/exclude
|
|
24
|
+
**/node_modules
|
|
25
|
+
key: npm-${{ runner.os }}-${{ hashFiles('package.json') }}
|
|
26
|
+
- run: yarn
|
|
27
|
+
- run: npm run lint
|
|
28
|
+
- run: npm run build
|
|
29
|
+
- env:
|
|
30
|
+
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
|
31
|
+
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
32
|
+
run: npm run release
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
name: Test
|
|
2
|
+
on: [push, pull_request]
|
|
3
|
+
jobs:
|
|
4
|
+
test:
|
|
5
|
+
name: Test
|
|
6
|
+
runs-on: ubuntu-latest
|
|
7
|
+
steps:
|
|
8
|
+
- uses: actions/checkout@v2
|
|
9
|
+
- name: Setup Node.js@lts environment
|
|
10
|
+
uses: actions/setup-node@v2
|
|
11
|
+
with:
|
|
12
|
+
node-version: "lts/*"
|
|
13
|
+
cache: "yarn"
|
|
14
|
+
- name: Cache multiple paths
|
|
15
|
+
uses: actions/cache@v2
|
|
16
|
+
with:
|
|
17
|
+
path: |
|
|
18
|
+
~/.npm
|
|
19
|
+
~/cache
|
|
20
|
+
!~/cache/exclude
|
|
21
|
+
**/node_modules
|
|
22
|
+
key: npm-${{ runner.os }}-${{ hashFiles('package.json') }}
|
|
23
|
+
- run: yarn
|
|
24
|
+
- run: npm run lint
|
|
25
|
+
- run: npm run build
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
const { name } = require('./package.json')
|
|
2
|
+
module.exports = {
|
|
3
|
+
plugins: [
|
|
4
|
+
[
|
|
5
|
+
"@semantic-release/commit-analyzer",
|
|
6
|
+
{
|
|
7
|
+
"config": "conventional-changelog-cmyr-config"
|
|
8
|
+
}
|
|
9
|
+
],
|
|
10
|
+
["@semantic-release/release-notes-generator",
|
|
11
|
+
{
|
|
12
|
+
"config": "conventional-changelog-cmyr-config"
|
|
13
|
+
}],
|
|
14
|
+
[
|
|
15
|
+
"@semantic-release/changelog",
|
|
16
|
+
{
|
|
17
|
+
"changelogFile": "CHANGELOG.md",
|
|
18
|
+
"changelogTitle": "# " + name
|
|
19
|
+
}
|
|
20
|
+
],
|
|
21
|
+
'@semantic-release/npm',
|
|
22
|
+
'@semantic-release/github',
|
|
23
|
+
[
|
|
24
|
+
"@semantic-release/git",
|
|
25
|
+
{
|
|
26
|
+
"assets": [
|
|
27
|
+
"src",
|
|
28
|
+
"CHANGELOG.md",
|
|
29
|
+
"package.json"
|
|
30
|
+
]
|
|
31
|
+
}
|
|
32
|
+
]
|
|
33
|
+
]
|
|
34
|
+
}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
1. Clone 本项目
|
|
10
10
|
|
|
11
11
|
```sh
|
|
12
|
-
git clone <%= repositoryUrl
|
|
12
|
+
git clone <%= repositoryUrl %>.git
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
2. 安装依赖
|
|
@@ -19,10 +19,9 @@
|
|
|
19
19
|
# 或 yarn
|
|
20
20
|
# 或 pnpm i
|
|
21
21
|
```
|
|
22
|
-
|
|
22
|
+
<% if (devCommand) { -%>
|
|
23
23
|
3. 运行开发环境
|
|
24
24
|
|
|
25
|
-
<% if (devCommand) { -%>
|
|
26
25
|
```sh
|
|
27
26
|
<%= devCommand %>
|
|
28
27
|
```
|
|
@@ -34,12 +33,12 @@
|
|
|
34
33
|
|
|
35
34
|
请尝试创建以下错误报告:
|
|
36
35
|
|
|
37
|
-
-
|
|
38
|
-
-
|
|
39
|
-
-
|
|
40
|
-
-
|
|
36
|
+
- *可重现*。包括重现问题的步骤。
|
|
37
|
+
- *具体的*。包括尽可能多的细节:哪个版本,什么环境等。
|
|
38
|
+
- *独特的*。不要复制现有的已打开问题。
|
|
39
|
+
- *范围仅限于单个错误*。每个报告一个错误。
|
|
41
40
|
|
|
42
|
-
|
|
41
|
+
**更好的是:提交带有修复或新功能的 Pull Requests!**
|
|
43
42
|
|
|
44
43
|
### 如何提交拉取请求
|
|
45
44
|
|
|
@@ -65,14 +64,14 @@
|
|
|
65
64
|
#若觉得修改太多也可分开提交。先 git add 一部分,执行 git cz 提交后再提交另外一部分
|
|
66
65
|
```
|
|
67
66
|
|
|
68
|
-
|
|
67
|
+
关于选项,参考 [semantic-release](https://github.com/semantic-release/semantic-release) 的文档
|
|
69
68
|
|
|
70
|
-
- 若为 BUG 修复,则选择 `fix`
|
|
71
|
-
- 若为新增功能,则选择 `feat
|
|
72
|
-
- 若为移除某些功能,则选择 `perf` 或填写 `BREAKING CHANGE`
|
|
73
|
-
|
|
69
|
+
- 若为 BUG 修复,则选择 `fix`
|
|
70
|
+
- 若为新增功能,则选择 `feat`
|
|
71
|
+
- 若为移除某些功能,则选择 `perf` 或填写 `BREAKING CHANGE`
|
|
72
|
+
- `perf` 和其他破坏性更新,若不是为了修复 BUG,原则上将拒绝该 PR
|
|
74
73
|
|
|
75
74
|
|
|
76
75
|
5. 推送到分支 ( `git push origin feat/your_feature`)
|
|
77
76
|
|
|
78
|
-
6. [打开一个新的 Pull Request](<%= repositoryUrl %>/compare?expand=1)
|
|
77
|
+
6. [打开一个新的 Pull Request](<%= repositoryUrl %>/compare?expand=1)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) <%= currentYear %> <%= authorName %>
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/templates/README.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
<% if (projectVersion && !isProjectOnNpm) { -%>
|
|
9
9
|
<img alt="Version" src="https://img.shields.io/badge/version-<%= projectVersion %>-blue.svg?cacheSeconds=2592000" />
|
|
10
10
|
<% } -%>
|
|
11
|
-
<% if (isGithubRepos) { -%>
|
|
11
|
+
<% if (isGithubRepos && isInitSemanticRelease) { -%>
|
|
12
12
|
<a href="<%= repositoryUrl %>/actions?query=workflow%3ARelease" target="_blank">
|
|
13
13
|
<img alt="GitHub Workflow Status" src="https://img.shields.io/github/workflow/status/<%= authorGithubUsername %>/<%= projectName %>/Release">
|
|
14
14
|
</a>
|
|
@@ -58,6 +58,7 @@
|
|
|
58
58
|
## 依赖要求
|
|
59
59
|
|
|
60
60
|
<% projectPrerequisites.map(({ name, value }) => { -%>
|
|
61
|
+
|
|
61
62
|
- <%= name %> <%= value %>
|
|
62
63
|
<% }) -%>
|
|
63
64
|
<% } -%>
|
|
@@ -109,6 +110,14 @@
|
|
|
109
110
|
<%= lintCommand %>
|
|
110
111
|
```
|
|
111
112
|
<% } -%>
|
|
113
|
+
<% if (commitCommand) { -%>
|
|
114
|
+
|
|
115
|
+
## Commit
|
|
116
|
+
|
|
117
|
+
```sh
|
|
118
|
+
<%= commitCommand %>
|
|
119
|
+
```
|
|
120
|
+
<% } -%>
|
|
112
121
|
|
|
113
122
|
<% if (authorName || authorGithubUsername) { -%>
|
|
114
123
|
|
|
@@ -131,10 +140,15 @@
|
|
|
131
140
|
欢迎 贡献、提问或提出新功能!<br />如有问题请查看 [issues page](<%= issuesUrl %>). <br/><%= contributingUrl ? `贡献或提出新功能可以查看[contributing guide](${contributingUrl}).` : '' %>
|
|
132
141
|
<% } -%>
|
|
133
142
|
|
|
134
|
-
##
|
|
143
|
+
## 💰支持
|
|
135
144
|
|
|
136
145
|
如果觉得这个项目有用的话请给一颗⭐️,非常感谢
|
|
146
|
+
<% if (isEnableAfdian) { -%>
|
|
137
147
|
|
|
148
|
+
<a href="https://afdian.net/@<%= authorName %>">
|
|
149
|
+
<img src="https://cdn.jsdelivr.net/gh/CaoMeiYouRen/image-hosting-01@master/images/202112181214695.png">
|
|
150
|
+
</a>
|
|
151
|
+
<% } -%>
|
|
138
152
|
<% if (licenseName && licenseUrl) { -%>
|
|
139
153
|
|
|
140
154
|
## 📝 License
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
extends: ['@commitlint/config-conventional'],
|
|
3
|
+
rules: {
|
|
4
|
+
'type-enum': [2, 'always', [
|
|
5
|
+
'feat',
|
|
6
|
+
'fix',
|
|
7
|
+
'docs',
|
|
8
|
+
'style',
|
|
9
|
+
'refactor',
|
|
10
|
+
'perf',
|
|
11
|
+
'test',
|
|
12
|
+
'build',
|
|
13
|
+
'ci',
|
|
14
|
+
'chore',
|
|
15
|
+
'revert',
|
|
16
|
+
]],
|
|
17
|
+
'subject-full-stop': [0, 'never'],
|
|
18
|
+
'subject-case': [0, 'never'],
|
|
19
|
+
},
|
|
20
|
+
}
|