@learnpack/learnpack 2.1.26 → 2.1.28
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
}
|