@learnpack/learnpack 2.0.2 → 2.0.5
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 +33 -38
- package/bin/run +1 -1
- package/oclif.manifest.json +1 -0
- package/package.json +4 -2
- package/src/commands/clean.ts +29 -29
- package/src/commands/download.ts +62 -62
- package/src/commands/init.ts +172 -172
- 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 +234 -234
- package/src/commands/test.ts +85 -85
- package/src/managers/config/exercise.ts +302 -302
- package/src/managers/config/index.ts +412 -412
- package/src/managers/file.ts +169 -169
- package/src/managers/server/index.ts +69 -69
- package/src/managers/server/routes.ts +255 -255
- package/src/managers/test.ts +83 -83
- package/src/plugin/plugin.ts +94 -94
- package/src/plugin/utils.ts +87 -87
- package/src/utils/BaseCommand.ts +48 -48
- package/src/utils/api.ts +194 -194
- package/src/utils/fileQueue.ts +198 -198
package/src/managers/test.ts
CHANGED
@@ -1,83 +1,83 @@
|
|
1
|
-
/*
|
2
|
-
|
3
|
-
import * as path from 'path'
|
4
|
-
import * as shell from 'shelljs'
|
5
|
-
import * as fs from 'fs'
|
6
|
-
import { TestingError } from './errors'
|
7
|
-
import Console from '../utils/console'
|
8
|
-
import * as color from 'colors'
|
9
|
-
import bcActivity from './bcActivity.js'
|
10
|
-
import { CompilerError } from '../utils/errors'
|
11
|
-
import { ISocket } from '../models/socket'
|
12
|
-
import { IFile } from '../models/file'
|
13
|
-
import { IConfig } from '@oclif/config'
|
14
|
-
|
15
|
-
module.exports = async function ({ socket, files, config, slug }: {socket: ISocket, files: IFile[], config: IConfig, slug: string}) {
|
16
|
-
|
17
|
-
const configPath = path.resolve(__dirname, `./config/tester/${config.tester}/${config.language}.config.js`);
|
18
|
-
if (!fs.existsSync(configPath)) throw CompilerError(`Uknown testing engine for compiler: '${config.language}'`);
|
19
|
-
|
20
|
-
const testingConfig = require(configPath)(files, config, slug);
|
21
|
-
testingConfig.validate();
|
22
|
-
|
23
|
-
if (config.ignoreTests) throw TestingError('Grading is disabled on learn.json file.');
|
24
|
-
|
25
|
-
if (!fs.existsSync(`${config.dirPath}/reports`)) {
|
26
|
-
fs.mkdirSync(`${config.dirPath}/reports`);
|
27
|
-
Console.debug(`Creating the ${config.dirPath}/reports directory`);
|
28
|
-
}
|
29
|
-
|
30
|
-
Console.info('Running tests...');
|
31
|
-
|
32
|
-
const command = await testingConfig.getCommand(socket)
|
33
|
-
const { stdout, stderr, code } = shell.exec(command);
|
34
|
-
|
35
|
-
if (code != 0) {
|
36
|
-
const errors = typeof (testingConfig.getErrors === 'function') ? testingConfig.getErrors(stdout || stderr) : [];
|
37
|
-
socket.log('testing-error', errors);
|
38
|
-
console.log(errors.join('\n'))
|
39
|
-
|
40
|
-
Console.error("There was an error while testing");
|
41
|
-
bcActivity.error('exercise_error', {
|
42
|
-
message: errors,
|
43
|
-
name: `${config.tester}-error`,
|
44
|
-
framework: config.tester,
|
45
|
-
language: config.language,
|
46
|
-
data: slug,
|
47
|
-
compiler: config.compiler
|
48
|
-
});
|
49
|
-
}
|
50
|
-
else {
|
51
|
-
socket.log('testing-success', [stdout || stderr].concat(["😁Everything is amazing!"]));
|
52
|
-
Console.success("Everything is amazing!");
|
53
|
-
|
54
|
-
bcActivity.activity('exercise_success', {
|
55
|
-
language: config.language,
|
56
|
-
slug: slug,
|
57
|
-
editor: config.editor,
|
58
|
-
compiler: config.compiler
|
59
|
-
});
|
60
|
-
config.exercises = config.exercises.map(e => {
|
61
|
-
if (e.slug === slug) e.done = true;
|
62
|
-
return e;
|
63
|
-
});
|
64
|
-
}
|
65
|
-
|
66
|
-
if (typeof testingConfig.cleanup !== "undefined") {
|
67
|
-
if (typeof testingConfig.cleanup === 'function' || typeof testingConfig.cleanup === 'object') {
|
68
|
-
const clean = await testingConfig.cleanup(socket);
|
69
|
-
if (clean) {
|
70
|
-
const { stdout, stderr, code } = shell.exec(clean);
|
71
|
-
if (code == 0) {
|
72
|
-
Console.debug("The cleanup command runned successfully");
|
73
|
-
}
|
74
|
-
else Console.warning("There is an error on the cleanup command for the test");
|
75
|
-
}
|
76
|
-
|
77
|
-
}
|
78
|
-
}
|
79
|
-
|
80
|
-
return true;
|
81
|
-
};
|
82
|
-
|
83
|
-
*/
|
1
|
+
/*
|
2
|
+
|
3
|
+
import * as path from 'path'
|
4
|
+
import * as shell from 'shelljs'
|
5
|
+
import * as fs from 'fs'
|
6
|
+
import { TestingError } from './errors'
|
7
|
+
import Console from '../utils/console'
|
8
|
+
import * as color from 'colors'
|
9
|
+
import bcActivity from './bcActivity.js'
|
10
|
+
import { CompilerError } from '../utils/errors'
|
11
|
+
import { ISocket } from '../models/socket'
|
12
|
+
import { IFile } from '../models/file'
|
13
|
+
import { IConfig } from '@oclif/config'
|
14
|
+
|
15
|
+
module.exports = async function ({ socket, files, config, slug }: {socket: ISocket, files: IFile[], config: IConfig, slug: string}) {
|
16
|
+
|
17
|
+
const configPath = path.resolve(__dirname, `./config/tester/${config.tester}/${config.language}.config.js`);
|
18
|
+
if (!fs.existsSync(configPath)) throw CompilerError(`Uknown testing engine for compiler: '${config.language}'`);
|
19
|
+
|
20
|
+
const testingConfig = require(configPath)(files, config, slug);
|
21
|
+
testingConfig.validate();
|
22
|
+
|
23
|
+
if (config.ignoreTests) throw TestingError('Grading is disabled on learn.json file.');
|
24
|
+
|
25
|
+
if (!fs.existsSync(`${config.dirPath}/reports`)) {
|
26
|
+
fs.mkdirSync(`${config.dirPath}/reports`);
|
27
|
+
Console.debug(`Creating the ${config.dirPath}/reports directory`);
|
28
|
+
}
|
29
|
+
|
30
|
+
Console.info('Running tests...');
|
31
|
+
|
32
|
+
const command = await testingConfig.getCommand(socket)
|
33
|
+
const { stdout, stderr, code } = shell.exec(command);
|
34
|
+
|
35
|
+
if (code != 0) {
|
36
|
+
const errors = typeof (testingConfig.getErrors === 'function') ? testingConfig.getErrors(stdout || stderr) : [];
|
37
|
+
socket.log('testing-error', errors);
|
38
|
+
console.log(errors.join('\n'))
|
39
|
+
|
40
|
+
Console.error("There was an error while testing");
|
41
|
+
bcActivity.error('exercise_error', {
|
42
|
+
message: errors,
|
43
|
+
name: `${config.tester}-error`,
|
44
|
+
framework: config.tester,
|
45
|
+
language: config.language,
|
46
|
+
data: slug,
|
47
|
+
compiler: config.compiler
|
48
|
+
});
|
49
|
+
}
|
50
|
+
else {
|
51
|
+
socket.log('testing-success', [stdout || stderr].concat(["😁Everything is amazing!"]));
|
52
|
+
Console.success("Everything is amazing!");
|
53
|
+
|
54
|
+
bcActivity.activity('exercise_success', {
|
55
|
+
language: config.language,
|
56
|
+
slug: slug,
|
57
|
+
editor: config.editor,
|
58
|
+
compiler: config.compiler
|
59
|
+
});
|
60
|
+
config.exercises = config.exercises.map(e => {
|
61
|
+
if (e.slug === slug) e.done = true;
|
62
|
+
return e;
|
63
|
+
});
|
64
|
+
}
|
65
|
+
|
66
|
+
if (typeof testingConfig.cleanup !== "undefined") {
|
67
|
+
if (typeof testingConfig.cleanup === 'function' || typeof testingConfig.cleanup === 'object') {
|
68
|
+
const clean = await testingConfig.cleanup(socket);
|
69
|
+
if (clean) {
|
70
|
+
const { stdout, stderr, code } = shell.exec(clean);
|
71
|
+
if (code == 0) {
|
72
|
+
Console.debug("The cleanup command runned successfully");
|
73
|
+
}
|
74
|
+
else Console.warning("There is an error on the cleanup command for the test");
|
75
|
+
}
|
76
|
+
|
77
|
+
}
|
78
|
+
}
|
79
|
+
|
80
|
+
return true;
|
81
|
+
};
|
82
|
+
|
83
|
+
*/
|
package/src/plugin/plugin.ts
CHANGED
@@ -1,94 +1,94 @@
|
|
1
|
-
import * as shell from "shelljs";
|
2
|
-
import { IPluginConfig } from "../models/plugin-config";
|
3
|
-
/**
|
4
|
-
* Main Plugin Runner, it defines the behavior of a learnpack plugin
|
5
|
-
* dividing it in "actions" like: Compile, test, etc.
|
6
|
-
* @param {object} pluginConfig Configuration object that must defined language and each possible action.
|
7
|
-
*/
|
8
|
-
export default (pluginConfig: IPluginConfig) => {
|
9
|
-
return async (args: any) => {
|
10
|
-
const { action, exercise, socket, configuration } = args;
|
11
|
-
|
12
|
-
if (pluginConfig.language === undefined)
|
13
|
-
throw new Error(`Missing language on the plugin configuration object`);
|
14
|
-
|
15
|
-
if (typeof action !== "string") {
|
16
|
-
throw new TypeError("Missing action property on hook details");
|
17
|
-
}
|
18
|
-
|
19
|
-
if (!exercise || exercise === undefined) {
|
20
|
-
throw new Error("Missing exercise information");
|
21
|
-
}
|
22
|
-
|
23
|
-
type actionType = "compile" | "test";
|
24
|
-
|
25
|
-
// if the action does not exist I don't do anything
|
26
|
-
if (pluginConfig[action as actionType] === undefined) {
|
27
|
-
console.log(`Ignoring ${action}`);
|
28
|
-
return () => null;
|
29
|
-
}
|
30
|
-
|
31
|
-
// ignore if the plugin language its not the same as the exercise language
|
32
|
-
if (exercise.language !== pluginConfig.language) {
|
33
|
-
return () => null;
|
34
|
-
}
|
35
|
-
|
36
|
-
if (!exercise.files || exercise.files.length === 0) {
|
37
|
-
throw new Error(`No files to process`);
|
38
|
-
}
|
39
|
-
|
40
|
-
try {
|
41
|
-
const _action = pluginConfig[action as actionType];
|
42
|
-
|
43
|
-
if (_action === null || typeof _action !== "object")
|
44
|
-
throw new Error(
|
45
|
-
`The ${pluginConfig.language} ${action} module must export an object configuration`
|
46
|
-
);
|
47
|
-
if (_action.validate === undefined)
|
48
|
-
throw new Error(
|
49
|
-
`Missing validate method for ${pluginConfig.language} ${action}`
|
50
|
-
);
|
51
|
-
if (_action.run === undefined)
|
52
|
-
throw new Error(
|
53
|
-
`Missing run method for ${pluginConfig.language} ${action}`
|
54
|
-
);
|
55
|
-
if (_action.dependencies !== undefined) {
|
56
|
-
if (!Array.isArray(_action.dependencies))
|
57
|
-
throw new Error(
|
58
|
-
`${action}.dependencies must be an array of package names`
|
59
|
-
);
|
60
|
-
|
61
|
-
for (const packageName of _action.dependencies) {
|
62
|
-
if (!shell.which(packageName)) {
|
63
|
-
throw new Error(
|
64
|
-
`🚫 You need to have ${packageName} installed to run test the exercises`
|
65
|
-
);
|
66
|
-
}
|
67
|
-
}
|
68
|
-
}
|
69
|
-
|
70
|
-
const valid = await _action.validate({ exercise, configuration });
|
71
|
-
if (valid) {
|
72
|
-
// look for the command standard implementation and execute it
|
73
|
-
const execute = require("./command/" + action + ".js").default;
|
74
|
-
// no matter the command, the response must always be a stdout
|
75
|
-
const stdout = await execute({
|
76
|
-
...args,
|
77
|
-
action: _action,
|
78
|
-
configuration,
|
79
|
-
});
|
80
|
-
|
81
|
-
// Map the action names to socket messaging standards
|
82
|
-
const actionToSuccessMapper = { compile: "compiler", test: "testing" };
|
83
|
-
|
84
|
-
socket.success(actionToSuccessMapper[action as actionType], stdout);
|
85
|
-
return stdout;
|
86
|
-
}
|
87
|
-
} catch (error: any) {
|
88
|
-
if (error.type === undefined)
|
89
|
-
socket.fatal(error);
|
90
|
-
else
|
91
|
-
socket.error(error.type, error.stdout);
|
92
|
-
}
|
93
|
-
};
|
94
|
-
};
|
1
|
+
import * as shell from "shelljs";
|
2
|
+
import { IPluginConfig } from "../models/plugin-config";
|
3
|
+
/**
|
4
|
+
* Main Plugin Runner, it defines the behavior of a learnpack plugin
|
5
|
+
* dividing it in "actions" like: Compile, test, etc.
|
6
|
+
* @param {object} pluginConfig Configuration object that must defined language and each possible action.
|
7
|
+
*/
|
8
|
+
export default (pluginConfig: IPluginConfig) => {
|
9
|
+
return async (args: any) => {
|
10
|
+
const { action, exercise, socket, configuration } = args;
|
11
|
+
|
12
|
+
if (pluginConfig.language === undefined)
|
13
|
+
throw new Error(`Missing language on the plugin configuration object`);
|
14
|
+
|
15
|
+
if (typeof action !== "string") {
|
16
|
+
throw new TypeError("Missing action property on hook details");
|
17
|
+
}
|
18
|
+
|
19
|
+
if (!exercise || exercise === undefined) {
|
20
|
+
throw new Error("Missing exercise information");
|
21
|
+
}
|
22
|
+
|
23
|
+
type actionType = "compile" | "test";
|
24
|
+
|
25
|
+
// if the action does not exist I don't do anything
|
26
|
+
if (pluginConfig[action as actionType] === undefined) {
|
27
|
+
console.log(`Ignoring ${action}`);
|
28
|
+
return () => null;
|
29
|
+
}
|
30
|
+
|
31
|
+
// ignore if the plugin language its not the same as the exercise language
|
32
|
+
if (exercise.language !== pluginConfig.language) {
|
33
|
+
return () => null;
|
34
|
+
}
|
35
|
+
|
36
|
+
if (!exercise.files || exercise.files.length === 0) {
|
37
|
+
throw new Error(`No files to process`);
|
38
|
+
}
|
39
|
+
|
40
|
+
try {
|
41
|
+
const _action = pluginConfig[action as actionType];
|
42
|
+
|
43
|
+
if (_action === null || typeof _action !== "object")
|
44
|
+
throw new Error(
|
45
|
+
`The ${pluginConfig.language} ${action} module must export an object configuration`
|
46
|
+
);
|
47
|
+
if (_action.validate === undefined)
|
48
|
+
throw new Error(
|
49
|
+
`Missing validate method for ${pluginConfig.language} ${action}`
|
50
|
+
);
|
51
|
+
if (_action.run === undefined)
|
52
|
+
throw new Error(
|
53
|
+
`Missing run method for ${pluginConfig.language} ${action}`
|
54
|
+
);
|
55
|
+
if (_action.dependencies !== undefined) {
|
56
|
+
if (!Array.isArray(_action.dependencies))
|
57
|
+
throw new Error(
|
58
|
+
`${action}.dependencies must be an array of package names`
|
59
|
+
);
|
60
|
+
|
61
|
+
for (const packageName of _action.dependencies) {
|
62
|
+
if (!shell.which(packageName)) {
|
63
|
+
throw new Error(
|
64
|
+
`🚫 You need to have ${packageName} installed to run test the exercises`
|
65
|
+
);
|
66
|
+
}
|
67
|
+
}
|
68
|
+
}
|
69
|
+
|
70
|
+
const valid = await _action.validate({ exercise, configuration });
|
71
|
+
if (valid) {
|
72
|
+
// look for the command standard implementation and execute it
|
73
|
+
const execute = require("./command/" + action + ".js").default;
|
74
|
+
// no matter the command, the response must always be a stdout
|
75
|
+
const stdout = await execute({
|
76
|
+
...args,
|
77
|
+
action: _action,
|
78
|
+
configuration,
|
79
|
+
});
|
80
|
+
|
81
|
+
// Map the action names to socket messaging standards
|
82
|
+
const actionToSuccessMapper = { compile: "compiler", test: "testing" };
|
83
|
+
|
84
|
+
socket.success(actionToSuccessMapper[action as actionType], stdout);
|
85
|
+
return stdout;
|
86
|
+
}
|
87
|
+
} catch (error: any) {
|
88
|
+
if (error.type === undefined)
|
89
|
+
socket.fatal(error);
|
90
|
+
else
|
91
|
+
socket.error(error.type, error.stdout);
|
92
|
+
}
|
93
|
+
};
|
94
|
+
};
|
package/src/plugin/utils.ts
CHANGED
@@ -1,87 +1,87 @@
|
|
1
|
-
import * as chalk from "chalk";
|
2
|
-
|
3
|
-
const getMatches = (reg: RegExp, content: string) => {
|
4
|
-
const inputs = [];
|
5
|
-
let m;
|
6
|
-
while ((m = reg.exec(content)) !== null) {
|
7
|
-
// This is necessary to avoid infinite loops with zero-width matches
|
8
|
-
if (m.index === reg.lastIndex)
|
9
|
-
reg.lastIndex++;
|
10
|
-
|
11
|
-
// The result can be accessed through the `m`-variable.
|
12
|
-
inputs.push(m[1] || null);
|
13
|
-
}
|
14
|
-
|
15
|
-
return inputs;
|
16
|
-
};
|
17
|
-
|
18
|
-
const cleanStdout = (buffer: string, inputs: string[]) => {
|
19
|
-
if (Array.isArray(inputs))
|
20
|
-
for (let i = 0; i < inputs.length; i++)
|
21
|
-
if (inputs[i])
|
22
|
-
buffer = buffer.replace(inputs[i], "");
|
23
|
-
|
24
|
-
return buffer;
|
25
|
-
};
|
26
|
-
|
27
|
-
const indent = (string: string, options: any, count = 1) => {
|
28
|
-
options = {
|
29
|
-
indent: " ",
|
30
|
-
includeEmptyLines: false,
|
31
|
-
...options,
|
32
|
-
};
|
33
|
-
|
34
|
-
if (typeof string !== "string") {
|
35
|
-
throw new TypeError(
|
36
|
-
`Expected \`input\` to be a \`string\`, got \`${typeof string}\``
|
37
|
-
);
|
38
|
-
}
|
39
|
-
|
40
|
-
if (typeof count !== "number") {
|
41
|
-
throw new TypeError(
|
42
|
-
`Expected \`count\` to be a \`number\`, got \`${typeof count}\``
|
43
|
-
);
|
44
|
-
}
|
45
|
-
|
46
|
-
if (count < 0) {
|
47
|
-
throw new RangeError(
|
48
|
-
`Expected \`count\` to be at least 0, got \`${count}\``
|
49
|
-
);
|
50
|
-
}
|
51
|
-
|
52
|
-
if (typeof options.indent !== "string") {
|
53
|
-
throw new TypeError(
|
54
|
-
`Expected \`options.indent\` to be a \`string\`, got \`${typeof options.indent}\``
|
55
|
-
);
|
56
|
-
}
|
57
|
-
|
58
|
-
if (count === 0) {
|
59
|
-
return string;
|
60
|
-
}
|
61
|
-
|
62
|
-
const regex = options.includeEmptyLines ? /^/gm : /^(?!\s*$)/gm;
|
63
|
-
|
64
|
-
return string.replace(regex, options.indent.repeat(count));
|
65
|
-
};
|
66
|
-
|
67
|
-
const Console = {
|
68
|
-
// _debug: true,
|
69
|
-
_debug: process.env.DEBUG === "true",
|
70
|
-
startDebug: function () {
|
71
|
-
this._debug = true;
|
72
|
-
},
|
73
|
-
log: (msg: string, ...args: any[]) => console.log(chalk.gray(msg), ...args),
|
74
|
-
error: (msg: string, ...args: any[]) =>
|
75
|
-
console.log(chalk.red("⨉ " + msg), ...args),
|
76
|
-
success: (msg: string, ...args: any[]) =>
|
77
|
-
console.log(chalk.green("✓ " + msg), ...args),
|
78
|
-
info: (msg: string, ...args: any[]) =>
|
79
|
-
console.log(chalk.blue("ⓘ " + msg), ...args),
|
80
|
-
help: (msg: string) =>
|
81
|
-
console.log(`${chalk.white.bold("⚠ help:")} ${chalk.white(msg)}`),
|
82
|
-
debug(...args: any[]) {
|
83
|
-
this._debug && console.log(chalk.magentaBright(`⚠ debug: `), args);
|
84
|
-
},
|
85
|
-
};
|
86
|
-
|
87
|
-
export default { getMatches, cleanStdout, indent, Console };
|
1
|
+
import * as chalk from "chalk";
|
2
|
+
|
3
|
+
const getMatches = (reg: RegExp, content: string) => {
|
4
|
+
const inputs = [];
|
5
|
+
let m;
|
6
|
+
while ((m = reg.exec(content)) !== null) {
|
7
|
+
// This is necessary to avoid infinite loops with zero-width matches
|
8
|
+
if (m.index === reg.lastIndex)
|
9
|
+
reg.lastIndex++;
|
10
|
+
|
11
|
+
// The result can be accessed through the `m`-variable.
|
12
|
+
inputs.push(m[1] || null);
|
13
|
+
}
|
14
|
+
|
15
|
+
return inputs;
|
16
|
+
};
|
17
|
+
|
18
|
+
const cleanStdout = (buffer: string, inputs: string[]) => {
|
19
|
+
if (Array.isArray(inputs))
|
20
|
+
for (let i = 0; i < inputs.length; i++)
|
21
|
+
if (inputs[i])
|
22
|
+
buffer = buffer.replace(inputs[i], "");
|
23
|
+
|
24
|
+
return buffer;
|
25
|
+
};
|
26
|
+
|
27
|
+
const indent = (string: string, options: any, count = 1) => {
|
28
|
+
options = {
|
29
|
+
indent: " ",
|
30
|
+
includeEmptyLines: false,
|
31
|
+
...options,
|
32
|
+
};
|
33
|
+
|
34
|
+
if (typeof string !== "string") {
|
35
|
+
throw new TypeError(
|
36
|
+
`Expected \`input\` to be a \`string\`, got \`${typeof string}\``
|
37
|
+
);
|
38
|
+
}
|
39
|
+
|
40
|
+
if (typeof count !== "number") {
|
41
|
+
throw new TypeError(
|
42
|
+
`Expected \`count\` to be a \`number\`, got \`${typeof count}\``
|
43
|
+
);
|
44
|
+
}
|
45
|
+
|
46
|
+
if (count < 0) {
|
47
|
+
throw new RangeError(
|
48
|
+
`Expected \`count\` to be at least 0, got \`${count}\``
|
49
|
+
);
|
50
|
+
}
|
51
|
+
|
52
|
+
if (typeof options.indent !== "string") {
|
53
|
+
throw new TypeError(
|
54
|
+
`Expected \`options.indent\` to be a \`string\`, got \`${typeof options.indent}\``
|
55
|
+
);
|
56
|
+
}
|
57
|
+
|
58
|
+
if (count === 0) {
|
59
|
+
return string;
|
60
|
+
}
|
61
|
+
|
62
|
+
const regex = options.includeEmptyLines ? /^/gm : /^(?!\s*$)/gm;
|
63
|
+
|
64
|
+
return string.replace(regex, options.indent.repeat(count));
|
65
|
+
};
|
66
|
+
|
67
|
+
const Console = {
|
68
|
+
// _debug: true,
|
69
|
+
_debug: process.env.DEBUG === "true",
|
70
|
+
startDebug: function () {
|
71
|
+
this._debug = true;
|
72
|
+
},
|
73
|
+
log: (msg: string, ...args: any[]) => console.log(chalk.gray(msg), ...args),
|
74
|
+
error: (msg: string, ...args: any[]) =>
|
75
|
+
console.log(chalk.red("⨉ " + msg), ...args),
|
76
|
+
success: (msg: string, ...args: any[]) =>
|
77
|
+
console.log(chalk.green("✓ " + msg), ...args),
|
78
|
+
info: (msg: string, ...args: any[]) =>
|
79
|
+
console.log(chalk.blue("ⓘ " + msg), ...args),
|
80
|
+
help: (msg: string) =>
|
81
|
+
console.log(`${chalk.white.bold("⚠ help:")} ${chalk.white(msg)}`),
|
82
|
+
debug(...args: any[]) {
|
83
|
+
this._debug && console.log(chalk.magentaBright(`⚠ debug: `), args);
|
84
|
+
},
|
85
|
+
};
|
86
|
+
|
87
|
+
export default { getMatches, cleanStdout, indent, Console };
|
package/src/utils/BaseCommand.ts
CHANGED
@@ -1,48 +1,48 @@
|
|
1
|
-
import { Command } from "@oclif/command";
|
2
|
-
import Console from "./console";
|
3
|
-
import { createInterface } from "readline";
|
4
|
-
// import SessionManager from '../managers/session'
|
5
|
-
|
6
|
-
class BaseCommand extends Command {
|
7
|
-
async catch(err: any) {
|
8
|
-
Console.debug("COMMAND CATCH", err);
|
9
|
-
|
10
|
-
throw err;
|
11
|
-
}
|
12
|
-
|
13
|
-
async init() {
|
14
|
-
const { flags, args } = this.parse(BaseCommand);
|
15
|
-
Console.debug("COMMAND INIT");
|
16
|
-
Console.debug("These are your flags: ", flags);
|
17
|
-
Console.debug("These are your args: ", args);
|
18
|
-
|
19
|
-
// quick fix for listening to the process termination on windows
|
20
|
-
if (process.platform === "win32") {
|
21
|
-
const rl = createInterface({
|
22
|
-
input: process.stdin,
|
23
|
-
output: process.stdout,
|
24
|
-
});
|
25
|
-
|
26
|
-
rl.on("SIGINT", function () {
|
27
|
-
// process.emit('SIGINT')
|
28
|
-
// process.emit('SIGINT')
|
29
|
-
});
|
30
|
-
}
|
31
|
-
|
32
|
-
process.on("SIGINT", function () {
|
33
|
-
Console.debug("Terminated (SIGINT)");
|
34
|
-
process.exit();
|
35
|
-
});
|
36
|
-
}
|
37
|
-
|
38
|
-
async finally() {
|
39
|
-
Console.debug("COMMAND FINALLY");
|
40
|
-
// called after run and catch regardless of whether or not the command errored
|
41
|
-
}
|
42
|
-
|
43
|
-
async run() {
|
44
|
-
// console.log('running my command')
|
45
|
-
}
|
46
|
-
}
|
47
|
-
|
48
|
-
export default BaseCommand;
|
1
|
+
import { Command } from "@oclif/command";
|
2
|
+
import Console from "./console";
|
3
|
+
import { createInterface } from "readline";
|
4
|
+
// import SessionManager from '../managers/session'
|
5
|
+
|
6
|
+
class BaseCommand extends Command {
|
7
|
+
async catch(err: any) {
|
8
|
+
Console.debug("COMMAND CATCH", err);
|
9
|
+
|
10
|
+
throw err;
|
11
|
+
}
|
12
|
+
|
13
|
+
async init() {
|
14
|
+
const { flags, args } = this.parse(BaseCommand);
|
15
|
+
Console.debug("COMMAND INIT");
|
16
|
+
Console.debug("These are your flags: ", flags);
|
17
|
+
Console.debug("These are your args: ", args);
|
18
|
+
|
19
|
+
// quick fix for listening to the process termination on windows
|
20
|
+
if (process.platform === "win32") {
|
21
|
+
const rl = createInterface({
|
22
|
+
input: process.stdin,
|
23
|
+
output: process.stdout,
|
24
|
+
});
|
25
|
+
|
26
|
+
rl.on("SIGINT", function () {
|
27
|
+
// process.emit('SIGINT')
|
28
|
+
// process.emit('SIGINT')
|
29
|
+
});
|
30
|
+
}
|
31
|
+
|
32
|
+
process.on("SIGINT", function () {
|
33
|
+
Console.debug("Terminated (SIGINT)");
|
34
|
+
process.exit();
|
35
|
+
});
|
36
|
+
}
|
37
|
+
|
38
|
+
async finally() {
|
39
|
+
Console.debug("COMMAND FINALLY");
|
40
|
+
// called after run and catch regardless of whether or not the command errored
|
41
|
+
}
|
42
|
+
|
43
|
+
async run() {
|
44
|
+
// console.log('running my command')
|
45
|
+
}
|
46
|
+
}
|
47
|
+
|
48
|
+
export default BaseCommand;
|