@learnpack/learnpack 2.1.26 → 2.1.27
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +10 -10
- package/oclif.manifest.json +1 -1
- package/package.json +2 -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/lib/commands/audit.d.ts +0 -6
- package/lib/commands/audit.js +0 -342
- package/lib/commands/clean.d.ts +0 -8
- package/lib/commands/clean.js +0 -25
- package/lib/commands/download.d.ts +0 -13
- package/lib/commands/download.js +0 -55
- package/lib/commands/init.d.ts +0 -9
- package/lib/commands/init.js +0 -123
- package/lib/commands/login.d.ts +0 -14
- package/lib/commands/login.js +0 -37
- package/lib/commands/logout.d.ts +0 -14
- package/lib/commands/logout.js +0 -37
- package/lib/commands/publish.d.ts +0 -14
- package/lib/commands/publish.js +0 -82
- package/lib/commands/start.d.ts +0 -7
- package/lib/commands/start.js +0 -165
- package/lib/commands/test.d.ts +0 -6
- package/lib/commands/test.js +0 -62
- package/lib/index.d.ts +0 -1
- package/lib/index.js +0 -4
- package/lib/managers/config/allowed_files.d.ts +0 -5
- package/lib/managers/config/allowed_files.js +0 -30
- package/lib/managers/config/defaults.d.ts +0 -39
- package/lib/managers/config/defaults.js +0 -40
- package/lib/managers/config/exercise.d.ts +0 -36
- package/lib/managers/config/exercise.js +0 -233
- package/lib/managers/config/index.d.ts +0 -3
- package/lib/managers/config/index.js +0 -320
- package/lib/managers/file.d.ts +0 -13
- package/lib/managers/file.js +0 -134
- package/lib/managers/gitpod.d.ts +0 -3
- package/lib/managers/gitpod.js +0 -67
- package/lib/managers/server/index.d.ts +0 -6
- package/lib/managers/server/index.js +0 -58
- package/lib/managers/server/routes.d.ts +0 -4
- package/lib/managers/server/routes.js +0 -167
- package/lib/managers/session.d.ts +0 -3
- package/lib/managers/session.js +0 -104
- package/lib/managers/socket.d.ts +0 -3
- package/lib/managers/socket.js +0 -164
- package/lib/managers/test.d.ts +0 -0
- package/lib/managers/test.js +0 -84
- package/lib/models/action.d.ts +0 -2
- package/lib/models/action.js +0 -2
- package/lib/models/audit.d.ts +0 -15
- package/lib/models/audit.js +0 -2
- package/lib/models/config-manager.d.ts +0 -21
- package/lib/models/config-manager.js +0 -2
- package/lib/models/config.d.ts +0 -62
- package/lib/models/config.js +0 -2
- package/lib/models/counter.d.ts +0 -11
- package/lib/models/counter.js +0 -2
- package/lib/models/errors.d.ts +0 -15
- package/lib/models/errors.js +0 -2
- package/lib/models/exercise-obj.d.ts +0 -27
- package/lib/models/exercise-obj.js +0 -2
- package/lib/models/file.d.ts +0 -5
- package/lib/models/file.js +0 -2
- package/lib/models/findings.d.ts +0 -17
- package/lib/models/findings.js +0 -2
- package/lib/models/flags.d.ts +0 -10
- package/lib/models/flags.js +0 -2
- package/lib/models/front-matter.d.ts +0 -11
- package/lib/models/front-matter.js +0 -2
- package/lib/models/gitpod-data.d.ts +0 -16
- package/lib/models/gitpod-data.js +0 -2
- package/lib/models/language.d.ts +0 -4
- package/lib/models/language.js +0 -2
- package/lib/models/package.d.ts +0 -7
- package/lib/models/package.js +0 -2
- package/lib/models/plugin-config.d.ts +0 -16
- package/lib/models/plugin-config.js +0 -2
- package/lib/models/session.d.ts +0 -23
- package/lib/models/session.js +0 -2
- package/lib/models/socket.d.ts +0 -31
- package/lib/models/socket.js +0 -2
- package/lib/models/status.d.ts +0 -1
- package/lib/models/status.js +0 -2
- package/lib/models/success-types.d.ts +0 -1
- package/lib/models/success-types.js +0 -2
- package/lib/plugin/command/compile.d.ts +0 -6
- package/lib/plugin/command/compile.js +0 -18
- package/lib/plugin/command/test.d.ts +0 -6
- package/lib/plugin/command/test.js +0 -25
- package/lib/plugin/index.d.ts +0 -27
- package/lib/plugin/index.js +0 -7
- package/lib/plugin/plugin.d.ts +0 -8
- package/lib/plugin/plugin.js +0 -68
- package/lib/plugin/utils.d.ts +0 -16
- package/lib/plugin/utils.js +0 -58
- package/lib/ui/download.d.ts +0 -5
- package/lib/ui/download.js +0 -61
- package/lib/utils/BaseCommand.d.ts +0 -8
- package/lib/utils/BaseCommand.js +0 -41
- package/lib/utils/SessionCommand.d.ts +0 -10
- package/lib/utils/SessionCommand.js +0 -47
- package/lib/utils/api.d.ts +0 -12
- package/lib/utils/api.js +0 -173
- package/lib/utils/audit.d.ts +0 -16
- package/lib/utils/audit.js +0 -302
- package/lib/utils/console.d.ts +0 -12
- package/lib/utils/console.js +0 -19
- package/lib/utils/errors.d.ts +0 -17
- package/lib/utils/errors.js +0 -100
- package/lib/utils/exercisesQueue.d.ts +0 -9
- package/lib/utils/exercisesQueue.js +0 -38
- package/lib/utils/fileQueue.d.ts +0 -40
- package/lib/utils/fileQueue.js +0 -168
- package/lib/utils/misc.d.ts +0 -1
- package/lib/utils/misc.js +0 -23
- package/lib/utils/validators.d.ts +0 -5
- package/lib/utils/validators.js +0 -17
- package/lib/utils/watcher.d.ts +0 -2
- package/lib/utils/watcher.js +0 -23
package/README.md
CHANGED
@@ -21,7 +21,7 @@ $ npm install -g @learnpack/learnpack
|
|
21
21
|
$ learnpack COMMAND
|
22
22
|
running command...
|
23
23
|
$ learnpack (-v|--version|version)
|
24
|
-
@learnpack/learnpack/2.1.
|
24
|
+
@learnpack/learnpack/2.1.27 darwin-arm64 node-v16.20.0
|
25
25
|
$ learnpack --help [COMMAND]
|
26
26
|
USAGE
|
27
27
|
$ learnpack COMMAND
|
@@ -74,7 +74,7 @@ DESCRIPTION
|
|
74
74
|
12. If there is a file within the exercises folder but not inside of any particular exercise's folder. (Warning)
|
75
75
|
```
|
76
76
|
|
77
|
-
_See code: [src/commands/audit.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1.
|
77
|
+
_See code: [src/commands/audit.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1.27/src/commands/audit.ts)_
|
78
78
|
|
79
79
|
## `learnpack clean`
|
80
80
|
|
@@ -89,7 +89,7 @@ DESCRIPTION
|
|
89
89
|
Extra documentation goes here
|
90
90
|
```
|
91
91
|
|
92
|
-
_See code: [src/commands/clean.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1.
|
92
|
+
_See code: [src/commands/clean.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1.27/src/commands/clean.ts)_
|
93
93
|
|
94
94
|
## `learnpack download [PACKAGE]`
|
95
95
|
|
@@ -107,7 +107,7 @@ DESCRIPTION
|
|
107
107
|
Extra documentation goes here
|
108
108
|
```
|
109
109
|
|
110
|
-
_See code: [src/commands/download.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1.
|
110
|
+
_See code: [src/commands/download.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1.27/src/commands/download.ts)_
|
111
111
|
|
112
112
|
## `learnpack help [COMMAND]`
|
113
113
|
|
@@ -138,7 +138,7 @@ OPTIONS
|
|
138
138
|
-h, --grading show CLI help
|
139
139
|
```
|
140
140
|
|
141
|
-
_See code: [src/commands/init.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1.
|
141
|
+
_See code: [src/commands/init.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1.27/src/commands/init.ts)_
|
142
142
|
|
143
143
|
## `learnpack login [PACKAGE]`
|
144
144
|
|
@@ -156,7 +156,7 @@ DESCRIPTION
|
|
156
156
|
Extra documentation goes here
|
157
157
|
```
|
158
158
|
|
159
|
-
_See code: [src/commands/login.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1.
|
159
|
+
_See code: [src/commands/login.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1.27/src/commands/login.ts)_
|
160
160
|
|
161
161
|
## `learnpack logout [PACKAGE]`
|
162
162
|
|
@@ -174,7 +174,7 @@ DESCRIPTION
|
|
174
174
|
Extra documentation goes here
|
175
175
|
```
|
176
176
|
|
177
|
-
_See code: [src/commands/logout.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1.
|
177
|
+
_See code: [src/commands/logout.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1.27/src/commands/logout.ts)_
|
178
178
|
|
179
179
|
## `learnpack plugins`
|
180
180
|
|
@@ -309,7 +309,7 @@ DESCRIPTION
|
|
309
309
|
Extra documentation goes here
|
310
310
|
```
|
311
311
|
|
312
|
-
_See code: [src/commands/publish.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1.
|
312
|
+
_See code: [src/commands/publish.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1.27/src/commands/publish.ts)_
|
313
313
|
|
314
314
|
## `learnpack start`
|
315
315
|
|
@@ -330,7 +330,7 @@ OPTIONS
|
|
330
330
|
-w, --watch Watch for file changes
|
331
331
|
```
|
332
332
|
|
333
|
-
_See code: [src/commands/start.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1.
|
333
|
+
_See code: [src/commands/start.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1.27/src/commands/start.ts)_
|
334
334
|
|
335
335
|
## `learnpack test [EXERCISESLUG]`
|
336
336
|
|
@@ -344,5 +344,5 @@ ARGUMENTS
|
|
344
344
|
EXERCISESLUG The name of the exercise to test
|
345
345
|
```
|
346
346
|
|
347
|
-
_See code: [src/commands/test.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1.
|
347
|
+
_See code: [src/commands/test.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1.27/src/commands/test.ts)_
|
348
348
|
<!-- commandsstop -->
|
package/oclif.manifest.json
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":"2.1.
|
1
|
+
{"version":"2.1.27","commands":{"audit":{"id":"audit","description":"learnpack audit is the command in charge of creating an auditory of the repository\n...\nlearnpack audit checks for the following information in a repository:\n 1. The configuration object has slug, repository and description. (Error)\n 2. The command learnpack clean has been run. (Error)\n 3. If a markdown or test file doesn't have any content. (Error)\n 4. The links are accessing to valid servers. (Error)\n 5. The relative images are working (If they have the shortest path to the image or if the images exists in the assets). (Error)\n 6. The external images are working (If they are pointing to a valid server). (Error)\n 7. The exercises directory names are valid. (Error)\n 8. If an exercise doesn't have a README file. (Error)\n 9. The exercises array (Of the config file) has content. (Error)\n 10. The exercses have the same translations. (Warning)\n 11. The .gitignore file exists. (Warning)\n 12. If there is a file within the exercises folder but not inside of any particular exercise's folder. (Warning)\n","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{},"args":[]},"clean":{"id":"clean","description":"Clean the configuration object\n ...\n Extra documentation goes here\n ","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{},"args":[]},"download":{"id":"download","description":"Describe the command here\n...\nExtra documentation goes here\n","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{},"args":[{"name":"package","description":"The unique string that identifies this package on learnpack","required":false,"hidden":false}]},"init":{"id":"init","description":"Create a new learning package: Book, Tutorial or Exercise","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{"grading":{"name":"grading","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[]},"login":{"id":"login","description":"Describe the command here\n ...\n Extra documentation goes here\n ","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{},"args":[{"name":"package","description":"The unique string that identifies this package on learnpack","required":false,"hidden":false}]},"logout":{"id":"logout","description":"Describe the command here\n ...\n Extra documentation goes here\n ","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{},"args":[{"name":"package","description":"The unique string that identifies this package on learnpack","required":false,"hidden":false}]},"publish":{"id":"publish","description":"Describe the command here\n ...\n Extra documentation goes here\n ","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{},"args":[{"name":"package","description":"The unique string that identifies this package on learnpack","required":false,"hidden":false}]},"start":{"id":"start","description":"Runs a small server with all the exercise instructions","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{"port":{"name":"port","type":"option","char":"p","description":"server port"},"host":{"name":"host","type":"option","char":"h","description":"server host"},"disableGrading":{"name":"disableGrading","type":"boolean","char":"D","description":"disble grading functionality","allowNo":false},"watch":{"name":"watch","type":"boolean","char":"w","description":"Watch for file changes","allowNo":false},"editor":{"name":"editor","type":"option","char":"e","description":"[standalone, gitpod]","options":["standalone","gitpod"]},"version":{"name":"version","type":"option","char":"v","description":"E.g: 1.0.1"},"grading":{"name":"grading","type":"option","char":"g","description":"[isolated, incremental]","options":["isolated","incremental"]},"debug":{"name":"debug","type":"boolean","char":"d","description":"debugger mode for more verbage","allowNo":false}},"args":[]},"test":{"id":"test","description":"Test exercises","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{},"args":[{"name":"exerciseSlug","description":"The name of the exercise to test","required":false,"hidden":false}]}}}
|
package/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"name": "@learnpack/learnpack",
|
3
3
|
"description": "Create, sell or download and take learning amazing learning packages",
|
4
|
-
"version": "2.1.
|
4
|
+
"version": "2.1.27",
|
5
5
|
"author": "Alejandro Sanchez @alesanchezr",
|
6
6
|
"bin": {
|
7
7
|
"learnpack": "bin/run"
|
@@ -67,6 +67,7 @@
|
|
67
67
|
"fs-extra": "^10.0.1",
|
68
68
|
"globby": "^10.0.2",
|
69
69
|
"husky": ">=6",
|
70
|
+
"learnpack-node": "^0.0.21",
|
70
71
|
"lint-staged": ">=10",
|
71
72
|
"mocha": "^5.2.0",
|
72
73
|
"mock-fs": "^5.1.2",
|
package/src/commands/audit.ts
CHANGED
@@ -1,34 +1,34 @@
|
|
1
|
-
import * as fs from "fs"
|
2
|
-
import { validateExerciseDirectoryName } from "../managers/config/exercise"
|
3
|
-
import Console from "../utils/console"
|
4
|
-
import Audit from "../utils/audit"
|
5
|
-
import SessionCommand from "../utils/SessionCommand"
|
6
|
-
import * as path from "path"
|
7
|
-
import { IFile } from "../models/file"
|
8
|
-
import { IExercise } from "../models/exercise-obj"
|
9
|
-
import { IFrontmatter } from "../models/front-matter"
|
10
|
-
import { IAuditErrors } from "../models/audit"
|
11
|
-
import { ICounter } from "../models/counter"
|
12
|
-
import { IFindings } from "../models/findings"
|
1
|
+
import * as fs from "fs"
|
2
|
+
import { validateExerciseDirectoryName } from "../managers/config/exercise"
|
3
|
+
import Console from "../utils/console"
|
4
|
+
import Audit from "../utils/audit"
|
5
|
+
import SessionCommand from "../utils/SessionCommand"
|
6
|
+
import * as path from "path"
|
7
|
+
import { IFile } from "../models/file"
|
8
|
+
import { IExercise } from "../models/exercise-obj"
|
9
|
+
import { IFrontmatter } from "../models/front-matter"
|
10
|
+
import { IAuditErrors } from "../models/audit"
|
11
|
+
import { ICounter } from "../models/counter"
|
12
|
+
import { IFindings } from "../models/findings"
|
13
13
|
|
14
14
|
// eslint-disable-next-line
|
15
15
|
const fetch = require("node-fetch");
|
16
16
|
|
17
17
|
class AuditCommand extends SessionCommand {
|
18
18
|
async init() {
|
19
|
-
const { flags } = this.parse(AuditCommand)
|
20
|
-
await this.initSession(flags)
|
19
|
+
const { flags } = this.parse(AuditCommand)
|
20
|
+
await this.initSession(flags)
|
21
21
|
}
|
22
22
|
|
23
23
|
async run() {
|
24
|
-
Console.log("Running command audit...")
|
24
|
+
Console.log("Running command audit...")
|
25
25
|
|
26
26
|
// Get configuration object.
|
27
|
-
let config = this.configManager?.get()
|
27
|
+
let config = this.configManager?.get()
|
28
28
|
|
29
29
|
if (config) {
|
30
|
-
const errors: IAuditErrors[] = []
|
31
|
-
const warnings: IAuditErrors[] = []
|
30
|
+
const errors: IAuditErrors[] = []
|
31
|
+
const warnings: IAuditErrors[] = []
|
32
32
|
if (config?.config?.projectType === "tutorial") {
|
33
33
|
const counter: ICounter = {
|
34
34
|
images: {
|
@@ -41,34 +41,34 @@ class AuditCommand extends SessionCommand {
|
|
41
41
|
},
|
42
42
|
exercises: 0,
|
43
43
|
readmeFiles: 0,
|
44
|
-
}
|
44
|
+
}
|
45
45
|
|
46
46
|
// Checks if learnpack clean has been run
|
47
|
-
Audit.checkLearnpackClean(config, errors)
|
47
|
+
Audit.checkLearnpackClean(config, errors)
|
48
48
|
|
49
49
|
// Build exercises if they are not built yet.
|
50
|
-
this.configManager?.buildIndex()
|
51
|
-
config = this.configManager?.get()
|
50
|
+
this.configManager?.buildIndex()
|
51
|
+
config = this.configManager?.get()
|
52
52
|
|
53
53
|
// Check if the exercises folder has some files within any ./exercise
|
54
|
-
const exercisesPath: string = config!.config!.exercisesPath
|
54
|
+
const exercisesPath: string = config!.config!.exercisesPath
|
55
55
|
|
56
56
|
fs.readdir(exercisesPath, (err, files) => {
|
57
57
|
if (err) {
|
58
|
-
return console.log("Unable to scan directory: " + err)
|
58
|
+
return console.log("Unable to scan directory: " + err)
|
59
59
|
}
|
60
60
|
|
61
61
|
// listing all files using forEach
|
62
62
|
for (const file of files) {
|
63
63
|
// Do whatever you want to do with the file
|
64
|
-
const filePath: string = path.join(exercisesPath, file)
|
64
|
+
const filePath: string = path.join(exercisesPath, file)
|
65
65
|
if (fs.statSync(filePath).isFile())
|
66
66
|
warnings.push({
|
67
67
|
exercise: file!,
|
68
68
|
msg: "This file is not inside any exercise folder.",
|
69
|
-
})
|
69
|
+
})
|
70
70
|
}
|
71
|
-
})
|
71
|
+
})
|
72
72
|
|
73
73
|
// This function is being created because the find method doesn't work with promises.
|
74
74
|
const find = async (file: IFile, lang: string, exercise: IExercise) => {
|
@@ -81,96 +81,96 @@ class AuditCommand extends SessionCommand {
|
|
81
81
|
errors,
|
82
82
|
warnings,
|
83
83
|
counter
|
84
|
-
)
|
85
|
-
return true
|
84
|
+
)
|
85
|
+
return true
|
86
86
|
}
|
87
87
|
|
88
|
-
return false
|
89
|
-
}
|
88
|
+
return false
|
89
|
+
}
|
90
90
|
|
91
|
-
Console.debug("config", config)
|
91
|
+
Console.debug("config", config)
|
92
92
|
|
93
|
-
Console.info(" Checking if the config file is fine...")
|
93
|
+
Console.info(" Checking if the config file is fine...")
|
94
94
|
// These two lines check if the 'slug' property is inside the configuration object.
|
95
95
|
Console.debug(
|
96
96
|
"Checking if the slug property is inside the configuration object..."
|
97
|
-
)
|
97
|
+
)
|
98
98
|
// check if the slug property is in the configuration object
|
99
99
|
if (!config!.config?.slug)
|
100
100
|
errors.push({
|
101
101
|
exercise: undefined,
|
102
102
|
msg: "The slug property is not in the configuration object",
|
103
|
-
})
|
103
|
+
})
|
104
104
|
// check if the duration property is in the configuration object
|
105
105
|
if (!config!.config?.duration)
|
106
106
|
warnings.push({
|
107
107
|
exercise: undefined,
|
108
108
|
msg: "The duration property is not in the configuration object",
|
109
|
-
})
|
109
|
+
})
|
110
110
|
// check if the difficulty property is in the configuration object
|
111
111
|
if (!config!.config?.difficulty)
|
112
112
|
warnings.push({
|
113
113
|
exercise: undefined,
|
114
114
|
msg: "The difficulty property is not in the configuration object",
|
115
|
-
})
|
115
|
+
})
|
116
116
|
// check if the bugs_link property is in the configuration object
|
117
117
|
if (!config!.config?.bugsLink)
|
118
118
|
errors.push({
|
119
119
|
exercise: undefined,
|
120
120
|
msg: "The bugsLink property is not in the configuration object",
|
121
|
-
})
|
121
|
+
})
|
122
122
|
// check if the video_solutions property is in the configuration object
|
123
123
|
if (config!.config?.videoSolutions === undefined)
|
124
124
|
warnings.push({
|
125
125
|
exercise: undefined,
|
126
126
|
msg: "The videoSolutions property is not in the configuration object",
|
127
|
-
})
|
127
|
+
})
|
128
128
|
|
129
129
|
// These two lines check if the 'repository' property is inside the configuration object.
|
130
130
|
Console.debug(
|
131
131
|
"Checking if the repository property is inside the configuration object..."
|
132
|
-
)
|
132
|
+
)
|
133
133
|
if (!config!.config?.repository)
|
134
134
|
errors.push({
|
135
135
|
exercise: undefined,
|
136
136
|
msg: "The repository property is not in the configuration object",
|
137
|
-
})
|
137
|
+
})
|
138
138
|
else
|
139
|
-
Audit.isUrl(config!.config?.repository, errors, counter)
|
139
|
+
Audit.isUrl(config!.config?.repository, errors, counter)
|
140
140
|
|
141
141
|
// These two lines check if the 'description' property is inside the configuration object.
|
142
142
|
Console.debug(
|
143
143
|
"Checking if the description property is inside the configuration object..."
|
144
|
-
)
|
144
|
+
)
|
145
145
|
if (!config!.config?.description)
|
146
146
|
errors.push({
|
147
147
|
exercise: undefined,
|
148
148
|
msg: "The description property is not in the configuration object",
|
149
|
-
})
|
149
|
+
})
|
150
150
|
|
151
151
|
if (errors.length === 0)
|
152
|
-
Console.log("The config file is ok")
|
152
|
+
Console.log("The config file is ok")
|
153
153
|
|
154
154
|
// Validates if images and links are working at every README file.
|
155
|
-
const exercises = config!.exercises
|
156
|
-
const readmeFiles = []
|
155
|
+
const exercises = config!.exercises
|
156
|
+
const readmeFiles = []
|
157
157
|
|
158
158
|
if (exercises && exercises.length > 0) {
|
159
|
-
Console.info(" Checking if the images are working...")
|
159
|
+
Console.info(" Checking if the images are working...")
|
160
160
|
for (const index in exercises) {
|
161
161
|
if (Object.prototype.hasOwnProperty.call(exercises, index)) {
|
162
|
-
const exercise = exercises[index]
|
162
|
+
const exercise = exercises[index]
|
163
163
|
if (!validateExerciseDirectoryName(exercise.title))
|
164
164
|
errors.push({
|
165
165
|
exercise: exercise.title,
|
166
166
|
msg: `The exercise ${exercise.title} has an invalid name.`,
|
167
|
-
})
|
168
|
-
let readmeFilesCount = { exercise: exercise.title, count: 0 }
|
167
|
+
})
|
168
|
+
let readmeFilesCount = { exercise: exercise.title, count: 0 }
|
169
169
|
if (Object.keys(exercise.translations!).length === 0)
|
170
170
|
errors.push({
|
171
171
|
exercise: exercise.title,
|
172
172
|
msg: `The exercise ${exercise.title} doesn't have a README.md file.`,
|
173
|
-
})
|
173
|
+
})
|
174
174
|
|
175
175
|
if (
|
176
176
|
exercise.language === "python3" ||
|
@@ -181,13 +181,13 @@ Console.log("The config file is ok");
|
|
181
181
|
f.path.includes("test.py") ||
|
182
182
|
f.path.includes("tests.py")
|
183
183
|
) {
|
184
|
-
const content = fs.readFileSync(f.path).toString()
|
185
|
-
const isEmpty = Audit.checkForEmptySpaces(content)
|
184
|
+
const content = fs.readFileSync(f.path).toString()
|
185
|
+
const isEmpty = Audit.checkForEmptySpaces(content)
|
186
186
|
if (isEmpty || !content)
|
187
187
|
errors.push({
|
188
188
|
exercise: exercise.title,
|
189
189
|
msg: `This file (${f.name}) doesn't have any content inside.`,
|
190
|
-
})
|
190
|
+
})
|
191
191
|
}
|
192
192
|
}
|
193
193
|
} else {
|
@@ -196,13 +196,13 @@ Console.log("The config file is ok");
|
|
196
196
|
f.path.includes("test.js") ||
|
197
197
|
f.path.includes("tests.js")
|
198
198
|
) {
|
199
|
-
const content = fs.readFileSync(f.path).toString()
|
200
|
-
const isEmpty: boolean = Audit.checkForEmptySpaces(content)
|
199
|
+
const content = fs.readFileSync(f.path).toString()
|
200
|
+
const isEmpty: boolean = Audit.checkForEmptySpaces(content)
|
201
201
|
if (isEmpty || !content)
|
202
202
|
errors.push({
|
203
203
|
exercise: exercise.title,
|
204
204
|
msg: `This file (${f.name}) doesn't have any content inside.`,
|
205
|
-
})
|
205
|
+
})
|
206
206
|
}
|
207
207
|
}
|
208
208
|
}
|
@@ -214,15 +214,15 @@ Console.log("The config file is ok");
|
|
214
214
|
lang
|
215
215
|
)
|
216
216
|
) {
|
217
|
-
const files: any[] = []
|
218
|
-
const findResultPromises = []
|
217
|
+
const files: any[] = []
|
218
|
+
const findResultPromises = []
|
219
219
|
for (const file of exercise.files) {
|
220
220
|
const found = find(
|
221
221
|
file,
|
222
222
|
exercise.translations[lang],
|
223
223
|
exercise
|
224
|
-
)
|
225
|
-
findResultPromises.push(found)
|
224
|
+
)
|
225
|
+
findResultPromises.push(found)
|
226
226
|
}
|
227
227
|
// eslint-disable-next-line
|
228
228
|
let findResults = await Promise.all(findResultPromises);
|
@@ -231,8 +231,8 @@ Console.log("The config file is ok");
|
|
231
231
|
readmeFilesCount = {
|
232
232
|
...readmeFilesCount,
|
233
233
|
count: readmeFilesCount.count + 1,
|
234
|
-
}
|
235
|
-
files.push(found)
|
234
|
+
}
|
235
|
+
files.push(found)
|
236
236
|
}
|
237
237
|
}
|
238
238
|
|
@@ -240,50 +240,50 @@ Console.log("The config file is ok");
|
|
240
240
|
errors.push({
|
241
241
|
exercise: exercise.title,
|
242
242
|
msg: "This exercise doesn't have a README.md file.",
|
243
|
-
})
|
243
|
+
})
|
244
244
|
}
|
245
245
|
}
|
246
246
|
|
247
|
-
readmeFiles.push(readmeFilesCount)
|
247
|
+
readmeFiles.push(readmeFilesCount)
|
248
248
|
}
|
249
249
|
}
|
250
250
|
} else
|
251
251
|
errors.push({
|
252
252
|
exercise: undefined,
|
253
253
|
msg: "The exercises array is empty.",
|
254
|
-
})
|
254
|
+
})
|
255
255
|
|
256
256
|
Console.log(
|
257
257
|
`${counter.images.total - counter.images.error} images ok from ${
|
258
258
|
counter.images.total
|
259
259
|
}`
|
260
|
-
)
|
260
|
+
)
|
261
261
|
|
262
262
|
Console.info(
|
263
263
|
" Checking if important files are missing... (README's, translations, gitignore...)"
|
264
|
-
)
|
264
|
+
)
|
265
265
|
// Check if all the exercises has the same ammount of README's, this way we can check if they have the same ammount of translations.
|
266
|
-
const files: string[] = []
|
267
|
-
let count = 0
|
266
|
+
const files: string[] = []
|
267
|
+
let count = 0
|
268
268
|
for (const item of readmeFiles) {
|
269
269
|
if (count < item.count)
|
270
|
-
count = item.count
|
270
|
+
count = item.count
|
271
271
|
}
|
272
272
|
|
273
273
|
for (const item of readmeFiles) {
|
274
274
|
if (item.count !== count)
|
275
|
-
files.push(` ${item.exercise}`)
|
275
|
+
files.push(` ${item.exercise}`)
|
276
276
|
}
|
277
277
|
|
278
278
|
if (files.length > 0) {
|
279
|
-
const filesString: string = files.join(",")
|
279
|
+
const filesString: string = files.join(",")
|
280
280
|
warnings.push({
|
281
281
|
exercise: undefined,
|
282
282
|
msg:
|
283
283
|
files.length === 1 ?
|
284
284
|
`This exercise is missing translations:${filesString}` :
|
285
285
|
`These exercises are missing translations:${filesString}`,
|
286
|
-
})
|
286
|
+
})
|
287
287
|
}
|
288
288
|
|
289
289
|
// Checks if the .gitignore file exists.
|
@@ -291,11 +291,11 @@ files.push(` ${item.exercise}`);
|
|
291
291
|
warnings.push({
|
292
292
|
exercise: undefined,
|
293
293
|
msg: ".gitignore file doesn't exist",
|
294
|
-
})
|
294
|
+
})
|
295
295
|
|
296
|
-
counter.exercises = exercises!.length
|
296
|
+
counter.exercises = exercises!.length
|
297
297
|
for (const readme of readmeFiles) {
|
298
|
-
counter.readmeFiles += readme.count
|
298
|
+
counter.readmeFiles += readme.count
|
299
299
|
}
|
300
300
|
} else {
|
301
301
|
// This is the audit code for Projects
|
@@ -303,68 +303,68 @@ files.push(` ${item.exercise}`);
|
|
303
303
|
// Getting the learn.json schema
|
304
304
|
const schemaResponse = await fetch(
|
305
305
|
"https://raw.githubusercontent.com/tommygonzaleza/project-template/main/.github/learn-schema.json"
|
306
|
-
)
|
307
|
-
const schema = await schemaResponse.json()
|
306
|
+
)
|
307
|
+
const schema = await schemaResponse.json()
|
308
308
|
|
309
309
|
// Checking the "learn.json" file:
|
310
310
|
const learnjson = JSON.parse(
|
311
311
|
fs.readFileSync("./learn.json").toString()
|
312
|
-
)
|
312
|
+
)
|
313
313
|
|
314
314
|
if (!learnjson) {
|
315
315
|
Console.error(
|
316
316
|
"There is no learn.json file located in the root of the project."
|
317
|
-
)
|
318
|
-
process.exit(1)
|
317
|
+
)
|
318
|
+
process.exit(1)
|
319
319
|
}
|
320
320
|
|
321
321
|
// Checking the README.md files and possible translations.
|
322
|
-
let readmeFiles: any[] = []
|
323
|
-
const translations: string[] = []
|
324
|
-
const translationRegex = /README\.([a-z]{2,3})\.md
|
322
|
+
let readmeFiles: any[] = []
|
323
|
+
const translations: string[] = []
|
324
|
+
const translationRegex = /README\.([a-z]{2,3})\.md/
|
325
325
|
|
326
326
|
try {
|
327
|
-
const data = await fs.promises.readdir("./")
|
328
|
-
readmeFiles = data.filter(file => file.includes("README"))
|
327
|
+
const data = await fs.promises.readdir("./")
|
328
|
+
readmeFiles = data.filter(file => file.includes("README"))
|
329
329
|
if (readmeFiles.length === 0)
|
330
330
|
errors.push({
|
331
331
|
exercise: undefined!,
|
332
332
|
msg: `There is no README file in the repository.`,
|
333
|
-
})
|
333
|
+
})
|
334
334
|
} catch (error) {
|
335
335
|
if (error)
|
336
336
|
Console.error(
|
337
337
|
"There was an error getting the directory files",
|
338
338
|
error
|
339
|
-
)
|
339
|
+
)
|
340
340
|
}
|
341
341
|
|
342
342
|
for (const readmeFile of readmeFiles) {
|
343
343
|
// Checking the language of each README file.
|
344
344
|
if (readmeFile === "README.md")
|
345
|
-
translations.push("us")
|
345
|
+
translations.push("us")
|
346
346
|
else {
|
347
|
-
const regexGroups = translationRegex.exec(readmeFile)
|
347
|
+
const regexGroups = translationRegex.exec(readmeFile)
|
348
348
|
if (regexGroups)
|
349
|
-
translations.push(regexGroups[1])
|
349
|
+
translations.push(regexGroups[1])
|
350
350
|
}
|
351
351
|
|
352
|
-
const readme = fs.readFileSync(path.resolve(readmeFile)).toString()
|
352
|
+
const readme = fs.readFileSync(path.resolve(readmeFile)).toString()
|
353
353
|
|
354
|
-
const isEmpty = Audit.checkForEmptySpaces(readme)
|
354
|
+
const isEmpty = Audit.checkForEmptySpaces(readme)
|
355
355
|
if (isEmpty || !readme) {
|
356
356
|
errors.push({
|
357
357
|
exercise: undefined!,
|
358
358
|
msg: `This file "${readmeFile}" doesn't have any content inside.`,
|
359
|
-
})
|
360
|
-
continue
|
359
|
+
})
|
360
|
+
continue
|
361
361
|
}
|
362
362
|
|
363
363
|
if (readme.length < 800)
|
364
364
|
errors.push({
|
365
365
|
exercise: undefined,
|
366
366
|
msg: `The "${readmeFile}" file should have at least 800 characters (It currently have: ${readme.length}).`,
|
367
|
-
})
|
367
|
+
})
|
368
368
|
|
369
369
|
// eslint-disable-next-line
|
370
370
|
await Audit.checkUrl(
|
@@ -376,43 +376,43 @@ translations.push(regexGroups[1]);
|
|
376
376
|
warnings,
|
377
377
|
// eslint-disable-next-line
|
378
378
|
undefined
|
379
|
-
)
|
379
|
+
)
|
380
380
|
}
|
381
381
|
|
382
382
|
// Adding the translations to the learn.json
|
383
|
-
learnjson.translations = translations
|
383
|
+
learnjson.translations = translations
|
384
384
|
|
385
385
|
// Checking if the preview image (from the learn.json) is OK.
|
386
386
|
try {
|
387
|
-
const res = await fetch(learnjson.preview, { method: "HEAD" })
|
387
|
+
const res = await fetch(learnjson.preview, { method: "HEAD" })
|
388
388
|
if (res.status > 399 && res.status < 500) {
|
389
389
|
errors.push({
|
390
390
|
exercise: undefined,
|
391
391
|
msg: `The link of the "preview" is broken: ${learnjson.preview}`,
|
392
|
-
})
|
392
|
+
})
|
393
393
|
}
|
394
394
|
} catch {
|
395
395
|
errors.push({
|
396
396
|
exercise: undefined,
|
397
397
|
msg: `The link of the "preview" is broken: ${learnjson.preview}`,
|
398
|
-
})
|
398
|
+
})
|
399
399
|
}
|
400
400
|
|
401
|
-
const date = new Date()
|
402
|
-
learnjson.validationAt = date.getTime()
|
401
|
+
const date = new Date()
|
402
|
+
learnjson.validationAt = date.getTime()
|
403
403
|
|
404
404
|
if (errors.length > 0)
|
405
|
-
learnjson.validationStatus = "error"
|
405
|
+
learnjson.validationStatus = "error"
|
406
406
|
else if (warnings.length > 0)
|
407
|
-
learnjson.validationStatus = "warning"
|
407
|
+
learnjson.validationStatus = "warning"
|
408
408
|
else
|
409
|
-
learnjson.validationStatus = "success"
|
409
|
+
learnjson.validationStatus = "success"
|
410
410
|
|
411
411
|
// Writes the "learn.json" file with all the new properties
|
412
|
-
await fs.promises.writeFile("./learn.json", JSON.stringify(learnjson))
|
412
|
+
await fs.promises.writeFile("./learn.json", JSON.stringify(learnjson))
|
413
413
|
}
|
414
414
|
|
415
|
-
await Audit.showWarnings(warnings)
|
415
|
+
await Audit.showWarnings(warnings)
|
416
416
|
// eslint-disable-next-line
|
417
417
|
await Audit.showErrors(errors, undefined);
|
418
418
|
}
|
@@ -434,10 +434,10 @@ learnpack audit checks for the following information in a repository:
|
|
434
434
|
10. The exercses have the same translations. (Warning)
|
435
435
|
11. The .gitignore file exists. (Warning)
|
436
436
|
12. If there is a file within the exercises folder but not inside of any particular exercise's folder. (Warning)
|
437
|
-
|
437
|
+
`
|
438
438
|
|
439
439
|
AuditCommand.flags = {
|
440
440
|
// name: flags.string({char: 'n', description: 'name to print'}),
|
441
|
-
}
|
441
|
+
}
|
442
442
|
|
443
|
-
export default AuditCommand
|
443
|
+
export default AuditCommand
|