@dawitworku/projectcli 0.2.1 → 0.2.2
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/README.md +8 -0
- package/package.json +2 -2
- package/src/devcontainer.js +82 -0
- package/src/index.js +234 -10
- package/src/license.js +80 -0
- package/src/settings.js +21 -3
package/README.md
CHANGED
|
@@ -19,6 +19,8 @@ We handle the complexity of calling the official CLIs for you.
|
|
|
19
19
|
- **Preflight Checks**: Warns you if you are missing required tools (e.g. `cargo`, `go`, `node`) before you start.
|
|
20
20
|
- **Remote Templates**: Clone any GitHub repository and automatically strip `.git` history for a fresh start.
|
|
21
21
|
- **CI/CD & Docker**: One-click generation of GitHub Actions workflows and Dockerfiles.
|
|
22
|
+
- **Dev Containers**: Generate `.devcontainer/devcontainer.json` for VS Code / Codespaces.
|
|
23
|
+
- **License Generator**: Add a standard `LICENSE` file (configurable default).
|
|
22
24
|
|
|
23
25
|
## 🚀 Quick Start
|
|
24
26
|
|
|
@@ -81,6 +83,12 @@ Save your preferences (like default package manager):
|
|
|
81
83
|
projectcli config
|
|
82
84
|
```
|
|
83
85
|
|
|
86
|
+
You can set defaults like:
|
|
87
|
+
|
|
88
|
+
- JS/TS package manager
|
|
89
|
+
- Author name (for LICENSE)
|
|
90
|
+
- Default license type (MIT/Apache2/ISC)
|
|
91
|
+
|
|
84
92
|
## 📦 Supported Generators (Partial List)
|
|
85
93
|
|
|
86
94
|
| Language | Frameworks / Tools |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dawitworku/projectcli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "The ultimate interactive project generator (language -> framework -> create).",
|
|
5
5
|
"author": "Dawit Worku",
|
|
6
6
|
"repository": {
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
],
|
|
33
33
|
"scripts": {
|
|
34
34
|
"start": "node bin/projectcli.js",
|
|
35
|
-
"lint": "node -c bin/projectcli.js && node -c src/index.js && node -c src/registry.js && node -c src/run.js"
|
|
35
|
+
"lint": "node -c bin/projectcli.js && node -c src/index.js && node -c src/registry.js && node -c src/run.js && node -c src/settings.js && node -c src/config.js && node -c src/devcontainer.js && node -c src/license.js"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"boxen": "^5.1.2",
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
const DEVCONTAINER_NODE = `{
|
|
2
|
+
"name": "Node.js",
|
|
3
|
+
"image": "mcr.microsoft.com/devcontainers/javascript-node:20",
|
|
4
|
+
"features": {
|
|
5
|
+
"ghcr.io/devcontainers/features/node:1": {}
|
|
6
|
+
},
|
|
7
|
+
"forwardPorts": [3000],
|
|
8
|
+
"postCreateCommand": "npm install"
|
|
9
|
+
}`;
|
|
10
|
+
|
|
11
|
+
const DEVCONTAINER_PYTHON = `{
|
|
12
|
+
"name": "Python 3",
|
|
13
|
+
"image": "mcr.microsoft.com/devcontainers/python:3.11",
|
|
14
|
+
"features": {
|
|
15
|
+
"ghcr.io/devcontainers/features/python:1": {}
|
|
16
|
+
},
|
|
17
|
+
"postCreateCommand": "pip install -r requirements.txt"
|
|
18
|
+
}`;
|
|
19
|
+
|
|
20
|
+
const DEVCONTAINER_RUST = `{
|
|
21
|
+
"name": "Rust",
|
|
22
|
+
"image": "mcr.microsoft.com/devcontainers/rust:1",
|
|
23
|
+
"features": {
|
|
24
|
+
"ghcr.io/devcontainers/features/rust:1": {}
|
|
25
|
+
},
|
|
26
|
+
"customizations": {
|
|
27
|
+
"vscode": {
|
|
28
|
+
"extensions": ["rust-lang.rust-analyzer", "tamasfe.even-better-toml"]
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"postCreateCommand": "cargo build"
|
|
32
|
+
}`;
|
|
33
|
+
|
|
34
|
+
const DEVCONTAINER_GO = `{
|
|
35
|
+
"name": "Go",
|
|
36
|
+
"image": "mcr.microsoft.com/devcontainers/go:1.21",
|
|
37
|
+
"features": {
|
|
38
|
+
"ghcr.io/devcontainers/features/go:1": {}
|
|
39
|
+
},
|
|
40
|
+
"customizations": {
|
|
41
|
+
"vscode": {
|
|
42
|
+
"extensions": ["golang.Go"]
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"postCreateCommand": "go mod download"
|
|
46
|
+
}`;
|
|
47
|
+
|
|
48
|
+
function getDevContainer(language) {
|
|
49
|
+
if (language === "JavaScript" || language === "TypeScript")
|
|
50
|
+
return DEVCONTAINER_NODE;
|
|
51
|
+
if (language === "Python") return DEVCONTAINER_PYTHON;
|
|
52
|
+
if (language === "Rust") return DEVCONTAINER_RUST;
|
|
53
|
+
if (language === "Go") return DEVCONTAINER_GO;
|
|
54
|
+
|
|
55
|
+
// Generic fallback
|
|
56
|
+
return `{
|
|
57
|
+
"name": "Default",
|
|
58
|
+
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
|
|
59
|
+
"features": {
|
|
60
|
+
"ghcr.io/devcontainers/features/common-utils:2": {}
|
|
61
|
+
}
|
|
62
|
+
}`;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function generateDevContainer(projectRoot, language) {
|
|
66
|
+
const content = getDevContainer(language);
|
|
67
|
+
return [
|
|
68
|
+
{
|
|
69
|
+
type: "mkdir",
|
|
70
|
+
path: ".devcontainer",
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
type: "writeFile",
|
|
74
|
+
path: ".devcontainer/devcontainer.json",
|
|
75
|
+
content: content,
|
|
76
|
+
},
|
|
77
|
+
];
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
module.exports = {
|
|
81
|
+
generateDevContainer,
|
|
82
|
+
};
|
package/src/index.js
CHANGED
|
@@ -31,6 +31,8 @@ const { runAdd } = require("./add");
|
|
|
31
31
|
const { checkBinaries } = require("./preflight");
|
|
32
32
|
const { gitClone, removeGitFolder } = require("./remote");
|
|
33
33
|
const { generateCI, generateDocker } = require("./cicd");
|
|
34
|
+
const { generateDevContainer } = require("./devcontainer");
|
|
35
|
+
const { generateLicense, licenseTypes } = require("./license");
|
|
34
36
|
const { getDescription } = require("./descriptions");
|
|
35
37
|
const { detectLanguage, detectPackageManager } = require("./detect");
|
|
36
38
|
const { loadConfig } = require("./config");
|
|
@@ -138,6 +140,8 @@ function parseArgs(argv) {
|
|
|
138
140
|
pm: undefined,
|
|
139
141
|
ci: false,
|
|
140
142
|
docker: false,
|
|
143
|
+
devcontainer: false,
|
|
144
|
+
license: undefined,
|
|
141
145
|
learning: false,
|
|
142
146
|
template: undefined,
|
|
143
147
|
};
|
|
@@ -156,6 +160,9 @@ function parseArgs(argv) {
|
|
|
156
160
|
else if (a === "--dry-run") out.dryRun = true;
|
|
157
161
|
else if (a === "--ci") out.ci = true;
|
|
158
162
|
else if (a === "--docker") out.docker = true;
|
|
163
|
+
else if (a === "--devcontainer") out.devcontainer = true;
|
|
164
|
+
else if (a === "--license") out.license = true;
|
|
165
|
+
else if (a === "--no-license") out.license = false;
|
|
159
166
|
else if (a === "--learning") out.learning = true;
|
|
160
167
|
else if (a.startsWith("--template="))
|
|
161
168
|
out.template = a.slice("--template=".length);
|
|
@@ -224,6 +231,9 @@ function printHelp() {
|
|
|
224
231
|
);
|
|
225
232
|
console.log(" --ci Auto-add GitHub Actions CI");
|
|
226
233
|
console.log(" --docker Auto-add Dockerfile");
|
|
234
|
+
console.log(" --devcontainer Auto-add VS Code Dev Container");
|
|
235
|
+
console.log(" --license Force-add LICENSE (uses config defaults)");
|
|
236
|
+
console.log(" --no-license Never add LICENSE");
|
|
227
237
|
console.log(" --learning Enable learning mode (shows descriptions)");
|
|
228
238
|
console.log(" --template Clone from a Git repository URL");
|
|
229
239
|
}
|
|
@@ -261,6 +271,22 @@ function printStepsPreview(steps) {
|
|
|
261
271
|
console.log("");
|
|
262
272
|
}
|
|
263
273
|
|
|
274
|
+
function filterExistingWriteFiles(steps, projectRoot) {
|
|
275
|
+
const kept = [];
|
|
276
|
+
const skipped = [];
|
|
277
|
+
for (const step of steps || []) {
|
|
278
|
+
if (step && step.type === "writeFile" && typeof step.path === "string") {
|
|
279
|
+
const target = path.resolve(projectRoot, step.path);
|
|
280
|
+
if (fs.existsSync(target)) {
|
|
281
|
+
skipped.push(step.path);
|
|
282
|
+
continue;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
kept.push(step);
|
|
286
|
+
}
|
|
287
|
+
return { kept, skipped };
|
|
288
|
+
}
|
|
289
|
+
|
|
264
290
|
function printList() {
|
|
265
291
|
for (const lang of getLanguages()) {
|
|
266
292
|
console.log(`${lang}:`);
|
|
@@ -361,6 +387,8 @@ async function main(options = {}) {
|
|
|
361
387
|
{ name: "Add Library / Dependency", value: "add" },
|
|
362
388
|
{ name: "Add GitHub Actions CI", value: "ci" },
|
|
363
389
|
{ name: "Add Dockerfile", value: "docker" },
|
|
390
|
+
{ name: "Add Dev Container (VS Code)", value: "devcontainer" },
|
|
391
|
+
{ name: "Add License", value: "license" },
|
|
364
392
|
new inquirer.Separator(),
|
|
365
393
|
{ name: "Start New Project Here", value: "new" },
|
|
366
394
|
{ name: "Exit", value: "exit" },
|
|
@@ -376,20 +404,31 @@ async function main(options = {}) {
|
|
|
376
404
|
return;
|
|
377
405
|
}
|
|
378
406
|
|
|
379
|
-
if (action === "ci" || action === "docker") {
|
|
407
|
+
if (action === "ci" || action === "docker" || action === "devcontainer") {
|
|
380
408
|
const pm = detectPackageManager(process.cwd());
|
|
381
409
|
let langArg = detected;
|
|
382
410
|
if (detected === "JavaScript/TypeScript") langArg = "JavaScript";
|
|
383
411
|
if (detected === "Java/Kotlin") langArg = "Java";
|
|
384
412
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
413
|
+
let steps = [];
|
|
414
|
+
if (action === "ci") steps = generateCI(process.cwd(), langArg, pm);
|
|
415
|
+
else if (action === "docker")
|
|
416
|
+
steps = generateDocker(process.cwd(), langArg);
|
|
417
|
+
else steps = generateDevContainer(process.cwd(), langArg);
|
|
418
|
+
|
|
419
|
+
const { kept, skipped } = filterExistingWriteFiles(
|
|
420
|
+
steps,
|
|
421
|
+
process.cwd()
|
|
422
|
+
);
|
|
389
423
|
|
|
390
|
-
if (
|
|
424
|
+
if (kept.length > 0) {
|
|
391
425
|
console.log("\nApplying changes...");
|
|
392
|
-
await runSteps(
|
|
426
|
+
await runSteps(kept, { projectRoot: process.cwd() });
|
|
427
|
+
if (skipped.length > 0) {
|
|
428
|
+
console.log(
|
|
429
|
+
chalk.dim(`Skipped existing files: ${skipped.join(", ")}`)
|
|
430
|
+
);
|
|
431
|
+
}
|
|
393
432
|
console.log(chalk.green("Done!"));
|
|
394
433
|
} else {
|
|
395
434
|
console.log(
|
|
@@ -401,6 +440,40 @@ async function main(options = {}) {
|
|
|
401
440
|
return;
|
|
402
441
|
}
|
|
403
442
|
|
|
443
|
+
if (action === "license") {
|
|
444
|
+
const { type, author } = await prompt([
|
|
445
|
+
{
|
|
446
|
+
type: "list",
|
|
447
|
+
name: "type",
|
|
448
|
+
message: "Choose a license:",
|
|
449
|
+
choices: licenseTypes,
|
|
450
|
+
},
|
|
451
|
+
{
|
|
452
|
+
type: "input",
|
|
453
|
+
name: "author",
|
|
454
|
+
message: "Author Name:",
|
|
455
|
+
default: userConfig.author || "The Authors",
|
|
456
|
+
},
|
|
457
|
+
]);
|
|
458
|
+
const steps = generateLicense(process.cwd(), type, author);
|
|
459
|
+
const { kept, skipped } = filterExistingWriteFiles(
|
|
460
|
+
steps,
|
|
461
|
+
process.cwd()
|
|
462
|
+
);
|
|
463
|
+
if (kept.length === 0) {
|
|
464
|
+
console.log(chalk.dim("Nothing to do (LICENSE already exists)."));
|
|
465
|
+
return;
|
|
466
|
+
}
|
|
467
|
+
await runSteps(kept, { projectRoot: process.cwd() });
|
|
468
|
+
if (skipped.length > 0) {
|
|
469
|
+
console.log(
|
|
470
|
+
chalk.dim(`Skipped existing files: ${skipped.join(", ")}`)
|
|
471
|
+
);
|
|
472
|
+
}
|
|
473
|
+
console.log(chalk.green("Done!"));
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
476
|
+
|
|
404
477
|
// If 'new', fall through to normal wizard
|
|
405
478
|
}
|
|
406
479
|
}
|
|
@@ -445,6 +518,17 @@ async function main(options = {}) {
|
|
|
445
518
|
args.learning = true;
|
|
446
519
|
}
|
|
447
520
|
|
|
521
|
+
const defaultLicenseType =
|
|
522
|
+
typeof userConfig.defaultLicense === "string" &&
|
|
523
|
+
licenseTypes.includes(userConfig.defaultLicense)
|
|
524
|
+
? userConfig.defaultLicense
|
|
525
|
+
: null;
|
|
526
|
+
|
|
527
|
+
const defaultAuthor =
|
|
528
|
+
typeof userConfig.author === "string" && userConfig.author.trim()
|
|
529
|
+
? userConfig.author.trim()
|
|
530
|
+
: "The Authors";
|
|
531
|
+
|
|
448
532
|
const state = {
|
|
449
533
|
template: args.template || undefined,
|
|
450
534
|
language:
|
|
@@ -737,6 +821,104 @@ async function main(options = {}) {
|
|
|
737
821
|
// Remove .git to make it a fresh project
|
|
738
822
|
removeGitFolder(projectRoot);
|
|
739
823
|
|
|
824
|
+
// Optional extras after cloning
|
|
825
|
+
const detectedTemplate = detectLanguage(projectRoot);
|
|
826
|
+
const pmTemplate = detectPackageManager(projectRoot);
|
|
827
|
+
|
|
828
|
+
let langArg = detectedTemplate;
|
|
829
|
+
if (detectedTemplate === "JavaScript/TypeScript")
|
|
830
|
+
langArg = "JavaScript";
|
|
831
|
+
if (detectedTemplate === "Java/Kotlin") langArg = "Java";
|
|
832
|
+
|
|
833
|
+
let wantCi = Boolean(args.ci);
|
|
834
|
+
let wantDocker = Boolean(args.docker);
|
|
835
|
+
let wantDevContainer = Boolean(args.devcontainer);
|
|
836
|
+
let wantLicense =
|
|
837
|
+
typeof args.license === "boolean"
|
|
838
|
+
? args.license
|
|
839
|
+
: defaultLicenseType !== null;
|
|
840
|
+
|
|
841
|
+
if (!args.yes) {
|
|
842
|
+
const licenseLabel =
|
|
843
|
+
defaultLicenseType !== null
|
|
844
|
+
? `LICENSE (${defaultLicenseType})`
|
|
845
|
+
: "LICENSE (skip)";
|
|
846
|
+
|
|
847
|
+
const { extras } = await prompt([
|
|
848
|
+
{
|
|
849
|
+
type: "checkbox",
|
|
850
|
+
name: "extras",
|
|
851
|
+
message: "Extras to apply after clone:",
|
|
852
|
+
choices: [
|
|
853
|
+
{ name: "GitHub Actions CI", value: "ci", checked: wantCi },
|
|
854
|
+
{
|
|
855
|
+
name: "Dockerfile",
|
|
856
|
+
value: "docker",
|
|
857
|
+
checked: wantDocker,
|
|
858
|
+
},
|
|
859
|
+
{
|
|
860
|
+
name: "Dev Container (VS Code)",
|
|
861
|
+
value: "devcontainer",
|
|
862
|
+
checked: wantDevContainer,
|
|
863
|
+
},
|
|
864
|
+
{
|
|
865
|
+
name: licenseLabel,
|
|
866
|
+
value: "license",
|
|
867
|
+
checked: wantLicense,
|
|
868
|
+
disabled:
|
|
869
|
+
defaultLicenseType === null
|
|
870
|
+
? "Configure a default license in 'projectcli config'"
|
|
871
|
+
: false,
|
|
872
|
+
},
|
|
873
|
+
],
|
|
874
|
+
},
|
|
875
|
+
]);
|
|
876
|
+
if (extras) {
|
|
877
|
+
wantCi = extras.includes("ci");
|
|
878
|
+
wantDocker = extras.includes("docker");
|
|
879
|
+
wantDevContainer = extras.includes("devcontainer");
|
|
880
|
+
wantLicense = extras.includes("license");
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
const extraSteps = [];
|
|
885
|
+
if (wantCi)
|
|
886
|
+
extraSteps.push(...generateCI(projectRoot, langArg, pmTemplate));
|
|
887
|
+
if (wantDocker)
|
|
888
|
+
extraSteps.push(...generateDocker(projectRoot, langArg));
|
|
889
|
+
if (wantDevContainer) {
|
|
890
|
+
extraSteps.push(...generateDevContainer(projectRoot, langArg));
|
|
891
|
+
}
|
|
892
|
+
if (wantLicense && defaultLicenseType !== null) {
|
|
893
|
+
extraSteps.push(
|
|
894
|
+
...generateLicense(projectRoot, defaultLicenseType, defaultAuthor)
|
|
895
|
+
);
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
if (wantLicense && defaultLicenseType === null) {
|
|
899
|
+
console.log(
|
|
900
|
+
chalk.dim(
|
|
901
|
+
"Skipping LICENSE (no default license configured; run 'projectcli config')."
|
|
902
|
+
)
|
|
903
|
+
);
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
if (extraSteps.length > 0) {
|
|
907
|
+
const { kept, skipped } = filterExistingWriteFiles(
|
|
908
|
+
extraSteps,
|
|
909
|
+
projectRoot
|
|
910
|
+
);
|
|
911
|
+
if (kept.length > 0) {
|
|
912
|
+
console.log(chalk.dim("\nApplying extras..."));
|
|
913
|
+
await runSteps(kept, { projectRoot });
|
|
914
|
+
}
|
|
915
|
+
if (skipped.length > 0) {
|
|
916
|
+
console.log(
|
|
917
|
+
chalk.dim(`Skipped existing files: ${skipped.join(", ")}`)
|
|
918
|
+
);
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
|
|
740
922
|
console.log(
|
|
741
923
|
chalk.green(`\nSuccess! Created project at ${projectRoot}`)
|
|
742
924
|
);
|
|
@@ -921,10 +1103,15 @@ async function main(options = {}) {
|
|
|
921
1103
|
}
|
|
922
1104
|
}
|
|
923
1105
|
|
|
924
|
-
// CI/CD & Docker
|
|
1106
|
+
// CI/CD & Docker & DevContainer
|
|
925
1107
|
if (!args.dryRun) {
|
|
926
1108
|
let wantCi = args.ci;
|
|
927
1109
|
let wantDocker = args.docker;
|
|
1110
|
+
let wantDevContainer = Boolean(args.devcontainer);
|
|
1111
|
+
let wantLicense =
|
|
1112
|
+
typeof args.license === "boolean"
|
|
1113
|
+
? args.license
|
|
1114
|
+
: defaultLicenseType !== null;
|
|
928
1115
|
|
|
929
1116
|
if (!args.yes) {
|
|
930
1117
|
const { extras } = await prompt([
|
|
@@ -935,12 +1122,31 @@ async function main(options = {}) {
|
|
|
935
1122
|
choices: [
|
|
936
1123
|
{ name: "GitHub Actions CI", value: "ci", checked: wantCi },
|
|
937
1124
|
{ name: "Dockerfile", value: "docker", checked: wantDocker },
|
|
1125
|
+
{
|
|
1126
|
+
name: "Dev Container (VS Code)",
|
|
1127
|
+
value: "devcontainer",
|
|
1128
|
+
checked: wantDevContainer,
|
|
1129
|
+
},
|
|
1130
|
+
{
|
|
1131
|
+
name:
|
|
1132
|
+
defaultLicenseType !== null
|
|
1133
|
+
? `LICENSE (${defaultLicenseType})`
|
|
1134
|
+
: "LICENSE (skip)",
|
|
1135
|
+
value: "license",
|
|
1136
|
+
checked: wantLicense,
|
|
1137
|
+
disabled:
|
|
1138
|
+
defaultLicenseType === null
|
|
1139
|
+
? "Configure a default license in 'projectcli config'"
|
|
1140
|
+
: false,
|
|
1141
|
+
},
|
|
938
1142
|
],
|
|
939
1143
|
},
|
|
940
1144
|
]);
|
|
941
1145
|
if (extras) {
|
|
942
1146
|
wantCi = extras.includes("ci");
|
|
943
1147
|
wantDocker = extras.includes("docker");
|
|
1148
|
+
wantDevContainer = extras.includes("devcontainer");
|
|
1149
|
+
wantLicense = extras.includes("license");
|
|
944
1150
|
}
|
|
945
1151
|
}
|
|
946
1152
|
|
|
@@ -951,10 +1157,28 @@ async function main(options = {}) {
|
|
|
951
1157
|
if (wantDocker) {
|
|
952
1158
|
extraSteps.push(...generateDocker(projectRoot, state.language));
|
|
953
1159
|
}
|
|
1160
|
+
if (wantDevContainer) {
|
|
1161
|
+
extraSteps.push(...generateDevContainer(projectRoot, state.language));
|
|
1162
|
+
}
|
|
1163
|
+
if (wantLicense && defaultLicenseType !== null) {
|
|
1164
|
+
extraSteps.push(
|
|
1165
|
+
...generateLicense(projectRoot, defaultLicenseType, defaultAuthor)
|
|
1166
|
+
);
|
|
1167
|
+
}
|
|
1168
|
+
|
|
1169
|
+
const { kept, skipped } = filterExistingWriteFiles(
|
|
1170
|
+
extraSteps,
|
|
1171
|
+
projectRoot
|
|
1172
|
+
);
|
|
954
1173
|
|
|
955
|
-
if (
|
|
1174
|
+
if (kept.length > 0) {
|
|
956
1175
|
console.log("Adding extras...");
|
|
957
|
-
await runSteps(
|
|
1176
|
+
await runSteps(kept, { projectRoot });
|
|
1177
|
+
}
|
|
1178
|
+
if (skipped.length > 0) {
|
|
1179
|
+
console.log(
|
|
1180
|
+
chalk.dim(`Skipped existing files: ${skipped.join(", ")}`)
|
|
1181
|
+
);
|
|
958
1182
|
}
|
|
959
1183
|
}
|
|
960
1184
|
|
package/src/license.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
const licenses = {
|
|
2
|
+
MIT: (year, author) => `MIT License
|
|
3
|
+
|
|
4
|
+
Copyright (c) ${year} ${author}
|
|
5
|
+
|
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
in the Software without restriction, including without limitation the rights
|
|
9
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
furnished to do so, subject to the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
+
SOFTWARE.
|
|
23
|
+
`,
|
|
24
|
+
Apache2: (year, author) => ` Apache License
|
|
25
|
+
Version 2.0, January 2004
|
|
26
|
+
http://www.apache.org/licenses/
|
|
27
|
+
|
|
28
|
+
Copyright ${year} ${author}
|
|
29
|
+
|
|
30
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
31
|
+
you may not use this file except in compliance with the License.
|
|
32
|
+
You may obtain a copy of the License at
|
|
33
|
+
|
|
34
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
35
|
+
|
|
36
|
+
Unless required by applicable law or agreed to in writing, software
|
|
37
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
38
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
39
|
+
See the License for the specific language governing permissions and
|
|
40
|
+
limitations under the License.
|
|
41
|
+
`,
|
|
42
|
+
ISC: (year, author) => `ISC License
|
|
43
|
+
|
|
44
|
+
Copyright (c) ${year}, ${author}
|
|
45
|
+
|
|
46
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
47
|
+
purpose with or without fee is hereby granted, provided that the above
|
|
48
|
+
copyright notice and this permission notice appear in all copies.
|
|
49
|
+
|
|
50
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
51
|
+
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
52
|
+
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
53
|
+
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
54
|
+
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
55
|
+
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
56
|
+
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
57
|
+
`,
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
function getLicense(type, author) {
|
|
61
|
+
const year = new Date().getFullYear();
|
|
62
|
+
const template = licenses[type] || licenses.MIT;
|
|
63
|
+
return template(year, author || "The Authors");
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function generateLicense(projectRoot, type, author) {
|
|
67
|
+
return [
|
|
68
|
+
{
|
|
69
|
+
type: "writeFile",
|
|
70
|
+
path: "LICENSE",
|
|
71
|
+
content: getLicense(type, author),
|
|
72
|
+
},
|
|
73
|
+
];
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
module.exports = {
|
|
77
|
+
getLicense,
|
|
78
|
+
generateLicense,
|
|
79
|
+
licenseTypes: ["MIT", "Apache2", "ISC"],
|
|
80
|
+
};
|
package/src/settings.js
CHANGED
|
@@ -14,7 +14,7 @@ async function runConfig({ prompt }) {
|
|
|
14
14
|
message: "Default Package Manager (for JS/TS):",
|
|
15
15
|
choices: [
|
|
16
16
|
{ name: "None (Always ask)", value: null },
|
|
17
|
-
|
|
17
|
+
inquirerSeparator(),
|
|
18
18
|
{ name: "npm", value: "npm" },
|
|
19
19
|
{ name: "pnpm", value: "pnpm" },
|
|
20
20
|
{ name: "yarn", value: "yarn" },
|
|
@@ -22,6 +22,26 @@ async function runConfig({ prompt }) {
|
|
|
22
22
|
],
|
|
23
23
|
default: config.packageManager || null,
|
|
24
24
|
},
|
|
25
|
+
{
|
|
26
|
+
type: "input",
|
|
27
|
+
name: "author",
|
|
28
|
+
message: "Default Author Name (for LICENSE):",
|
|
29
|
+
default: config.author || "The Authors",
|
|
30
|
+
filter: (v) => String(v || "").trim(),
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
type: "list",
|
|
34
|
+
name: "defaultLicense",
|
|
35
|
+
message: "Default License Type:",
|
|
36
|
+
choices: [
|
|
37
|
+
{ name: "None", value: null },
|
|
38
|
+
inquirerSeparator(),
|
|
39
|
+
{ name: "MIT", value: "MIT" },
|
|
40
|
+
{ name: "Apache-2.0", value: "Apache2" },
|
|
41
|
+
{ name: "ISC", value: "ISC" },
|
|
42
|
+
],
|
|
43
|
+
default: config.defaultLicense || "MIT",
|
|
44
|
+
},
|
|
25
45
|
{
|
|
26
46
|
type: "confirm",
|
|
27
47
|
name: "learningMode",
|
|
@@ -37,8 +57,6 @@ async function runConfig({ prompt }) {
|
|
|
37
57
|
// Helper for pure inquirer usage if needed,
|
|
38
58
|
// though index.js passes the prompt instance.
|
|
39
59
|
function inquirerSeparator() {
|
|
40
|
-
// We can't easily import inquirer.Separator here without adding dependency
|
|
41
|
-
// or passing it in. Let's just use a string for now or skip it.
|
|
42
60
|
return { name: "──────────────", disabled: true };
|
|
43
61
|
}
|
|
44
62
|
|