@learnpack/learnpack 2.1.26 → 2.1.28
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 +10 -10
- package/lib/commands/start.js +15 -4
- package/lib/managers/file.d.ts +1 -0
- package/lib/managers/file.js +8 -1
- package/lib/managers/server/routes.js +48 -14
- package/lib/managers/session.d.ts +1 -1
- package/lib/managers/session.js +39 -12
- package/lib/managers/socket.d.ts +1 -1
- package/lib/managers/socket.js +57 -43
- package/lib/models/action.d.ts +1 -1
- package/lib/models/config.d.ts +1 -1
- package/lib/models/exercise-obj.d.ts +3 -0
- package/lib/models/session.d.ts +4 -1
- package/lib/models/socket.d.ts +7 -6
- package/lib/models/status.d.ts +1 -1
- package/lib/utils/api.d.ts +2 -0
- package/lib/utils/api.js +51 -6
- package/oclif.manifest.json +1 -1
- package/package.json +3 -1
- package/src/commands/audit.ts +113 -113
- package/src/commands/clean.ts +10 -10
- package/src/commands/download.ts +18 -18
- package/src/commands/init.ts +39 -39
- package/src/commands/login.ts +13 -13
- package/src/commands/logout.ts +9 -9
- package/src/commands/publish.ts +25 -25
- package/src/commands/start.ts +101 -75
- package/src/commands/test.ts +34 -34
- package/src/managers/config/allowed_files.ts +2 -2
- package/src/managers/config/defaults.ts +2 -2
- package/src/managers/config/exercise.ts +79 -79
- package/src/managers/config/index.ts +145 -145
- package/src/managers/file.ts +74 -65
- package/src/managers/server/index.ts +32 -31
- package/src/managers/server/routes.ts +139 -90
- package/src/managers/session.ts +53 -24
- package/src/managers/socket.ts +92 -79
- package/src/models/action.ts +8 -1
- package/src/models/config-manager.ts +2 -2
- package/src/models/config.ts +7 -2
- package/src/models/exercise-obj.ts +6 -3
- package/src/models/plugin-config.ts +2 -2
- package/src/models/session.ts +5 -2
- package/src/models/socket.ts +12 -6
- package/src/models/status.ts +15 -14
- package/src/plugin/command/compile.ts +10 -10
- package/src/plugin/command/test.ts +14 -14
- package/src/plugin/index.ts +5 -5
- package/src/plugin/plugin.ts +26 -26
- package/src/plugin/utils.ts +23 -23
- package/src/utils/BaseCommand.ts +16 -16
- package/src/utils/api.ts +143 -91
- package/src/utils/audit.ts +93 -96
- package/src/utils/exercisesQueue.ts +15 -15
- package/src/utils/fileQueue.ts +85 -85
- package/src/utils/watcher.ts +14 -14
package/src/commands/start.ts
CHANGED
@@ -1,19 +1,24 @@
|
|
1
1
|
// import path from "path";
|
2
|
-
import { flags } from "@oclif/command"
|
3
|
-
import SessionCommand from "../utils/SessionCommand";
|
4
|
-
import Console from "../utils/console";
|
5
|
-
import socket from "../managers/socket";
|
6
|
-
import queue from "../utils/fileQueue";
|
7
|
-
import { decompress, downloadEditor } from "../managers/file";
|
8
|
-
import { prioritizeHTMLFile } from "../utils/misc";
|
2
|
+
import { flags } from "@oclif/command"
|
9
3
|
|
10
|
-
import
|
4
|
+
import SessionCommand from "../utils/SessionCommand"
|
5
|
+
import Console from "../utils/console"
|
6
|
+
import socket from "../managers/socket"
|
7
|
+
import queue from "../utils/fileQueue"
|
8
|
+
import {
|
9
|
+
decompress,
|
10
|
+
downloadEditor,
|
11
|
+
checkIfDirectoryExists,
|
12
|
+
} from "../managers/file"
|
13
|
+
import { prioritizeHTMLFile } from "../utils/misc"
|
11
14
|
|
12
|
-
import
|
13
|
-
|
15
|
+
import createServer from "../managers/server"
|
16
|
+
|
17
|
+
import { IGitpodData } from "../models/gitpod-data"
|
18
|
+
import { IExercise, IExerciseData } from "../models/exercise-obj"
|
14
19
|
|
15
20
|
export default class StartCommand extends SessionCommand {
|
16
|
-
static description = "Runs a small server with all the exercise instructions"
|
21
|
+
static description = "Runs a small server with all the exercise instructions"
|
17
22
|
|
18
23
|
static flags = {
|
19
24
|
...SessionCommand.flags,
|
@@ -50,25 +55,25 @@ export default class StartCommand extends SessionCommand {
|
|
50
55
|
description: "debugger mode for more verbage",
|
51
56
|
default: false,
|
52
57
|
}),
|
53
|
-
}
|
58
|
+
}
|
54
59
|
|
55
60
|
// 🛑 IMPORTANT
|
56
61
|
// Every command that will use the configManager needs this init method
|
57
62
|
async init() {
|
58
|
-
const { flags } = this.parse(StartCommand)
|
59
|
-
await this.initSession(flags)
|
63
|
+
const { flags } = this.parse(StartCommand)
|
64
|
+
await this.initSession(flags)
|
60
65
|
}
|
61
66
|
|
62
67
|
async run() {
|
63
68
|
// get configuration object
|
64
|
-
const configObject = this.configManager?.get()
|
65
|
-
const config = configObject?.config
|
69
|
+
const configObject = this.configManager?.get()
|
70
|
+
const config = configObject?.config
|
66
71
|
|
67
72
|
if (configObject) {
|
68
|
-
const { config } = configObject
|
73
|
+
const { config } = configObject
|
69
74
|
|
70
75
|
// build exerises
|
71
|
-
this.configManager?.buildIndex()
|
76
|
+
this.configManager?.buildIndex()
|
72
77
|
|
73
78
|
Console.debug(
|
74
79
|
`Grading: ${config?.grading} ${
|
@@ -78,19 +83,25 @@ export default class StartCommand extends SessionCommand {
|
|
78
83
|
configObject?.exercises.length :
|
79
84
|
0
|
80
85
|
} exercises found`
|
81
|
-
)
|
86
|
+
)
|
87
|
+
|
88
|
+
const appAlreadyExists = checkIfDirectoryExists(
|
89
|
+
`${config?.dirPath}/_app`
|
90
|
+
)
|
82
91
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
92
|
+
if (!appAlreadyExists) {
|
93
|
+
// download app and decompress
|
94
|
+
await downloadEditor(
|
95
|
+
config?.editor.version,
|
96
|
+
`${config?.dirPath}/app.tar.gz`
|
97
|
+
)
|
88
98
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
99
|
+
Console.info("Decompressing LearnPack UI, this may take a minute...")
|
100
|
+
await decompress(
|
101
|
+
`${config?.dirPath}/app.tar.gz`,
|
102
|
+
`${config?.dirPath}/_app/`
|
103
|
+
)
|
104
|
+
}
|
94
105
|
|
95
106
|
// listen to socket commands
|
96
107
|
if (config && this.configManager) {
|
@@ -98,45 +109,51 @@ export default class StartCommand extends SessionCommand {
|
|
98
109
|
configObject,
|
99
110
|
this.configManager,
|
100
111
|
process.env.NODE_ENV === "test"
|
101
|
-
)
|
112
|
+
)
|
102
113
|
|
103
114
|
const dispatcher = queue.dispatcher({
|
104
115
|
create: true,
|
105
116
|
path: `${config.dirPath}/vscode_queue.json`,
|
106
|
-
})
|
117
|
+
})
|
107
118
|
|
108
|
-
socket.start(config, server, false)
|
119
|
+
socket.start(config, server, false)
|
109
120
|
|
110
121
|
socket.on("open", (data: IGitpodData) => {
|
111
|
-
Console.debug("Opening these files: ", data)
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
122
|
+
Console.debug("Opening these files: ", data)
|
123
|
+
console.log("Opening files", data)
|
124
|
+
|
125
|
+
const files = prioritizeHTMLFile(data.files)
|
126
|
+
// console.log("files",files);
|
127
|
+
|
128
|
+
dispatcher.enqueue(dispatcher.events.OPEN_FILES, files)
|
129
|
+
socket.ready("Ready to compile...")
|
130
|
+
})
|
116
131
|
|
117
132
|
socket.on("open_window", (data: IGitpodData) => {
|
118
|
-
Console.debug("Opening window: ", data)
|
119
|
-
dispatcher.enqueue(dispatcher.events.OPEN_WINDOW, data)
|
120
|
-
|
121
|
-
|
133
|
+
Console.debug("Opening window: ", data)
|
134
|
+
dispatcher.enqueue(dispatcher.events.OPEN_WINDOW, data)
|
135
|
+
console.log(data)
|
136
|
+
|
137
|
+
socket.ready("Ready to compile...")
|
138
|
+
})
|
122
139
|
|
123
140
|
socket.on("reset", (exercise: IExerciseData) => {
|
124
141
|
try {
|
125
|
-
this.configManager?.reset(exercise.exerciseSlug)
|
142
|
+
this.configManager?.reset(exercise.exerciseSlug)
|
126
143
|
dispatcher.enqueue(
|
127
144
|
dispatcher.events.RESET_EXERCISE,
|
128
145
|
exercise.exerciseSlug
|
129
|
-
)
|
130
|
-
socket.ready("Ready to compile...")
|
146
|
+
)
|
147
|
+
socket.ready("Ready to compile...")
|
131
148
|
} catch (error) {
|
132
149
|
socket.error(
|
133
150
|
"compiler-error",
|
134
151
|
(error as TypeError).message ||
|
135
152
|
"There was an error reseting the exercise"
|
136
|
-
)
|
137
|
-
setTimeout(() => socket.ready("Ready to compile..."), 2000)
|
153
|
+
)
|
154
|
+
setTimeout(() => socket.ready("Ready to compile..."), 2000)
|
138
155
|
}
|
139
|
-
})
|
156
|
+
})
|
140
157
|
// socket.on("preview", (data) => {
|
141
158
|
// Console.debug("Preview triggered, removing the 'preview' action ")
|
142
159
|
// socket.removeAllowed("preview")
|
@@ -144,7 +161,7 @@ export default class StartCommand extends SessionCommand {
|
|
144
161
|
// })
|
145
162
|
|
146
163
|
socket.on("build", async (data: IExerciseData) => {
|
147
|
-
const exercise = this.configManager?.getExercise(data.exerciseSlug)
|
164
|
+
const exercise = this.configManager?.getExercise(data.exerciseSlug)
|
148
165
|
|
149
166
|
if (!exercise?.language) {
|
150
167
|
socket.error(
|
@@ -152,8 +169,8 @@ export default class StartCommand extends SessionCommand {
|
|
152
169
|
"Impossible to detect language to build for " +
|
153
170
|
data.exerciseSlug +
|
154
171
|
"..."
|
155
|
-
)
|
156
|
-
return
|
172
|
+
)
|
173
|
+
return
|
157
174
|
}
|
158
175
|
|
159
176
|
socket.log(
|
@@ -163,17 +180,23 @@ export default class StartCommand extends SessionCommand {
|
|
163
180
|
" with " +
|
164
181
|
exercise.language +
|
165
182
|
"..."
|
166
|
-
)
|
183
|
+
)
|
167
184
|
await this.config.runHook("action", {
|
168
185
|
action: "compile",
|
169
186
|
socket,
|
170
187
|
configuration: config,
|
171
188
|
exercise,
|
172
|
-
})
|
173
|
-
})
|
189
|
+
})
|
190
|
+
})
|
191
|
+
|
192
|
+
socket.on("generate", async (data: IExerciseData) => {
|
193
|
+
console.log("data", data)
|
194
|
+
})
|
174
195
|
|
175
196
|
socket.on("test", async (data: IExerciseData) => {
|
176
|
-
const exercise = this.configManager?.getExercise(data.exerciseSlug)
|
197
|
+
const exercise = this.configManager?.getExercise(data.exerciseSlug)
|
198
|
+
|
199
|
+
console.log("data", data)
|
177
200
|
|
178
201
|
if (!exercise?.language) {
|
179
202
|
socket.error(
|
@@ -181,57 +204,60 @@ export default class StartCommand extends SessionCommand {
|
|
181
204
|
"Impossible to detect engine language for testing for " +
|
182
205
|
data.exerciseSlug +
|
183
206
|
"..."
|
184
|
-
)
|
185
|
-
return
|
207
|
+
)
|
208
|
+
return
|
186
209
|
}
|
187
210
|
|
188
211
|
if (
|
189
212
|
config?.disabledActions!.includes("test") ||
|
190
213
|
config?.disableGrading
|
191
214
|
) {
|
192
|
-
socket.ready("Grading is disabled on configuration")
|
193
|
-
return true
|
215
|
+
socket.ready("Grading is disabled on configuration")
|
216
|
+
return true
|
194
217
|
}
|
195
218
|
|
196
219
|
socket.log(
|
197
220
|
"testing",
|
198
221
|
"Testing your exercise using the " + exercise.language + " engine."
|
199
|
-
)
|
222
|
+
)
|
223
|
+
|
224
|
+
console.log("About to call runHook")
|
200
225
|
|
201
226
|
await this.config.runHook("action", {
|
202
227
|
action: "test",
|
203
228
|
socket,
|
204
229
|
configuration: config,
|
205
230
|
exercise,
|
206
|
-
})
|
207
|
-
|
231
|
+
})
|
232
|
+
|
233
|
+
this.configManager?.save()
|
208
234
|
|
209
|
-
return true
|
210
|
-
})
|
235
|
+
return true
|
236
|
+
})
|
211
237
|
|
212
238
|
const terminate = () => {
|
213
|
-
Console.debug("Terminating Learnpack...")
|
239
|
+
Console.debug("Terminating Learnpack...")
|
214
240
|
server.terminate(() => {
|
215
|
-
this.configManager?.noCurrentExercise()
|
216
|
-
dispatcher.enqueue(dispatcher.events.END)
|
217
|
-
process.exit()
|
218
|
-
})
|
219
|
-
}
|
241
|
+
this.configManager?.noCurrentExercise()
|
242
|
+
dispatcher.enqueue(dispatcher.events.END)
|
243
|
+
process.exit()
|
244
|
+
})
|
245
|
+
}
|
220
246
|
|
221
|
-
server.on("close", terminate)
|
222
|
-
process.on("SIGINT", terminate)
|
223
|
-
process.on("SIGTERM", terminate)
|
224
|
-
process.on("SIGHUP", terminate)
|
247
|
+
server.on("close", terminate)
|
248
|
+
process.on("SIGINT", terminate)
|
249
|
+
process.on("SIGTERM", terminate)
|
250
|
+
process.on("SIGHUP", terminate)
|
225
251
|
|
226
252
|
// finish the server startup
|
227
|
-
setTimeout(() => dispatcher.enqueue(dispatcher.events.RUNNING), 1000)
|
253
|
+
setTimeout(() => dispatcher.enqueue(dispatcher.events.RUNNING), 1000)
|
228
254
|
|
229
255
|
// start watching for file changes
|
230
256
|
|
231
257
|
if (StartCommand.flags.watch)
|
232
258
|
this.configManager.watchIndex(_exercises =>
|
233
259
|
socket.reload(null, _exercises)
|
234
|
-
)
|
260
|
+
)
|
235
261
|
}
|
236
262
|
}
|
237
263
|
}
|
package/src/commands/test.ts
CHANGED
@@ -1,77 +1,77 @@
|
|
1
|
-
import Console from "../utils/console"
|
2
|
-
import SessionCommand from "../utils/SessionCommand"
|
3
|
-
import socket from "../managers/socket"
|
1
|
+
import Console from "../utils/console"
|
2
|
+
import SessionCommand from "../utils/SessionCommand"
|
3
|
+
import socket from "../managers/socket"
|
4
4
|
|
5
|
-
import createServer from "../managers/server"
|
6
|
-
import ExercisesQueue from "../utils/exercisesQueue"
|
7
|
-
import { IExercise } from "../models/exercise-obj"
|
5
|
+
import createServer from "../managers/server"
|
6
|
+
import ExercisesQueue from "../utils/exercisesQueue"
|
7
|
+
import { IExercise } from "../models/exercise-obj"
|
8
8
|
|
9
9
|
class TestCommand extends SessionCommand {
|
10
10
|
async init() {
|
11
|
-
const { flags } = this.parse(TestCommand)
|
12
|
-
await this.initSession(flags)
|
11
|
+
const { flags } = this.parse(TestCommand)
|
12
|
+
await this.initSession(flags)
|
13
13
|
}
|
14
14
|
|
15
15
|
async run() {
|
16
16
|
const {
|
17
17
|
args: { exerciseSlug },
|
18
|
-
} = this.parse(TestCommand)
|
18
|
+
} = this.parse(TestCommand)
|
19
19
|
|
20
20
|
// Build exercises index
|
21
|
-
this.configManager?.buildIndex()
|
21
|
+
this.configManager?.buildIndex()
|
22
22
|
|
23
|
-
let exercises: IExercise[] | undefined = []
|
23
|
+
let exercises: IExercise[] | undefined = []
|
24
24
|
|
25
25
|
// test all exercises
|
26
26
|
!exerciseSlug ?
|
27
27
|
(exercises = this.configManager?.getAllExercises()) :
|
28
|
-
(exercises = [this.configManager!.getExercise(exerciseSlug)])
|
28
|
+
(exercises = [this.configManager!.getExercise(exerciseSlug)])
|
29
29
|
|
30
|
-
const exercisesQueue = new ExercisesQueue(exercises)
|
30
|
+
const exercisesQueue = new ExercisesQueue(exercises)
|
31
31
|
|
32
|
-
const configObject = this.configManager?.get()
|
32
|
+
const configObject = this.configManager?.get()
|
33
33
|
|
34
|
-
let hasFailed = false
|
35
|
-
let failedTestsCount = 0
|
36
|
-
let successTestsCount = 0
|
37
|
-
const testsToRunCount = exercisesQueue.size()
|
34
|
+
let hasFailed = false
|
35
|
+
let failedTestsCount = 0
|
36
|
+
let successTestsCount = 0
|
37
|
+
const testsToRunCount = exercisesQueue.size()
|
38
38
|
|
39
39
|
configObject!.config!.testingFinishedCallback = ({ result }) => {
|
40
40
|
if (result === "failed") {
|
41
|
-
hasFailed = true
|
42
|
-
failedTestsCount
|
41
|
+
hasFailed = true
|
42
|
+
failedTestsCount++
|
43
43
|
} else {
|
44
|
-
successTestsCount
|
44
|
+
successTestsCount++
|
45
45
|
}
|
46
46
|
|
47
47
|
if (exercisesQueue.isEmpty()) {
|
48
48
|
Console.info(
|
49
49
|
`${testsToRunCount} test${testsToRunCount > 1 ? "s" : ""} runned`
|
50
|
-
)
|
50
|
+
)
|
51
51
|
Console.success(
|
52
52
|
`${successTestsCount} test${successTestsCount > 1 ? "s" : ""} passed`
|
53
|
-
)
|
53
|
+
)
|
54
54
|
Console.error(
|
55
55
|
`${failedTestsCount} test${failedTestsCount > 1 ? "s" : ""} failed`
|
56
|
-
)
|
56
|
+
)
|
57
57
|
|
58
|
-
process.exit(hasFailed ? 1 : 0)
|
58
|
+
process.exit(hasFailed ? 1 : 0)
|
59
59
|
} else {
|
60
|
-
exercisesQueue.pop()!.test!(this.config, config!, socket)
|
60
|
+
exercisesQueue.pop()!.test!(this.config, config!, socket)
|
61
61
|
}
|
62
|
-
}
|
62
|
+
}
|
63
63
|
|
64
|
-
const config = configObject?.config
|
64
|
+
const config = configObject?.config
|
65
65
|
|
66
|
-
const server = await createServer(configObject!, this.configManager!, true)
|
66
|
+
const server = await createServer(configObject!, this.configManager!, true)
|
67
67
|
|
68
|
-
socket.start(config!, server, true)
|
68
|
+
socket.start(config!, server, true)
|
69
69
|
|
70
|
-
exercisesQueue.pop()!.test!(this.config, config!, socket)
|
70
|
+
exercisesQueue.pop()!.test!(this.config, config!, socket)
|
71
71
|
}
|
72
72
|
}
|
73
73
|
|
74
|
-
TestCommand.description = `Test exercises
|
74
|
+
TestCommand.description = `Test exercises`
|
75
75
|
|
76
76
|
TestCommand.args = [
|
77
77
|
{
|
@@ -80,6 +80,6 @@ TestCommand.args = [
|
|
80
80
|
description: "The name of the exercise to test",
|
81
81
|
hidden: false,
|
82
82
|
},
|
83
|
-
]
|
83
|
+
]
|
84
84
|
|
85
|
-
export default TestCommand
|
85
|
+
export default TestCommand
|
@@ -3,7 +3,7 @@ export default {
|
|
3
3
|
port: 3000,
|
4
4
|
editor: {
|
5
5
|
mode: null, // [standalone, preview]
|
6
|
-
agent: null, // [vscode, gitpod, localhost]
|
6
|
+
agent: null, // [vscode, gitpod, localhost, codespaces] TODO: We need to check if we are in codespaces
|
7
7
|
version: null,
|
8
8
|
},
|
9
9
|
dirPath: "./.learn",
|
@@ -35,4 +35,4 @@ export default {
|
|
35
35
|
exercises: [],
|
36
36
|
bugsLink: null,
|
37
37
|
videoSolutions: false,
|
38
|
-
}
|
38
|
+
}
|