@learnpack/learnpack 2.1.39 → 2.1.40
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 +370 -35
- package/bin/run +17 -17
- package/bin/run.cmd +3 -3
- package/lib/commands/audit.d.ts +6 -6
- package/lib/commands/audit.js +342 -342
- package/lib/commands/clean.d.ts +8 -8
- package/lib/commands/clean.js +25 -25
- package/lib/commands/download.d.ts +13 -13
- package/lib/commands/download.js +55 -55
- package/lib/commands/init.d.ts +9 -9
- package/lib/commands/init.js +123 -123
- package/lib/commands/login.d.ts +14 -14
- package/lib/commands/login.js +37 -37
- package/lib/commands/logout.d.ts +14 -14
- package/lib/commands/logout.js +37 -37
- package/lib/commands/publish.d.ts +14 -14
- package/lib/commands/publish.js +82 -82
- package/lib/commands/start.d.ts +7 -7
- package/lib/commands/start.js +239 -208
- package/lib/commands/test.d.ts +6 -6
- package/lib/commands/test.js +62 -62
- package/lib/index.d.ts +1 -1
- package/lib/index.js +4 -4
- package/lib/managers/config/allowed_files.d.ts +5 -5
- package/lib/managers/config/allowed_files.js +30 -30
- package/lib/managers/config/defaults.d.ts +41 -41
- package/lib/managers/config/defaults.js +44 -44
- package/lib/managers/config/exercise.d.ts +36 -36
- package/lib/managers/config/exercise.js +236 -236
- package/lib/managers/config/index.d.ts +3 -3
- package/lib/managers/config/index.js +337 -337
- package/lib/managers/file.d.ts +14 -14
- package/lib/managers/file.js +153 -153
- package/lib/managers/gitpod.d.ts +3 -3
- package/lib/managers/gitpod.js +67 -67
- package/lib/managers/server/index.d.ts +6 -6
- package/lib/managers/server/index.js +58 -58
- package/lib/managers/server/routes.d.ts +4 -4
- package/lib/managers/server/routes.js +219 -219
- package/lib/managers/session.d.ts +3 -3
- package/lib/managers/session.js +125 -125
- package/lib/managers/socket.d.ts +3 -3
- package/lib/managers/socket.js +176 -176
- package/lib/managers/telemetry.d.ts +74 -74
- package/lib/managers/telemetry.js +206 -206
- package/lib/managers/test.js +84 -84
- package/lib/models/action.d.ts +2 -2
- package/lib/models/action.js +2 -2
- package/lib/models/audit.d.ts +15 -15
- package/lib/models/audit.js +2 -2
- package/lib/models/config-manager.d.ts +21 -21
- package/lib/models/config-manager.js +2 -2
- package/lib/models/config.d.ts +68 -67
- package/lib/models/config.js +2 -2
- package/lib/models/counter.d.ts +11 -11
- package/lib/models/counter.js +2 -2
- package/lib/models/errors.d.ts +15 -15
- package/lib/models/errors.js +2 -2
- package/lib/models/exercise-obj.d.ts +30 -30
- package/lib/models/exercise-obj.js +2 -2
- package/lib/models/file.d.ts +5 -5
- package/lib/models/file.js +2 -2
- package/lib/models/findings.d.ts +17 -17
- package/lib/models/findings.js +2 -2
- package/lib/models/flags.d.ts +10 -10
- package/lib/models/flags.js +2 -2
- package/lib/models/front-matter.d.ts +11 -11
- package/lib/models/front-matter.js +2 -2
- package/lib/models/gitpod-data.d.ts +16 -16
- package/lib/models/gitpod-data.js +2 -2
- package/lib/models/language.d.ts +4 -4
- package/lib/models/language.js +2 -2
- package/lib/models/package.d.ts +7 -7
- package/lib/models/package.js +2 -2
- package/lib/models/plugin-config.d.ts +16 -16
- package/lib/models/plugin-config.js +2 -2
- package/lib/models/session.d.ts +31 -31
- package/lib/models/session.js +2 -2
- package/lib/models/socket.d.ts +36 -32
- package/lib/models/socket.js +2 -2
- package/lib/models/status.d.ts +1 -1
- package/lib/models/status.js +2 -2
- package/lib/models/success-types.d.ts +1 -1
- package/lib/models/success-types.js +2 -2
- package/lib/plugin/command/compile.d.ts +6 -6
- package/lib/plugin/command/compile.js +18 -18
- package/lib/plugin/command/test.d.ts +6 -6
- package/lib/plugin/command/test.js +25 -25
- package/lib/plugin/index.d.ts +27 -27
- package/lib/plugin/index.js +7 -7
- package/lib/plugin/plugin.d.ts +8 -8
- package/lib/plugin/plugin.js +68 -68
- package/lib/plugin/utils.d.ts +16 -16
- package/lib/plugin/utils.js +58 -58
- package/lib/ui/download.d.ts +5 -5
- package/lib/ui/download.js +61 -61
- package/lib/utils/BaseCommand.d.ts +8 -8
- package/lib/utils/BaseCommand.js +41 -41
- package/lib/utils/SessionCommand.d.ts +10 -10
- package/lib/utils/SessionCommand.js +43 -43
- package/lib/utils/api.d.ts +14 -14
- package/lib/utils/api.js +255 -255
- package/lib/utils/audit.d.ts +16 -16
- package/lib/utils/audit.js +303 -303
- package/lib/utils/checkNotInstalled.d.ts +2 -0
- package/lib/utils/checkNotInstalled.js +36 -0
- package/lib/utils/console.d.ts +12 -12
- package/lib/utils/console.js +19 -19
- package/lib/utils/errors.d.ts +17 -17
- package/lib/utils/errors.js +100 -100
- package/lib/utils/exercisesQueue.d.ts +9 -9
- package/lib/utils/exercisesQueue.js +38 -38
- package/lib/utils/fileQueue.d.ts +40 -40
- package/lib/utils/fileQueue.js +168 -168
- package/lib/utils/misc.d.ts +1 -1
- package/lib/utils/misc.js +23 -23
- package/lib/utils/osOperations.d.ts +5 -5
- package/lib/utils/osOperations.js +72 -72
- package/lib/utils/validators.d.ts +5 -5
- package/lib/utils/validators.js +17 -17
- package/lib/utils/watcher.d.ts +2 -2
- package/lib/utils/watcher.js +25 -25
- package/oclif.manifest.json +1 -1
- package/package.json +139 -139
- package/src/commands/audit.ts +443 -443
- package/src/commands/clean.ts +29 -29
- package/src/commands/download.ts +61 -61
- package/src/commands/init.ts +170 -170
- package/src/commands/login.ts +42 -42
- package/src/commands/logout.ts +43 -43
- package/src/commands/publish.ts +107 -107
- package/src/commands/start.ts +53 -23
- package/src/commands/test.ts +85 -85
- package/src/index.ts +1 -1
- package/src/managers/config/allowed_files.ts +29 -29
- package/src/managers/config/defaults.ts +42 -42
- package/src/managers/config/exercise.ts +311 -311
- package/src/managers/config/index.ts +455 -455
- package/src/managers/file.ts +196 -196
- package/src/managers/gitpod.ts +84 -84
- package/src/managers/server/index.ts +78 -78
- package/src/managers/server/routes.ts +330 -330
- package/src/managers/session.ts +145 -145
- package/src/managers/socket.ts +250 -250
- package/src/managers/telemetry.ts +346 -346
- package/src/managers/test.ts +83 -83
- package/src/models/action.ts +10 -10
- package/src/models/audit.ts +16 -16
- package/src/models/config-manager.ts +23 -23
- package/src/models/config.ts +5 -3
- package/src/models/counter.ts +11 -11
- package/src/models/errors.ts +22 -22
- package/src/models/exercise-obj.ts +29 -29
- package/src/models/file.ts +5 -5
- package/src/models/findings.ts +18 -18
- package/src/models/flags.ts +10 -10
- package/src/models/front-matter.ts +11 -11
- package/src/models/gitpod-data.ts +19 -19
- package/src/models/language.ts +4 -4
- package/src/models/package.ts +7 -7
- package/src/models/plugin-config.ts +17 -17
- package/src/models/session.ts +34 -34
- package/src/models/socket.ts +5 -0
- package/src/models/status.ts +16 -16
- package/src/models/success-types.ts +1 -1
- package/src/plugin/command/compile.ts +17 -17
- package/src/plugin/command/test.ts +30 -30
- package/src/plugin/index.ts +6 -6
- package/src/plugin/plugin.ts +94 -94
- package/src/plugin/utils.ts +87 -87
- package/src/types/node-fetch.d.ts +1 -1
- package/src/ui/download.ts +71 -71
- package/src/utils/BaseCommand.ts +48 -48
- package/src/utils/SessionCommand.ts +43 -43
- package/src/utils/api.ts +303 -303
- package/src/utils/audit.ts +393 -393
- package/src/utils/checkNotInstalled.ts +46 -0
- package/src/utils/console.ts +24 -24
- package/src/utils/errors.ts +117 -117
- package/src/utils/exercisesQueue.ts +51 -51
- package/src/utils/fileQueue.ts +198 -198
- package/src/utils/misc.ts +23 -23
- package/src/utils/osOperations.ts +79 -79
- package/src/utils/templates/gitignore.txt +19 -19
- package/src/utils/templates/incremental/.learn/exercises/01-hello-world/README.es.md +24 -24
- package/src/utils/templates/incremental/.learn/exercises/01-hello-world/README.md +24 -24
- package/src/utils/templates/incremental/README.ejs +4 -4
- package/src/utils/templates/incremental/README.es.ejs +4 -4
- package/src/utils/templates/isolated/01-hello-world/README.es.md +26 -26
- package/src/utils/templates/isolated/01-hello-world/README.md +26 -26
- package/src/utils/templates/isolated/README.ejs +4 -4
- package/src/utils/templates/isolated/README.es.ejs +4 -4
- package/src/utils/templates/no-grading/README.ejs +4 -4
- package/src/utils/templates/no-grading/README.es.ejs +4 -4
- package/src/utils/validators.ts +18 -18
- package/src/utils/watcher.ts +27 -27
package/src/commands/logout.ts
CHANGED
|
@@ -1,43 +1,43 @@
|
|
|
1
|
-
// import {Command, flags} from '@oclif/command'
|
|
2
|
-
// import { prompt } from "enquirer"
|
|
3
|
-
// import fetch from 'node-fetch'
|
|
4
|
-
import SessionCommand from "../utils/SessionCommand"
|
|
5
|
-
import SessionManager from "../managers/session"
|
|
6
|
-
// import Console from '../utils/console'
|
|
7
|
-
// import { replace } from 'node-emoji'
|
|
8
|
-
// import { validURL } from "../utils/validators"
|
|
9
|
-
// const BaseCommand from '../utils/BaseCommand');
|
|
10
|
-
|
|
11
|
-
class LogoutCommand extends SessionCommand {
|
|
12
|
-
static description = `Describe the command here
|
|
13
|
-
...
|
|
14
|
-
Extra documentation goes here
|
|
15
|
-
`
|
|
16
|
-
|
|
17
|
-
static flags: any = {
|
|
18
|
-
// name: flags.string({char: 'n', description: 'name to print'}),
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
static args = [
|
|
22
|
-
{
|
|
23
|
-
name: "package", // name of arg to show in help and reference with args[name]
|
|
24
|
-
required: false, // make the arg required with `required: true`
|
|
25
|
-
description:
|
|
26
|
-
"The unique string that identifies this package on learnpack", // help description
|
|
27
|
-
hidden: false, // hide this arg from help
|
|
28
|
-
},
|
|
29
|
-
]
|
|
30
|
-
|
|
31
|
-
async init() {
|
|
32
|
-
const { flags } = this.parse(LogoutCommand)
|
|
33
|
-
await this.initSession(flags)
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
async run() {
|
|
37
|
-
// const {flags, args} = this.parse(LogoutCommand)
|
|
38
|
-
|
|
39
|
-
SessionManager.destroy()
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export default LogoutCommand
|
|
1
|
+
// import {Command, flags} from '@oclif/command'
|
|
2
|
+
// import { prompt } from "enquirer"
|
|
3
|
+
// import fetch from 'node-fetch'
|
|
4
|
+
import SessionCommand from "../utils/SessionCommand"
|
|
5
|
+
import SessionManager from "../managers/session"
|
|
6
|
+
// import Console from '../utils/console'
|
|
7
|
+
// import { replace } from 'node-emoji'
|
|
8
|
+
// import { validURL } from "../utils/validators"
|
|
9
|
+
// const BaseCommand from '../utils/BaseCommand');
|
|
10
|
+
|
|
11
|
+
class LogoutCommand extends SessionCommand {
|
|
12
|
+
static description = `Describe the command here
|
|
13
|
+
...
|
|
14
|
+
Extra documentation goes here
|
|
15
|
+
`
|
|
16
|
+
|
|
17
|
+
static flags: any = {
|
|
18
|
+
// name: flags.string({char: 'n', description: 'name to print'}),
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
static args = [
|
|
22
|
+
{
|
|
23
|
+
name: "package", // name of arg to show in help and reference with args[name]
|
|
24
|
+
required: false, // make the arg required with `required: true`
|
|
25
|
+
description:
|
|
26
|
+
"The unique string that identifies this package on learnpack", // help description
|
|
27
|
+
hidden: false, // hide this arg from help
|
|
28
|
+
},
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
async init() {
|
|
32
|
+
const { flags } = this.parse(LogoutCommand)
|
|
33
|
+
await this.initSession(flags)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async run() {
|
|
37
|
+
// const {flags, args} = this.parse(LogoutCommand)
|
|
38
|
+
|
|
39
|
+
SessionManager.destroy()
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export default LogoutCommand
|
package/src/commands/publish.ts
CHANGED
|
@@ -1,107 +1,107 @@
|
|
|
1
|
-
import { prompt } from "enquirer"
|
|
2
|
-
import SessionCommand from "../utils/SessionCommand"
|
|
3
|
-
import Console from "../utils/console"
|
|
4
|
-
import api from "../utils/api"
|
|
5
|
-
import { validURL } from "../utils/validators"
|
|
6
|
-
|
|
7
|
-
// eslint-disable-next-line
|
|
8
|
-
const fetch = require("node-fetch");
|
|
9
|
-
|
|
10
|
-
class PublishCommand extends SessionCommand {
|
|
11
|
-
static description = `Describe the command here
|
|
12
|
-
...
|
|
13
|
-
Extra documentation goes here
|
|
14
|
-
`
|
|
15
|
-
|
|
16
|
-
static flags: any = {
|
|
17
|
-
// name: flags.string({char: 'n', description: 'name to print'}),
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
static args = [
|
|
21
|
-
{
|
|
22
|
-
name: "package", // name of arg to show in help and reference with args[name]
|
|
23
|
-
required: false, // make the arg required with `required: true`
|
|
24
|
-
description:
|
|
25
|
-
"The unique string that identifies this package on learnpack", // help description
|
|
26
|
-
hidden: false, // hide this arg from help
|
|
27
|
-
},
|
|
28
|
-
]
|
|
29
|
-
|
|
30
|
-
async init() {
|
|
31
|
-
const { flags } = this.parse(PublishCommand)
|
|
32
|
-
await this.initSession(flags, true)
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
async run() {
|
|
36
|
-
const { flags, args } = this.parse(PublishCommand)
|
|
37
|
-
|
|
38
|
-
// avoid annonymus sessions
|
|
39
|
-
// eslint-disable-next-line
|
|
40
|
-
if (!this.session) return;
|
|
41
|
-
|
|
42
|
-
Console.info(
|
|
43
|
-
`Session found for ${this.session.payload.email}, publishing the package...`
|
|
44
|
-
)
|
|
45
|
-
|
|
46
|
-
const configObject = this.configManager?.get()
|
|
47
|
-
if (
|
|
48
|
-
configObject?.config?.slug === undefined ||
|
|
49
|
-
!configObject.config?.slug
|
|
50
|
-
) {
|
|
51
|
-
throw new Error(
|
|
52
|
-
"The package is missing a slug (unique name identifier), please check your learn.json file and make sure it has a 'slug'"
|
|
53
|
-
)
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
if (!validURL(configObject?.config?.repository ?? "")) {
|
|
57
|
-
throw new Error(
|
|
58
|
-
"The package has a missing or invalid 'repository' on the configuration file, it needs to be a Github URL"
|
|
59
|
-
)
|
|
60
|
-
} else {
|
|
61
|
-
const validateResp = await fetch(configObject.config?.repository, {
|
|
62
|
-
method: "HEAD",
|
|
63
|
-
})
|
|
64
|
-
if (!validateResp.ok || validateResp.status !== 200) {
|
|
65
|
-
throw new Error(
|
|
66
|
-
`The specified repository URL on the configuration file does not exist or its private, only public repositories are allowed at the moment: ${configObject.config?.repository}`
|
|
67
|
-
)
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// start watching for file changes
|
|
72
|
-
try {
|
|
73
|
-
await api.publish({
|
|
74
|
-
...configObject,
|
|
75
|
-
author: this.session.payload.user_id,
|
|
76
|
-
})
|
|
77
|
-
Console.success(
|
|
78
|
-
`Package updated and published successfully: ${configObject.config?.slug}`
|
|
79
|
-
)
|
|
80
|
-
} catch (error) {
|
|
81
|
-
if ((error as any).status === 404) {
|
|
82
|
-
const answer = await prompt([
|
|
83
|
-
{
|
|
84
|
-
type: "confirm",
|
|
85
|
-
name: "create",
|
|
86
|
-
message: `Package with slug ${configObject.config?.slug} does not exist, do you want to create it?`,
|
|
87
|
-
},
|
|
88
|
-
])
|
|
89
|
-
if (answer) {
|
|
90
|
-
await api.update({
|
|
91
|
-
...configObject,
|
|
92
|
-
author: this.session.payload.user_id,
|
|
93
|
-
})
|
|
94
|
-
Console.success(
|
|
95
|
-
`Package created and published successfully: ${configObject.config?.slug}`
|
|
96
|
-
)
|
|
97
|
-
} else {
|
|
98
|
-
Console.error("No answer from server")
|
|
99
|
-
}
|
|
100
|
-
} else {
|
|
101
|
-
Console.error((error as TypeError).message)
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
export default PublishCommand
|
|
1
|
+
import { prompt } from "enquirer"
|
|
2
|
+
import SessionCommand from "../utils/SessionCommand"
|
|
3
|
+
import Console from "../utils/console"
|
|
4
|
+
import api from "../utils/api"
|
|
5
|
+
import { validURL } from "../utils/validators"
|
|
6
|
+
|
|
7
|
+
// eslint-disable-next-line
|
|
8
|
+
const fetch = require("node-fetch");
|
|
9
|
+
|
|
10
|
+
class PublishCommand extends SessionCommand {
|
|
11
|
+
static description = `Describe the command here
|
|
12
|
+
...
|
|
13
|
+
Extra documentation goes here
|
|
14
|
+
`
|
|
15
|
+
|
|
16
|
+
static flags: any = {
|
|
17
|
+
// name: flags.string({char: 'n', description: 'name to print'}),
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
static args = [
|
|
21
|
+
{
|
|
22
|
+
name: "package", // name of arg to show in help and reference with args[name]
|
|
23
|
+
required: false, // make the arg required with `required: true`
|
|
24
|
+
description:
|
|
25
|
+
"The unique string that identifies this package on learnpack", // help description
|
|
26
|
+
hidden: false, // hide this arg from help
|
|
27
|
+
},
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
async init() {
|
|
31
|
+
const { flags } = this.parse(PublishCommand)
|
|
32
|
+
await this.initSession(flags, true)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async run() {
|
|
36
|
+
const { flags, args } = this.parse(PublishCommand)
|
|
37
|
+
|
|
38
|
+
// avoid annonymus sessions
|
|
39
|
+
// eslint-disable-next-line
|
|
40
|
+
if (!this.session) return;
|
|
41
|
+
|
|
42
|
+
Console.info(
|
|
43
|
+
`Session found for ${this.session.payload.email}, publishing the package...`
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
const configObject = this.configManager?.get()
|
|
47
|
+
if (
|
|
48
|
+
configObject?.config?.slug === undefined ||
|
|
49
|
+
!configObject.config?.slug
|
|
50
|
+
) {
|
|
51
|
+
throw new Error(
|
|
52
|
+
"The package is missing a slug (unique name identifier), please check your learn.json file and make sure it has a 'slug'"
|
|
53
|
+
)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (!validURL(configObject?.config?.repository ?? "")) {
|
|
57
|
+
throw new Error(
|
|
58
|
+
"The package has a missing or invalid 'repository' on the configuration file, it needs to be a Github URL"
|
|
59
|
+
)
|
|
60
|
+
} else {
|
|
61
|
+
const validateResp = await fetch(configObject.config?.repository, {
|
|
62
|
+
method: "HEAD",
|
|
63
|
+
})
|
|
64
|
+
if (!validateResp.ok || validateResp.status !== 200) {
|
|
65
|
+
throw new Error(
|
|
66
|
+
`The specified repository URL on the configuration file does not exist or its private, only public repositories are allowed at the moment: ${configObject.config?.repository}`
|
|
67
|
+
)
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// start watching for file changes
|
|
72
|
+
try {
|
|
73
|
+
await api.publish({
|
|
74
|
+
...configObject,
|
|
75
|
+
author: this.session.payload.user_id,
|
|
76
|
+
})
|
|
77
|
+
Console.success(
|
|
78
|
+
`Package updated and published successfully: ${configObject.config?.slug}`
|
|
79
|
+
)
|
|
80
|
+
} catch (error) {
|
|
81
|
+
if ((error as any).status === 404) {
|
|
82
|
+
const answer = await prompt([
|
|
83
|
+
{
|
|
84
|
+
type: "confirm",
|
|
85
|
+
name: "create",
|
|
86
|
+
message: `Package with slug ${configObject.config?.slug} does not exist, do you want to create it?`,
|
|
87
|
+
},
|
|
88
|
+
])
|
|
89
|
+
if (answer) {
|
|
90
|
+
await api.update({
|
|
91
|
+
...configObject,
|
|
92
|
+
author: this.session.payload.user_id,
|
|
93
|
+
})
|
|
94
|
+
Console.success(
|
|
95
|
+
`Package created and published successfully: ${configObject.config?.slug}`
|
|
96
|
+
)
|
|
97
|
+
} else {
|
|
98
|
+
Console.error("No answer from server")
|
|
99
|
+
}
|
|
100
|
+
} else {
|
|
101
|
+
Console.error((error as TypeError).message)
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export default PublishCommand
|
package/src/commands/start.ts
CHANGED
|
@@ -17,6 +17,9 @@ import { prioritizeHTMLFile } from "../utils/misc"
|
|
|
17
17
|
import { IGitpodData } from "../models/gitpod-data"
|
|
18
18
|
import { IExercise, IExerciseData } from "../models/exercise-obj"
|
|
19
19
|
import { eventManager } from "../utils/osOperations"
|
|
20
|
+
import { cli } from "cli-ux"
|
|
21
|
+
import { TOpenWindowData } from "../models/socket"
|
|
22
|
+
import { checkNotInstalledPlugins } from "../utils/checkNotInstalled"
|
|
20
23
|
|
|
21
24
|
export default class StartCommand extends SessionCommand {
|
|
22
25
|
static description = "Runs a small server with all the exercise instructions"
|
|
@@ -68,9 +71,51 @@ export default class StartCommand extends SessionCommand {
|
|
|
68
71
|
async run() {
|
|
69
72
|
// get configuration object
|
|
70
73
|
const configObject = this.configManager?.get()
|
|
71
|
-
const config = configObject?.config
|
|
72
74
|
|
|
73
|
-
|
|
75
|
+
// TODO: console.log(this.config.platform); get the platfrom from Oclif
|
|
76
|
+
|
|
77
|
+
const installedPlugins = this.config.plugins.map(plugin => {
|
|
78
|
+
return `${plugin.pjson.name}`
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
const neededToInstallPlugins = checkNotInstalledPlugins(
|
|
82
|
+
configObject?.exercises || [],
|
|
83
|
+
installedPlugins
|
|
84
|
+
)
|
|
85
|
+
if (neededToInstallPlugins.length > 0) {
|
|
86
|
+
Console.error(
|
|
87
|
+
"These plugins are not installed but required: ",
|
|
88
|
+
neededToInstallPlugins
|
|
89
|
+
)
|
|
90
|
+
const confirmInstall = await cli.confirm(
|
|
91
|
+
"Do you want to install the needed plugins? (y/n)"
|
|
92
|
+
)
|
|
93
|
+
if (confirmInstall) {
|
|
94
|
+
Console.info("Installing the needed plugins...")
|
|
95
|
+
for await (const p of neededToInstallPlugins) {
|
|
96
|
+
await this.config.runCommand(`plugins:install`, [p])
|
|
97
|
+
Console.log(`Plugin ${p} installed`)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
Console.log(
|
|
101
|
+
"All needed plugins installed, please restart LearnPack to load them."
|
|
102
|
+
)
|
|
103
|
+
Console.info("Run: $ learnpack start")
|
|
104
|
+
this.exit(0)
|
|
105
|
+
} else {
|
|
106
|
+
Console.error(
|
|
107
|
+
"You need to install the plugins to complete this exercise"
|
|
108
|
+
)
|
|
109
|
+
Console.info(
|
|
110
|
+
"To install the plugins run each of the following commands: "
|
|
111
|
+
)
|
|
112
|
+
for (const p of neededToInstallPlugins) {
|
|
113
|
+
Console.log(`learnpack plugins:install ${p}`)
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
this.exit(1)
|
|
117
|
+
}
|
|
118
|
+
}
|
|
74
119
|
|
|
75
120
|
if (configObject) {
|
|
76
121
|
const { config } = configObject
|
|
@@ -113,9 +158,7 @@ export default class StartCommand extends SessionCommand {
|
|
|
113
158
|
this.configManager,
|
|
114
159
|
process.env.NODE_ENV === "test"
|
|
115
160
|
)
|
|
116
|
-
server.setMaxListeners(
|
|
117
|
-
|
|
118
|
-
// console.log(config, "this is the f*!shell.which("code")!shell.which("code")cking config");
|
|
161
|
+
server.setMaxListeners(25)
|
|
119
162
|
|
|
120
163
|
// I should call a method to get the EventListener
|
|
121
164
|
const dispatcher = queue.dispatcher({
|
|
@@ -164,28 +207,15 @@ export default class StartCommand extends SessionCommand {
|
|
|
164
207
|
socket.ready("Ready to compile...")
|
|
165
208
|
})
|
|
166
209
|
|
|
167
|
-
socket.on("open_window", (data:
|
|
210
|
+
socket.on("open_window", (data: TOpenWindowData) => {
|
|
168
211
|
Console.debug("Opening window: ", data)
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
config.editor.agent === "os" &&
|
|
172
|
-
((config.os === "linux" && hasXDG) || config.os !== "linux")
|
|
173
|
-
) {
|
|
174
|
-
eventManager.enqueue(dispatcher.events.OPEN_WINDOW, data)
|
|
175
|
-
} else {
|
|
176
|
-
dispatcher.enqueue(dispatcher.events.OPEN_WINDOW, data)
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
socket.ready("Ready to compile...")
|
|
212
|
+
cli.open(data.url)
|
|
213
|
+
socket.log("open_window", `URL ${data.url} opened in the browser`)
|
|
180
214
|
})
|
|
181
215
|
|
|
182
216
|
socket.on("reset", (exercise: IExerciseData) => {
|
|
183
217
|
try {
|
|
184
218
|
this.configManager?.reset(exercise.exerciseSlug)
|
|
185
|
-
dispatcher.enqueue(
|
|
186
|
-
dispatcher.events.RESET_EXERCISE,
|
|
187
|
-
exercise.exerciseSlug
|
|
188
|
-
)
|
|
189
219
|
socket.ready("Ready to compile...")
|
|
190
220
|
} catch (error) {
|
|
191
221
|
socket.error(
|
|
@@ -271,9 +301,9 @@ export default class StartCommand extends SessionCommand {
|
|
|
271
301
|
return true
|
|
272
302
|
})
|
|
273
303
|
|
|
274
|
-
const terminate = () => {
|
|
304
|
+
const terminate = async () => {
|
|
275
305
|
Console.error("Terminating Learnpack...")
|
|
276
|
-
TelemetryManager.submit()
|
|
306
|
+
await TelemetryManager.submit()
|
|
277
307
|
this.configManager?.noCurrentExercise()
|
|
278
308
|
dispatcher.enqueue(dispatcher.events.END)
|
|
279
309
|
process.exit()
|
package/src/commands/test.ts
CHANGED
|
@@ -1,85 +1,85 @@
|
|
|
1
|
-
import Console from "../utils/console"
|
|
2
|
-
import SessionCommand from "../utils/SessionCommand"
|
|
3
|
-
import socket from "../managers/socket"
|
|
4
|
-
|
|
5
|
-
import createServer from "../managers/server"
|
|
6
|
-
import ExercisesQueue from "../utils/exercisesQueue"
|
|
7
|
-
import { IExercise } from "../models/exercise-obj"
|
|
8
|
-
|
|
9
|
-
class TestCommand extends SessionCommand {
|
|
10
|
-
async init() {
|
|
11
|
-
const { flags } = this.parse(TestCommand)
|
|
12
|
-
await this.initSession(flags)
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
async run() {
|
|
16
|
-
const {
|
|
17
|
-
args: { exerciseSlug },
|
|
18
|
-
} = this.parse(TestCommand)
|
|
19
|
-
|
|
20
|
-
// Build exercises index
|
|
21
|
-
this.configManager?.buildIndex()
|
|
22
|
-
|
|
23
|
-
let exercises: IExercise[] | undefined = []
|
|
24
|
-
|
|
25
|
-
// test all exercises
|
|
26
|
-
!exerciseSlug ?
|
|
27
|
-
(exercises = this.configManager?.getAllExercises()) :
|
|
28
|
-
(exercises = [this.configManager!.getExercise(exerciseSlug)])
|
|
29
|
-
|
|
30
|
-
const exercisesQueue = new ExercisesQueue(exercises)
|
|
31
|
-
|
|
32
|
-
const configObject = this.configManager?.get()
|
|
33
|
-
|
|
34
|
-
let hasFailed = false
|
|
35
|
-
let failedTestsCount = 0
|
|
36
|
-
let successTestsCount = 0
|
|
37
|
-
const testsToRunCount = exercisesQueue.size()
|
|
38
|
-
|
|
39
|
-
configObject!.config!.testingFinishedCallback = ({ result }) => {
|
|
40
|
-
if (result === "failed") {
|
|
41
|
-
hasFailed = true
|
|
42
|
-
failedTestsCount++
|
|
43
|
-
} else {
|
|
44
|
-
successTestsCount++
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
if (exercisesQueue.isEmpty()) {
|
|
48
|
-
Console.info(
|
|
49
|
-
`${testsToRunCount} test${testsToRunCount > 1 ? "s" : ""} runned`
|
|
50
|
-
)
|
|
51
|
-
Console.success(
|
|
52
|
-
`${successTestsCount} test${successTestsCount > 1 ? "s" : ""} passed`
|
|
53
|
-
)
|
|
54
|
-
Console.error(
|
|
55
|
-
`${failedTestsCount} test${failedTestsCount > 1 ? "s" : ""} failed`
|
|
56
|
-
)
|
|
57
|
-
|
|
58
|
-
process.exit(hasFailed ? 1 : 0)
|
|
59
|
-
} else {
|
|
60
|
-
exercisesQueue.pop()!.test!(this.config, config!, socket)
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const config = configObject?.config
|
|
65
|
-
|
|
66
|
-
const server = await createServer(configObject!, this.configManager!, true)
|
|
67
|
-
|
|
68
|
-
socket.start(config!, server, true)
|
|
69
|
-
|
|
70
|
-
exercisesQueue.pop()!.test!(this.config, config!, socket)
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
TestCommand.description = `Test exercises`
|
|
75
|
-
|
|
76
|
-
TestCommand.args = [
|
|
77
|
-
{
|
|
78
|
-
name: "exerciseSlug",
|
|
79
|
-
required: false,
|
|
80
|
-
description: "The name of the exercise to test",
|
|
81
|
-
hidden: false,
|
|
82
|
-
},
|
|
83
|
-
]
|
|
84
|
-
|
|
85
|
-
export default TestCommand
|
|
1
|
+
import Console from "../utils/console"
|
|
2
|
+
import SessionCommand from "../utils/SessionCommand"
|
|
3
|
+
import socket from "../managers/socket"
|
|
4
|
+
|
|
5
|
+
import createServer from "../managers/server"
|
|
6
|
+
import ExercisesQueue from "../utils/exercisesQueue"
|
|
7
|
+
import { IExercise } from "../models/exercise-obj"
|
|
8
|
+
|
|
9
|
+
class TestCommand extends SessionCommand {
|
|
10
|
+
async init() {
|
|
11
|
+
const { flags } = this.parse(TestCommand)
|
|
12
|
+
await this.initSession(flags)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async run() {
|
|
16
|
+
const {
|
|
17
|
+
args: { exerciseSlug },
|
|
18
|
+
} = this.parse(TestCommand)
|
|
19
|
+
|
|
20
|
+
// Build exercises index
|
|
21
|
+
this.configManager?.buildIndex()
|
|
22
|
+
|
|
23
|
+
let exercises: IExercise[] | undefined = []
|
|
24
|
+
|
|
25
|
+
// test all exercises
|
|
26
|
+
!exerciseSlug ?
|
|
27
|
+
(exercises = this.configManager?.getAllExercises()) :
|
|
28
|
+
(exercises = [this.configManager!.getExercise(exerciseSlug)])
|
|
29
|
+
|
|
30
|
+
const exercisesQueue = new ExercisesQueue(exercises)
|
|
31
|
+
|
|
32
|
+
const configObject = this.configManager?.get()
|
|
33
|
+
|
|
34
|
+
let hasFailed = false
|
|
35
|
+
let failedTestsCount = 0
|
|
36
|
+
let successTestsCount = 0
|
|
37
|
+
const testsToRunCount = exercisesQueue.size()
|
|
38
|
+
|
|
39
|
+
configObject!.config!.testingFinishedCallback = ({ result }) => {
|
|
40
|
+
if (result === "failed") {
|
|
41
|
+
hasFailed = true
|
|
42
|
+
failedTestsCount++
|
|
43
|
+
} else {
|
|
44
|
+
successTestsCount++
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (exercisesQueue.isEmpty()) {
|
|
48
|
+
Console.info(
|
|
49
|
+
`${testsToRunCount} test${testsToRunCount > 1 ? "s" : ""} runned`
|
|
50
|
+
)
|
|
51
|
+
Console.success(
|
|
52
|
+
`${successTestsCount} test${successTestsCount > 1 ? "s" : ""} passed`
|
|
53
|
+
)
|
|
54
|
+
Console.error(
|
|
55
|
+
`${failedTestsCount} test${failedTestsCount > 1 ? "s" : ""} failed`
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
process.exit(hasFailed ? 1 : 0)
|
|
59
|
+
} else {
|
|
60
|
+
exercisesQueue.pop()!.test!(this.config, config!, socket)
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const config = configObject?.config
|
|
65
|
+
|
|
66
|
+
const server = await createServer(configObject!, this.configManager!, true)
|
|
67
|
+
|
|
68
|
+
socket.start(config!, server, true)
|
|
69
|
+
|
|
70
|
+
exercisesQueue.pop()!.test!(this.config, config!, socket)
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
TestCommand.description = `Test exercises`
|
|
75
|
+
|
|
76
|
+
TestCommand.args = [
|
|
77
|
+
{
|
|
78
|
+
name: "exerciseSlug",
|
|
79
|
+
required: false,
|
|
80
|
+
description: "The name of the exercise to test",
|
|
81
|
+
hidden: false,
|
|
82
|
+
},
|
|
83
|
+
]
|
|
84
|
+
|
|
85
|
+
export default TestCommand
|
package/src/index.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from '@oclif/command'
|
|
1
|
+
export * from '@oclif/command'
|
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
const extensions = {
|
|
2
|
-
extensions: [
|
|
3
|
-
"py",
|
|
4
|
-
"java",
|
|
5
|
-
"py",
|
|
6
|
-
"ruby",
|
|
7
|
-
"html",
|
|
8
|
-
"css",
|
|
9
|
-
"htm",
|
|
10
|
-
"php", // images
|
|
11
|
-
"js",
|
|
12
|
-
"jsx",
|
|
13
|
-
"ts", // images
|
|
14
|
-
"sh",
|
|
15
|
-
"bash", // images
|
|
16
|
-
"json",
|
|
17
|
-
"yml",
|
|
18
|
-
"yaml",
|
|
19
|
-
"csv",
|
|
20
|
-
"xml", // file storage extensions
|
|
21
|
-
"txt",
|
|
22
|
-
"text",
|
|
23
|
-
"markdown",
|
|
24
|
-
"readme", // compressed files
|
|
25
|
-
],
|
|
26
|
-
names: ["package.json", "package-lock.json"],
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export default extensions
|
|
1
|
+
const extensions = {
|
|
2
|
+
extensions: [
|
|
3
|
+
"py",
|
|
4
|
+
"java",
|
|
5
|
+
"py",
|
|
6
|
+
"ruby",
|
|
7
|
+
"html",
|
|
8
|
+
"css",
|
|
9
|
+
"htm",
|
|
10
|
+
"php", // images
|
|
11
|
+
"js",
|
|
12
|
+
"jsx",
|
|
13
|
+
"ts", // images
|
|
14
|
+
"sh",
|
|
15
|
+
"bash", // images
|
|
16
|
+
"json",
|
|
17
|
+
"yml",
|
|
18
|
+
"yaml",
|
|
19
|
+
"csv",
|
|
20
|
+
"xml", // file storage extensions
|
|
21
|
+
"txt",
|
|
22
|
+
"text",
|
|
23
|
+
"markdown",
|
|
24
|
+
"readme", // compressed files
|
|
25
|
+
],
|
|
26
|
+
names: ["package.json", "package-lock.json"],
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export default extensions
|