@learnpack/learnpack 2.1.23 → 2.1.24

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,172 +1,170 @@
1
- import { flags } from "@oclif/command";
2
- import BaseCommand from "../utils/BaseCommand";
3
-
4
- // eslint-disable-next-line
5
- import * as fs from "fs-extra";
6
- import * as prompts from "prompts";
7
- import cli from "cli-ux";
8
- import * as eta from "eta";
9
-
10
- import Console from "../utils/console";
11
- import { ValidationError } from "../utils/errors";
12
- import defaults from "../managers/config/defaults";
13
-
14
- import * as path from "path";
15
-
16
- class InitComand extends BaseCommand {
17
- static description =
18
- "Create a new learning package: Book, Tutorial or Exercise";
19
-
20
- static flags = {
21
- ...BaseCommand.flags,
22
- grading: flags.help({ char: "h" }),
23
- };
24
-
25
- async run() {
26
- const { flags } = this.parse(InitComand);
27
-
28
- // if the folder/file .learn or .breathecode aleady exists
29
- await alreadyInitialized();
30
-
31
- const choices = await prompts([
32
- {
33
- type: "select",
34
- name: "grading",
35
- message: "Is the auto-grading going to be isolated or incremental?",
36
- choices: [
37
- {
38
- title: "Incremental: Build on top of each other like a tutorial",
39
- value: "incremental",
40
- },
41
- { title: "Isolated: Small separated exercises", value: "isolated" },
42
- {
43
- title: "No grading: No feedback or testing whatsoever",
44
- value: null,
45
- },
46
- ],
47
- },
48
- {
49
- type: "text",
50
- name: "title",
51
- initial: "My Interactive Tutorial",
52
- message: "Title for your tutorial? Press enter to leave as it is",
53
- },
54
- {
55
- type: "text",
56
- name: "description",
57
- initial: "",
58
- message: "Description for your tutorial? Press enter to leave blank",
59
- },
60
- {
61
- type: "select",
62
- name: "difficulty",
63
- message: "How difficulty will be to complete the tutorial?",
64
- choices: [
65
- { title: "Begginer (no previous experience)", value: "beginner" },
66
- { title: "Easy (just a bit of experience required)", value: "easy" },
67
- {
68
- title: "Intermediate (you need experience)",
69
- value: "intermediate",
70
- },
71
- { title: "Hard (master the topic)", value: "hard" },
72
- ],
73
- },
74
- {
75
- type: "text",
76
- name: "duration",
77
- initial: "1",
78
- message: "How many hours avg it takes to complete (number)?",
79
- validate: (value: string) => {
80
- const n = Math.floor(Number(value));
81
- return (
82
- n !== Number.POSITIVE_INFINITY && String(n) === value && n >= 0
83
- );
84
- },
85
- },
86
- ]);
87
-
88
- const packageInfo = {
89
- ...defaults.config,
90
- grading: choices.grading,
91
- difficulty: choices.difficulty,
92
- duration: parseInt(choices.duration),
93
- description: choices.description,
94
- title: choices.title,
95
- slug: choices.title
96
- .toLowerCase()
97
- .replace(/ /g, "-")
98
- .replace(/[^\w-]+/g, ""),
99
- };
100
-
101
- cli.action.start("Initializing package");
102
-
103
- const languages = ["en", "es"];
104
-
105
- const templatesDir = path.resolve(
106
- __dirname,
107
- "../../src/utils/templates/" + choices.grading || "no-grading"
108
- );
109
- if (!fs.existsSync(templatesDir))
110
- throw ValidationError(`Template ${templatesDir} does not exists`);
111
- await fs.copySync(templatesDir, "./");
112
-
113
- // Creating README files
114
- // eslint-disable-next-line
115
- languages.forEach((language) => {
116
- const readmeFilename = `README${language !== "en" ? `.${language}` : ""}`;
117
- fs.writeFileSync(
118
- `./${readmeFilename}.md`,
119
- eta.render(
120
- fs.readFileSync(
121
- path.resolve(__dirname, `${templatesDir}/${readmeFilename}.ejs`),
122
- "utf-8"
123
- ),
124
- packageInfo
125
- )
126
- );
127
- if (fs.existsSync(`./${readmeFilename}.ejs`))
128
- fs.removeSync(`./${readmeFilename}.ejs`);
129
- });
130
-
131
- if (!fs.existsSync("./.gitignore"))
132
- fs.copyFile(
133
- path.resolve(__dirname, "../../src/utils/templates/gitignore.txt"),
134
- "./.gitignore"
135
- );
136
- fs.writeFileSync("./learn.json", JSON.stringify(packageInfo, null, 2));
137
-
138
- cli.action.stop();
139
- Console.success(`😋 Package initialized successfully`);
140
- Console.help(
141
- `Start the exercises by running the following command on your terminal: $ learnpack start`
142
- );
143
- }
144
- }
145
-
146
- const alreadyInitialized = () =>
147
- new Promise((resolve, reject) => {
148
- fs.readdir("./", function (err: any, files: any) {
149
- files = files.filter((f: any) =>
150
- [".learn", "learn.json", "bc.json", ".breathecode"].includes(f)
151
- );
152
- if (err) {
153
- reject(ValidationError(err.message));
154
- throw ValidationError(err.message);
155
- } else if (files.length > 0) {
156
- reject(
157
- ValidationError(
158
- "It seems the package is already initialized because we've found the following files: " +
159
- files.join(",")
160
- )
161
- );
162
- throw ValidationError(
163
- "It seems the package is already initialized because we've found the following files: " +
164
- files.join(",")
165
- );
166
- }
167
-
168
- resolve(false);
169
- });
170
- });
171
-
172
- export default InitComand;
1
+ import { flags } from "@oclif/command";
2
+ import BaseCommand from "../utils/BaseCommand";
3
+
4
+ // eslint-disable-next-line
5
+ import * as fs from "fs-extra";
6
+ import * as prompts from "prompts";
7
+ import cli from "cli-ux";
8
+ import * as eta from "eta";
9
+
10
+ import Console from "../utils/console";
11
+ import { ValidationError } from "../utils/errors";
12
+
13
+ import * as path from "path";
14
+
15
+ class InitComand extends BaseCommand {
16
+ static description =
17
+ "Create a new learning package: Book, Tutorial or Exercise";
18
+
19
+ static flags = {
20
+ ...BaseCommand.flags,
21
+ grading: flags.help({ char: "h" }),
22
+ };
23
+
24
+ async run() {
25
+ const { flags } = this.parse(InitComand);
26
+
27
+ // if the folder/file .learn or .breathecode aleady exists
28
+ await alreadyInitialized();
29
+
30
+ const choices = await prompts([
31
+ {
32
+ type: "select",
33
+ name: "grading",
34
+ message: "Is the auto-grading going to be isolated or incremental?",
35
+ choices: [
36
+ {
37
+ title: "Incremental: Build on top of each other like a tutorial",
38
+ value: "incremental",
39
+ },
40
+ { title: "Isolated: Small separated exercises", value: "isolated" },
41
+ {
42
+ title: "No grading: No feedback or testing whatsoever",
43
+ value: null,
44
+ },
45
+ ],
46
+ },
47
+ {
48
+ type: "text",
49
+ name: "title",
50
+ initial: "My Interactive Tutorial",
51
+ message: "Title for your tutorial? Press enter to leave as it is",
52
+ },
53
+ {
54
+ type: "text",
55
+ name: "description",
56
+ initial: "",
57
+ message: "Description for your tutorial? Press enter to leave blank",
58
+ },
59
+ {
60
+ type: "select",
61
+ name: "difficulty",
62
+ message: "How difficulty will be to complete the tutorial?",
63
+ choices: [
64
+ { title: "Begginer (no previous experience)", value: "beginner" },
65
+ { title: "Easy (just a bit of experience required)", value: "easy" },
66
+ {
67
+ title: "Intermediate (you need experience)",
68
+ value: "intermediate",
69
+ },
70
+ { title: "Hard (master the topic)", value: "hard" },
71
+ ],
72
+ },
73
+ {
74
+ type: "text",
75
+ name: "duration",
76
+ initial: "1",
77
+ message: "How many hours avg it takes to complete (number)?",
78
+ validate: (value: string) => {
79
+ const n = Math.floor(Number(value));
80
+ return (
81
+ n !== Number.POSITIVE_INFINITY && String(n) === value && n >= 0
82
+ );
83
+ },
84
+ },
85
+ ]);
86
+
87
+ const packageInfo = {
88
+ grading: choices.grading,
89
+ difficulty: choices.difficulty,
90
+ duration: parseInt(choices.duration),
91
+ description: choices.description,
92
+ title: choices.title,
93
+ slug: choices.title
94
+ .toLowerCase()
95
+ .replace(/ /g, "-")
96
+ .replace(/[^\w-]+/g, ""),
97
+ };
98
+
99
+ cli.action.start("Initializing package");
100
+
101
+ const languages = ["en", "es"];
102
+
103
+ const templatesDir = path.resolve(
104
+ __dirname,
105
+ "../../src/utils/templates/" + choices.grading || "no-grading"
106
+ );
107
+ if (!fs.existsSync(templatesDir))
108
+ throw ValidationError(`Template ${templatesDir} does not exists`);
109
+ await fs.copySync(templatesDir, "./");
110
+
111
+ // Creating README files
112
+ // eslint-disable-next-line
113
+ languages.forEach((language) => {
114
+ const readmeFilename = `README${language !== "en" ? `.${language}` : ""}`;
115
+ fs.writeFileSync(
116
+ `./${readmeFilename}.md`,
117
+ eta.render(
118
+ fs.readFileSync(
119
+ path.resolve(__dirname, `${templatesDir}/${readmeFilename}.ejs`),
120
+ "utf-8"
121
+ ),
122
+ packageInfo
123
+ )
124
+ );
125
+ if (fs.existsSync(`./${readmeFilename}.ejs`))
126
+ fs.removeSync(`./${readmeFilename}.ejs`);
127
+ });
128
+
129
+ if (!fs.existsSync("./.gitignore"))
130
+ fs.copyFile(
131
+ path.resolve(__dirname, "../../src/utils/templates/gitignore.txt"),
132
+ "./.gitignore"
133
+ );
134
+ fs.writeFileSync("./learn.json", JSON.stringify(packageInfo, null, 2));
135
+
136
+ cli.action.stop();
137
+ Console.success(`😋 Package initialized successfully`);
138
+ Console.help(
139
+ `Start the exercises by running the following command on your terminal: $ learnpack start`
140
+ );
141
+ }
142
+ }
143
+
144
+ const alreadyInitialized = () =>
145
+ new Promise((resolve, reject) => {
146
+ fs.readdir("./", function (err: any, files: any) {
147
+ files = files.filter((f: any) =>
148
+ [".learn", "learn.json", "bc.json", ".breathecode"].includes(f)
149
+ );
150
+ if (err) {
151
+ reject(ValidationError(err.message));
152
+ throw ValidationError(err.message);
153
+ } else if (files.length > 0) {
154
+ reject(
155
+ ValidationError(
156
+ "It seems the package is already initialized because we've found the following files: " +
157
+ files.join(",")
158
+ )
159
+ );
160
+ throw ValidationError(
161
+ "It seems the package is already initialized because we've found the following files: " +
162
+ files.join(",")
163
+ );
164
+ }
165
+
166
+ resolve(false);
167
+ });
168
+ });
169
+
170
+ export default InitComand;