@learnpack/learnpack 5.0.8 → 5.0.10
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 +17 -17
- package/bin/run +17 -17
- package/bin/run.cmd +3 -3
- package/lib/commands/audit.js +15 -15
- package/lib/commands/clean.js +3 -3
- package/lib/commands/download.js +3 -3
- package/lib/commands/login.js +3 -3
- package/lib/commands/logout.js +3 -3
- package/lib/commands/publish.js +8 -7
- package/lib/managers/config/index.js +10 -0
- package/lib/managers/session.js +1 -1
- package/lib/utils/checkNotInstalled.js +3 -5
- package/oclif.manifest.json +1 -1
- package/package.json +152 -152
- package/src/commands/audit.ts +449 -449
- package/src/commands/clean.ts +29 -29
- package/src/commands/download.ts +61 -61
- package/src/commands/login.ts +42 -42
- package/src/commands/logout.ts +43 -43
- package/src/commands/publish.ts +9 -7
- 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/index.ts +12 -0
- package/src/managers/gitpod.ts +84 -84
- package/src/managers/server/index.ts +78 -78
- package/src/managers/session.ts +2 -1
- package/src/managers/telemetry.ts +353 -353
- package/src/managers/test.ts +83 -83
- package/src/models/audit.ts +16 -16
- package/src/models/config-manager.ts +23 -23
- 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/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/audit.ts +393 -393
- package/src/utils/checkNotInstalled.ts +10 -12
- package/src/utils/errors.ts +117 -117
- package/src/utils/exercisesQueue.ts +51 -51
- package/src/utils/fileQueue.ts +199 -199
- 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/.vscode/schema.json +121 -121
- package/src/utils/templates/incremental/.vscode/settings.json +13 -13
- package/src/utils/templates/incremental/README.ejs +4 -4
- package/src/utils/templates/incremental/README.es.ejs +4 -4
- package/src/utils/templates/isolated/.vscode/schema.json +121 -121
- package/src/utils/templates/isolated/.vscode/settings.json +13 -13
- 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
@@ -8,10 +8,10 @@ import { cli } from "cli-ux"
|
|
8
8
|
import Console from "./console"
|
9
9
|
|
10
10
|
type TNeededPlugins = {
|
11
|
-
needed: string[]
|
12
|
-
notInstalled: string[]
|
13
|
-
}
|
14
|
-
type TPackageManager = "npm" | "pip"
|
11
|
+
needed: string[]
|
12
|
+
notInstalled: string[]
|
13
|
+
}
|
14
|
+
type TPackageManager = "npm" | "pip"
|
15
15
|
|
16
16
|
export const checkNotInstalledPlugins = async (
|
17
17
|
exercises: IExercise[],
|
@@ -116,9 +116,7 @@ continue
|
|
116
116
|
Console.info("Run: $ learnpack start")
|
117
117
|
command.exit(0)
|
118
118
|
} else {
|
119
|
-
Console.error(
|
120
|
-
"You need to install the plugins to complete this exercise"
|
121
|
-
)
|
119
|
+
Console.error("You need to install the plugins to complete this exercise")
|
122
120
|
Console.info(
|
123
121
|
"To install the plugins run each of the following commands: "
|
124
122
|
)
|
@@ -166,10 +164,8 @@ export const checkNotInstalledDependencies = async (
|
|
166
164
|
neededPlugins: string[]
|
167
165
|
) => {
|
168
166
|
Console.info("Checking needed dependencies...")
|
169
|
-
|
170
|
-
|
171
|
-
"jest-environment-jsdom@29.7.0",
|
172
|
-
]
|
167
|
+
|
168
|
+
const jsPluginsDependencies = ["jest@29.7.0", "jest-environment-jsdom@29.7.0"]
|
173
169
|
const pyPluginsDependencies = ["pytest==6.2.5", "pytest-testdox", "mock"]
|
174
170
|
|
175
171
|
const npmLsCommand = "npm ls jest jest-environment-jsdom -g"
|
@@ -186,7 +182,7 @@ export const checkNotInstalledDependencies = async (
|
|
186
182
|
jestNeeded = true
|
187
183
|
}
|
188
184
|
|
189
|
-
if ("@learnpack/python"
|
185
|
+
if (neededPlugins.includes("@learnpack/python")) {
|
190
186
|
pytestNeeded = true
|
191
187
|
}
|
192
188
|
|
@@ -225,6 +221,8 @@ return true
|
|
225
221
|
}
|
226
222
|
|
227
223
|
if (pytestNeeded) {
|
224
|
+
console.log("Trying to install pytest dependencies")
|
225
|
+
|
228
226
|
const { stdout, stderr } = await exec("pip list")
|
229
227
|
if (stderr) {
|
230
228
|
Console.error(`Error executing pip list. Use debug for more info`)
|
package/src/utils/errors.ts
CHANGED
@@ -1,117 +1,117 @@
|
|
1
|
-
import Console from './console'
|
2
|
-
|
3
|
-
import {ISolution, IError} from '../models/errors'
|
4
|
-
|
5
|
-
// eslint-disable-next-line
|
6
|
-
const fetch = require("node-fetch");
|
7
|
-
|
8
|
-
let solutions: { [key: string]: ISolution } | null = null
|
9
|
-
|
10
|
-
const uknown: ISolution = {
|
11
|
-
video: 'https://www.youtube.com/watch?v=gD1Sa99GiE4',
|
12
|
-
message: 'Uknown internal error',
|
13
|
-
slug: 'uknown',
|
14
|
-
gif: 'https://github.com/breatheco-de/breathecode-cli/blob/master/docs/errors/uknown.gif?raw=true',
|
15
|
-
}
|
16
|
-
|
17
|
-
export const getSolution = (slug?: string): ISolution => {
|
18
|
-
if (!slug) {
|
19
|
-
Console.debug('Getting solution templates from the learnpack repository')
|
20
|
-
} else {
|
21
|
-
Console.debug(`Getting solution for ${slug}`, solutions)
|
22
|
-
}
|
23
|
-
|
24
|
-
if (!solutions) {
|
25
|
-
Console.debug('Fetching for errors.json on github')
|
26
|
-
fetch(
|
27
|
-
'https://raw.githubusercontent.com/breatheco-de/breathecode-cli/master/docs/errors/errors.json',
|
28
|
-
)
|
29
|
-
.then((r: Response) => r.json())
|
30
|
-
.then(function (_s: { [key: string]: ISolution }) {
|
31
|
-
solutions = _s
|
32
|
-
})
|
33
|
-
return uknown
|
34
|
-
}
|
35
|
-
|
36
|
-
return typeof solutions[slug || ''] === 'undefined' || !slug ?
|
37
|
-
uknown :
|
38
|
-
solutions[slug]
|
39
|
-
}
|
40
|
-
|
41
|
-
export const ValidationError = (error: IError | string) => {
|
42
|
-
const message: string = (error as IError).message || (error as string)
|
43
|
-
const _err = new Error(message) as IError
|
44
|
-
_err.status = 400
|
45
|
-
_err.type = 'validation-error'
|
46
|
-
|
47
|
-
const sol: ISolution = getSolution((error as IError).slug)
|
48
|
-
_err.video = sol.video
|
49
|
-
_err.gif = sol.gif
|
50
|
-
_err.message = typeof message === 'string' ? message : sol.message
|
51
|
-
return _err
|
52
|
-
}
|
53
|
-
|
54
|
-
export const NotFoundError = (error: IError | string) => {
|
55
|
-
const message = (error as IError).message || (error as string)
|
56
|
-
const _err = new Error(message) as IError
|
57
|
-
_err.status = 400
|
58
|
-
_err.type = 'not-found-error'
|
59
|
-
|
60
|
-
const sol = getSolution((error as IError).slug)
|
61
|
-
_err.video = sol.video
|
62
|
-
_err.gif = sol.gif
|
63
|
-
_err.message = typeof message === 'string' ? message : sol.message
|
64
|
-
return _err
|
65
|
-
}
|
66
|
-
|
67
|
-
export const CompilerError = (error: IError | string) => {
|
68
|
-
const message = (error as IError).message || (error as string)
|
69
|
-
const _err = new Error(message) as IError
|
70
|
-
_err.status = 400
|
71
|
-
_err.type = 'compiler-error'
|
72
|
-
|
73
|
-
const sol = getSolution((error as IError).slug)
|
74
|
-
_err.video = sol.video
|
75
|
-
_err.gif = sol.gif
|
76
|
-
_err.message = typeof message === 'string' ? message : sol.message
|
77
|
-
return _err
|
78
|
-
}
|
79
|
-
|
80
|
-
export const TestingError = (error: IError | string) => {
|
81
|
-
const message = (error as IError).message || (error as string)
|
82
|
-
const _err = new Error(message) as IError
|
83
|
-
_err.status = 400
|
84
|
-
_err.type = 'testing-error'
|
85
|
-
return _err
|
86
|
-
}
|
87
|
-
|
88
|
-
export const AuthError = (error: IError | string) => {
|
89
|
-
const message = (error as IError).message || (error as string)
|
90
|
-
const _err = new Error(message) as IError
|
91
|
-
_err.status = 403
|
92
|
-
_err.type = 'auth-error'
|
93
|
-
return _err
|
94
|
-
}
|
95
|
-
|
96
|
-
export const InternalError = (error: IError | string) => {
|
97
|
-
const message = (error as IError).message || (error as string)
|
98
|
-
const _err = new Error(message) as IError
|
99
|
-
_err.status = 500
|
100
|
-
_err.type = 'internal-error'
|
101
|
-
|
102
|
-
const sol = getSolution((error as IError).slug)
|
103
|
-
_err.video = sol.video
|
104
|
-
_err.gif = sol.gif
|
105
|
-
_err.message = typeof message === 'string' ? message : sol.message
|
106
|
-
return _err
|
107
|
-
}
|
108
|
-
|
109
|
-
getSolution()
|
110
|
-
export default {
|
111
|
-
ValidationError,
|
112
|
-
CompilerError,
|
113
|
-
TestingError,
|
114
|
-
NotFoundError,
|
115
|
-
InternalError,
|
116
|
-
AuthError,
|
117
|
-
}
|
1
|
+
import Console from './console'
|
2
|
+
|
3
|
+
import {ISolution, IError} from '../models/errors'
|
4
|
+
|
5
|
+
// eslint-disable-next-line
|
6
|
+
const fetch = require("node-fetch");
|
7
|
+
|
8
|
+
let solutions: { [key: string]: ISolution } | null = null
|
9
|
+
|
10
|
+
const uknown: ISolution = {
|
11
|
+
video: 'https://www.youtube.com/watch?v=gD1Sa99GiE4',
|
12
|
+
message: 'Uknown internal error',
|
13
|
+
slug: 'uknown',
|
14
|
+
gif: 'https://github.com/breatheco-de/breathecode-cli/blob/master/docs/errors/uknown.gif?raw=true',
|
15
|
+
}
|
16
|
+
|
17
|
+
export const getSolution = (slug?: string): ISolution => {
|
18
|
+
if (!slug) {
|
19
|
+
Console.debug('Getting solution templates from the learnpack repository')
|
20
|
+
} else {
|
21
|
+
Console.debug(`Getting solution for ${slug}`, solutions)
|
22
|
+
}
|
23
|
+
|
24
|
+
if (!solutions) {
|
25
|
+
Console.debug('Fetching for errors.json on github')
|
26
|
+
fetch(
|
27
|
+
'https://raw.githubusercontent.com/breatheco-de/breathecode-cli/master/docs/errors/errors.json',
|
28
|
+
)
|
29
|
+
.then((r: Response) => r.json())
|
30
|
+
.then(function (_s: { [key: string]: ISolution }) {
|
31
|
+
solutions = _s
|
32
|
+
})
|
33
|
+
return uknown
|
34
|
+
}
|
35
|
+
|
36
|
+
return typeof solutions[slug || ''] === 'undefined' || !slug ?
|
37
|
+
uknown :
|
38
|
+
solutions[slug]
|
39
|
+
}
|
40
|
+
|
41
|
+
export const ValidationError = (error: IError | string) => {
|
42
|
+
const message: string = (error as IError).message || (error as string)
|
43
|
+
const _err = new Error(message) as IError
|
44
|
+
_err.status = 400
|
45
|
+
_err.type = 'validation-error'
|
46
|
+
|
47
|
+
const sol: ISolution = getSolution((error as IError).slug)
|
48
|
+
_err.video = sol.video
|
49
|
+
_err.gif = sol.gif
|
50
|
+
_err.message = typeof message === 'string' ? message : sol.message
|
51
|
+
return _err
|
52
|
+
}
|
53
|
+
|
54
|
+
export const NotFoundError = (error: IError | string) => {
|
55
|
+
const message = (error as IError).message || (error as string)
|
56
|
+
const _err = new Error(message) as IError
|
57
|
+
_err.status = 400
|
58
|
+
_err.type = 'not-found-error'
|
59
|
+
|
60
|
+
const sol = getSolution((error as IError).slug)
|
61
|
+
_err.video = sol.video
|
62
|
+
_err.gif = sol.gif
|
63
|
+
_err.message = typeof message === 'string' ? message : sol.message
|
64
|
+
return _err
|
65
|
+
}
|
66
|
+
|
67
|
+
export const CompilerError = (error: IError | string) => {
|
68
|
+
const message = (error as IError).message || (error as string)
|
69
|
+
const _err = new Error(message) as IError
|
70
|
+
_err.status = 400
|
71
|
+
_err.type = 'compiler-error'
|
72
|
+
|
73
|
+
const sol = getSolution((error as IError).slug)
|
74
|
+
_err.video = sol.video
|
75
|
+
_err.gif = sol.gif
|
76
|
+
_err.message = typeof message === 'string' ? message : sol.message
|
77
|
+
return _err
|
78
|
+
}
|
79
|
+
|
80
|
+
export const TestingError = (error: IError | string) => {
|
81
|
+
const message = (error as IError).message || (error as string)
|
82
|
+
const _err = new Error(message) as IError
|
83
|
+
_err.status = 400
|
84
|
+
_err.type = 'testing-error'
|
85
|
+
return _err
|
86
|
+
}
|
87
|
+
|
88
|
+
export const AuthError = (error: IError | string) => {
|
89
|
+
const message = (error as IError).message || (error as string)
|
90
|
+
const _err = new Error(message) as IError
|
91
|
+
_err.status = 403
|
92
|
+
_err.type = 'auth-error'
|
93
|
+
return _err
|
94
|
+
}
|
95
|
+
|
96
|
+
export const InternalError = (error: IError | string) => {
|
97
|
+
const message = (error as IError).message || (error as string)
|
98
|
+
const _err = new Error(message) as IError
|
99
|
+
_err.status = 500
|
100
|
+
_err.type = 'internal-error'
|
101
|
+
|
102
|
+
const sol = getSolution((error as IError).slug)
|
103
|
+
_err.video = sol.video
|
104
|
+
_err.gif = sol.gif
|
105
|
+
_err.message = typeof message === 'string' ? message : sol.message
|
106
|
+
return _err
|
107
|
+
}
|
108
|
+
|
109
|
+
getSolution()
|
110
|
+
export default {
|
111
|
+
ValidationError,
|
112
|
+
CompilerError,
|
113
|
+
TestingError,
|
114
|
+
NotFoundError,
|
115
|
+
InternalError,
|
116
|
+
AuthError,
|
117
|
+
}
|
@@ -1,51 +1,51 @@
|
|
1
|
-
import { IConfig } from "../models/config"
|
2
|
-
import { IExercise } from "../models/exercise-obj"
|
3
|
-
import { ISocket } from "../models/socket"
|
4
|
-
|
5
|
-
class Exercise {
|
6
|
-
exercise: IExercise
|
7
|
-
constructor(exercise: IExercise) {
|
8
|
-
this.exercise = exercise
|
9
|
-
}
|
10
|
-
|
11
|
-
test(sessionConfig: IConfig, config: IConfig, socket: ISocket) {
|
12
|
-
if (this.exercise.language) {
|
13
|
-
socket.log(
|
14
|
-
"testing",
|
15
|
-
`Testing exercise ${this.exercise.slug} using ${this.exercise.language} engine`
|
16
|
-
)
|
17
|
-
|
18
|
-
sessionConfig.runHook("action", {
|
19
|
-
action: "test",
|
20
|
-
socket,
|
21
|
-
configuration: config,
|
22
|
-
exercise: this.exercise,
|
23
|
-
})
|
24
|
-
} else {
|
25
|
-
socket.onTestingFinished({ result: "success" })
|
26
|
-
}
|
27
|
-
}
|
28
|
-
}
|
29
|
-
|
30
|
-
class ExercisesQueue {
|
31
|
-
exercises: IExercise[]
|
32
|
-
constructor(exercises: any) {
|
33
|
-
this.exercises = exercises.map((exercise: IExercise) => {
|
34
|
-
return new Exercise(exercise)
|
35
|
-
})
|
36
|
-
}
|
37
|
-
|
38
|
-
pop() {
|
39
|
-
return this.exercises.shift()
|
40
|
-
}
|
41
|
-
|
42
|
-
isEmpty() {
|
43
|
-
return this.size() === 0
|
44
|
-
}
|
45
|
-
|
46
|
-
size() {
|
47
|
-
return this.exercises.length
|
48
|
-
}
|
49
|
-
}
|
50
|
-
|
51
|
-
export default ExercisesQueue
|
1
|
+
import { IConfig } from "../models/config"
|
2
|
+
import { IExercise } from "../models/exercise-obj"
|
3
|
+
import { ISocket } from "../models/socket"
|
4
|
+
|
5
|
+
class Exercise {
|
6
|
+
exercise: IExercise
|
7
|
+
constructor(exercise: IExercise) {
|
8
|
+
this.exercise = exercise
|
9
|
+
}
|
10
|
+
|
11
|
+
test(sessionConfig: IConfig, config: IConfig, socket: ISocket) {
|
12
|
+
if (this.exercise.language) {
|
13
|
+
socket.log(
|
14
|
+
"testing",
|
15
|
+
`Testing exercise ${this.exercise.slug} using ${this.exercise.language} engine`
|
16
|
+
)
|
17
|
+
|
18
|
+
sessionConfig.runHook("action", {
|
19
|
+
action: "test",
|
20
|
+
socket,
|
21
|
+
configuration: config,
|
22
|
+
exercise: this.exercise,
|
23
|
+
})
|
24
|
+
} else {
|
25
|
+
socket.onTestingFinished({ result: "success" })
|
26
|
+
}
|
27
|
+
}
|
28
|
+
}
|
29
|
+
|
30
|
+
class ExercisesQueue {
|
31
|
+
exercises: IExercise[]
|
32
|
+
constructor(exercises: any) {
|
33
|
+
this.exercises = exercises.map((exercise: IExercise) => {
|
34
|
+
return new Exercise(exercise)
|
35
|
+
})
|
36
|
+
}
|
37
|
+
|
38
|
+
pop() {
|
39
|
+
return this.exercises.shift()
|
40
|
+
}
|
41
|
+
|
42
|
+
isEmpty() {
|
43
|
+
return this.size() === 0
|
44
|
+
}
|
45
|
+
|
46
|
+
size() {
|
47
|
+
return this.exercises.length
|
48
|
+
}
|
49
|
+
}
|
50
|
+
|
51
|
+
export default ExercisesQueue
|