@learnpack/learnpack 2.1.0 → 2.1.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.
@@ -1,172 +1,172 @@
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
+ 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,33 +1,34 @@
1
- export default {
2
- config: {
3
- port: 3000,
4
- editor: {
5
- mode: null, // [standalone, preview]
6
- agent: null, // [vscode, theia]
7
- version: null,
8
- },
9
- dirPath: './.learn',
10
- configPath: './learn.json',
11
- outputPath: './.learn/dist',
12
- publicPath: '/preview',
13
- publicUrl: null,
14
- language: 'auto',
15
- grading: 'isolated', // [isolated, incremental]
16
- exercisesPath: './', // path to the folder that contains the exercises
17
- webpackTemplate: null, // if you want webpack to use an HTML template
18
- disableGrading: false,
19
- disabledActions: [], // Possible: 'build', 'test' or 'reset'
20
- actions: [], // ⚠️ deprecated, leave empty )
21
- entries: {
22
- html: 'index.html',
23
- vanillajs: 'index.js',
24
- react: 'app.jsx',
25
- node: 'app.js',
26
- python3: 'app.py',
27
- java: 'app.java',
28
- },
29
- },
30
- address: 'http://localhost',
31
- currentExercise: null,
32
- exercises: [],
33
- }
1
+ export default {
2
+ config: {
3
+ port: 3000,
4
+ editor: {
5
+ mode: null, // [standalone, preview]
6
+ agent: null, // [vscode, gitpod, localhost]
7
+ version: null,
8
+ },
9
+ dirPath: "./.learn",
10
+ configPath: "./learn.json",
11
+ outputPath: "./.learn/dist",
12
+ publicPath: "/preview",
13
+ publicUrl: null,
14
+ language: "auto",
15
+ autoPlay: true,
16
+ grading: "isolated", // [isolated, incremental]
17
+ exercisesPath: "./", // path to the folder that contains the exercises
18
+ webpackTemplate: null, // if you want webpack to use an HTML template
19
+ disableGrading: false,
20
+ disabledActions: [], // Possible: 'build', 'test' or 'reset'
21
+ actions: [], // ⚠️ deprecated, leave empty )
22
+ entries: {
23
+ html: "index.html",
24
+ vanillajs: "index.js",
25
+ react: "app.jsx",
26
+ node: "app.js",
27
+ python3: "app.py",
28
+ java: "app.java",
29
+ },
30
+ },
31
+ address: "http://localhost",
32
+ currentExercise: null,
33
+ exercises: [],
34
+ };
@@ -30,12 +30,7 @@ const chalk = require("chalk");
30
30
  /* exercise folder name standard */
31
31
 
32
32
  const getConfigPath = () => {
33
- const possibleFileNames = [
34
- "learn.json",
35
- ".learn/learn.json",
36
- "bc.json",
37
- ".breathecode/bc.json",
38
- ];
33
+ const possibleFileNames = ["learn.json", ".learn/learn.json"];
39
34
  const config = possibleFileNames.find(file => fs.existsSync(file)) || null;
40
35
  if (config && fs.existsSync(".breathecode"))
41
36
  return { config, base: ".breathecode" };
@@ -75,7 +70,6 @@ export default async ({
75
70
 
76
71
  if (confPath) {
77
72
  const bcContent = fs.readFileSync(confPath.config);
78
-
79
73
  let hiddenBcContent = {};
80
74
  if (fs.existsSync(confPath.base + "/config.json")) {
81
75
  hiddenBcContent = fs.readFileSync(confPath.base + "/config.json");
@@ -131,7 +125,6 @@ export default async ({
131
125
 
132
126
  // auto detect agent (if possible)
133
127
  if (shell.which("gp") && configObj && configObj.config) {
134
- configObj.config.editor.agent = "gitpod";
135
128
  configObj.address = getGitpodAddress();
136
129
  configObj.config.publicUrl = `https://${
137
130
  configObj.config.port
@@ -144,8 +137,8 @@ export default async ({
144
137
  configObj.config.publicUrl = `${configObj.address}:${configObj.config.port}`;
145
138
 
146
139
  // Assign default editor mode if not set already
147
- if (configObj.config && mode !== null) {
148
- configObj.config.editor.mode = (mode as TMode) || ("vscode" as TMode);
140
+ if (configObj.config && !mode) {
141
+ configObj.config.editor.mode = mode as TMode;
149
142
  }
150
143
 
151
144
  if (configObj.config && !configObj.config.editor.mode)
@@ -160,7 +153,7 @@ configObj.config.editor.version = version;
160
153
  "https://raw.githubusercontent.com/learnpack/coding-ide/learnpack/package.json"
161
154
  );
162
155
  const packageJSON = await resp.json();
163
- configObj.config.editor.version = packageJSON.version || "1.0.72";
156
+ configObj.config.editor.version = packageJSON.version || "1.0.73";
164
157
  }
165
158
 
166
159
  if (configObj.config) {
@@ -54,6 +54,7 @@ export interface IConfig {
54
54
  exercisesPath: string;
55
55
  disableGrading: boolean; // TODO: Deprecate
56
56
  actions: Array<string>; // TODO: Deprecate
57
+ autoPlay: boolean;
57
58
  // TODO: nameExerciseValidation
58
59
  disabledActions?: Array<TConfigAction>;
59
60
  compiler: TCompiler;