@memlab/cli 1.0.1 → 1.0.4
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 +1 -1
- package/dist/BaseCommand.d.ts +1 -0
- package/dist/BaseCommand.js +21 -12
- package/dist/CommandLoader.d.ts +22 -0
- package/dist/CommandLoader.js +95 -0
- package/dist/Dispatcher.d.ts +1 -5
- package/dist/Dispatcher.js +8 -70
- package/dist/commands/MemLabRunCommand.d.ts +3 -1
- package/dist/commands/MemLabRunCommand.js +54 -2
- package/dist/commands/PrintSummaryCommand.js +1 -1
- package/dist/commands/RunMeasureCommand.d.ts +1 -0
- package/dist/commands/RunMeasureCommand.js +7 -0
- package/dist/commands/WarmupAppCommand.d.ts +1 -0
- package/dist/commands/WarmupAppCommand.js +6 -0
- package/dist/commands/heap/CheckLeakCommand.js +3 -1
- package/dist/commands/heap/GetRetainerTraceCommand.js +6 -2
- package/dist/commands/helper/GenerateCLIDocCommand.d.ts +31 -0
- package/dist/commands/helper/GenerateCLIDocCommand.js +207 -0
- package/dist/commands/helper/HelperCommand.js +2 -1
- package/dist/commands/snapshot/TakeSnapshotCommand.d.ts +1 -0
- package/dist/commands/snapshot/TakeSnapshotCommand.js +7 -0
- package/dist/options/HeapNodeIdOption.js +8 -9
- package/dist/options/heap/LeakClusterSizeThresholdOption.d.ts +19 -0
- package/dist/options/heap/LeakClusterSizeThresholdOption.js +43 -0
- package/dist/options/heap/OversizeThresholdOption.js +2 -2
- package/dist/options/heap/leak-filter/examples/large-object-as-leak.example.js +1 -0
- package/dist/options/lib/UniversalOptions.d.ts +17 -0
- package/dist/options/lib/UniversalOptions.js +27 -0
- package/package.json +2 -1
- package/dist/BaseCommand.d.ts.map +0 -1
- package/dist/Dispatcher.d.ts.map +0 -1
- package/dist/TypesThirdParty.d.ts.map +0 -1
- package/dist/commands/CleanLoggerDataCommand.d.ts.map +0 -1
- package/dist/commands/CleanRunDataCommand.d.ts.map +0 -1
- package/dist/commands/InitDirectoryCommand.d.ts.map +0 -1
- package/dist/commands/ListScenariosCommand.d.ts.map +0 -1
- package/dist/commands/MemLabRunCommand.d.ts.map +0 -1
- package/dist/commands/PrintSummaryCommand.d.ts.map +0 -1
- package/dist/commands/ResetDirectoryCommand.d.ts.map +0 -1
- package/dist/commands/RunMeasureCommand.d.ts.map +0 -1
- package/dist/commands/WarmupAppCommand.d.ts.map +0 -1
- package/dist/commands/heap/CheckLeakCommand.d.ts.map +0 -1
- package/dist/commands/heap/GetRetainerTraceCommand.d.ts.map +0 -1
- package/dist/commands/heap/HeapAnalysisCommand.d.ts.map +0 -1
- package/dist/commands/heap/HeapAnalysisSubCommandWrapper.d.ts.map +0 -1
- package/dist/commands/helper/HelperCommand.d.ts.map +0 -1
- package/dist/commands/helper/lib/CommandOrder.d.ts.map +0 -1
- package/dist/commands/helper/lib/Types.d.ts.map +0 -1
- package/dist/commands/query/QueryDefaultWorkDirCommand.d.ts.map +0 -1
- package/dist/commands/snapshot/CheckXvfbSupportCommand.d.ts.map +0 -1
- package/dist/commands/snapshot/Snapshot.d.ts.map +0 -1
- package/dist/commands/snapshot/TakeSnapshotCommand.d.ts.map +0 -1
- package/dist/commands/snapshot/WarmupAndSnapshotCommand.d.ts.map +0 -1
- package/dist/commands/test/BrowserTest.d.ts +0 -11
- package/dist/commands/test/BrowserTest.d.ts.map +0 -1
- package/dist/commands/test/BrowserTest.js +0 -41
- package/dist/commands/test/RunAllInteractionTestsCommand.d.ts +0 -19
- package/dist/commands/test/RunAllInteractionTestsCommand.d.ts.map +0 -1
- package/dist/commands/test/RunAllInteractionTestsCommand.js +0 -71
- package/dist/commands/test/RunInteractionTestCommand.d.ts +0 -19
- package/dist/commands/test/RunInteractionTestCommand.d.ts.map +0 -1
- package/dist/commands/test/RunInteractionTestCommand.js +0 -75
- package/dist/index.d.ts.map +0 -1
- package/dist/options/AppOption.d.ts.map +0 -1
- package/dist/options/DebugOption.d.ts.map +0 -1
- package/dist/options/DisableXvfbOption.d.ts.map +0 -1
- package/dist/options/FullExecutionOption.d.ts.map +0 -1
- package/dist/options/HeapNodeIdOption.d.ts.map +0 -1
- package/dist/options/HelperOption.d.ts.map +0 -1
- package/dist/options/InteractionOption.d.ts.map +0 -1
- package/dist/options/NumberOfRunsOption.d.ts.map +0 -1
- package/dist/options/RemoteBrowserDebugOption.d.ts.map +0 -1
- package/dist/options/RunningModeOption.d.ts.map +0 -1
- package/dist/options/ScenarioFileOption.d.ts.map +0 -1
- package/dist/options/SetContinuousTestOption.d.ts.map +0 -1
- package/dist/options/SetDeviceOption.d.ts.map +0 -1
- package/dist/options/SetWorkingDirectoryOption.d.ts.map +0 -1
- package/dist/options/SilentOption.d.ts.map +0 -1
- package/dist/options/SkipExtraOperationOption.d.ts.map +0 -1
- package/dist/options/SkipGCOption.d.ts.map +0 -1
- package/dist/options/SkipScreenshotOption.d.ts.map +0 -1
- package/dist/options/SkipScrollOption.d.ts.map +0 -1
- package/dist/options/SkipSnapshotOption.d.ts.map +0 -1
- package/dist/options/SkipWarmupOption.d.ts.map +0 -1
- package/dist/options/VerboseOption.d.ts.map +0 -1
- package/dist/options/heap/BaselineFileOption.d.ts.map +0 -1
- package/dist/options/heap/FinalFileOption.d.ts.map +0 -1
- package/dist/options/heap/JSEngineOption.d.ts.map +0 -1
- package/dist/options/heap/LogTraceAsClusterOption.d.ts.map +0 -1
- package/dist/options/heap/OversizeThresholdOption.d.ts.map +0 -1
- package/dist/options/heap/SnapshotDirectoryOption.d.ts.map +0 -1
- package/dist/options/heap/SnapshotFileOption.d.ts.map +0 -1
- package/dist/options/heap/TargetFileOption.d.ts.map +0 -1
- package/dist/options/heap/TraceAllObjectsOption.d.ts.map +0 -1
- package/dist/options/heap/leak-filter/LeakFilterFileOption.d.ts.map +0 -1
- package/dist/options/heap/leak-filter/examples/FilterLib.d.ts.map +0 -1
- package/dist/options/heap/leak-filter/examples/dup-string-as-leak.example-1.d.ts.map +0 -1
- package/dist/options/heap/leak-filter/examples/dup-string-as-leak.example-2.d.ts.map +0 -1
- package/dist/options/heap/leak-filter/examples/large-object-as-leak.example.d.ts.map +0 -1
- package/dist/runner.d.ts.map +0 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
## memlab CLI
|
|
2
2
|
|
|
3
|
-
This is the memlab CLI library. It contains all memlab commands, command-line options, and command-line interfaces.
|
|
3
|
+
This is the memlab CLI library. It contains all memlab commands, command-line options, and command-line interfaces.
|
|
4
4
|
The library supports adding new commands.
|
|
5
5
|
|
|
6
6
|
## Full documentation
|
package/dist/BaseCommand.d.ts
CHANGED
|
@@ -30,6 +30,7 @@ export default class BaseCommand extends Command {
|
|
|
30
30
|
getPrerequisites(): BaseCommand[];
|
|
31
31
|
isInternalCommand(): boolean;
|
|
32
32
|
getOptions(): BaseOption[];
|
|
33
|
+
getExcludedOptions(): BaseOption[];
|
|
33
34
|
getSubCommands(): BaseCommand[];
|
|
34
35
|
run(_options: CLIOptions): Promise<void>;
|
|
35
36
|
}
|
package/dist/BaseCommand.js
CHANGED
|
@@ -55,21 +55,23 @@ class Command {
|
|
|
55
55
|
const uniqueOptions = new Map();
|
|
56
56
|
const visitedCommands = new Set();
|
|
57
57
|
const queue = [self];
|
|
58
|
+
const excludedOptions = new Set(self.getExcludedOptions().map(option => option.getOptionName()));
|
|
58
59
|
while (queue.length > 0) {
|
|
59
60
|
const cur = queue.shift();
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
uniqueOptions.set(optionName, option);
|
|
66
|
-
}
|
|
61
|
+
const options = cur.getOptions();
|
|
62
|
+
for (const option of options) {
|
|
63
|
+
const optionName = option.getOptionName();
|
|
64
|
+
if (excludedOptions.has(optionName)) {
|
|
65
|
+
continue;
|
|
67
66
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
67
|
+
if (!uniqueOptions.has(optionName)) {
|
|
68
|
+
uniqueOptions.set(optionName, option);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
visitedCommands.add(cur.getCommandName());
|
|
72
|
+
for (const prereq of cur.getPrerequisites()) {
|
|
73
|
+
if (!visitedCommands.has(prereq.getCommandName())) {
|
|
74
|
+
queue.push(prereq);
|
|
73
75
|
}
|
|
74
76
|
}
|
|
75
77
|
}
|
|
@@ -112,6 +114,13 @@ class BaseCommand extends Command {
|
|
|
112
114
|
getOptions() {
|
|
113
115
|
return [];
|
|
114
116
|
}
|
|
117
|
+
// commands from getPrerequisites may propagate
|
|
118
|
+
// options that does not make sense for the
|
|
119
|
+
// current command, this returns the list of
|
|
120
|
+
// options that should be excluded from helper text
|
|
121
|
+
getExcludedOptions() {
|
|
122
|
+
return [];
|
|
123
|
+
}
|
|
115
124
|
// get subcommands of this command
|
|
116
125
|
// for example command 'A' has two sub-commands 'B' and 'C'
|
|
117
126
|
// CLI supports running in terminal: `memlab A B` or `memlab A C`
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @emails oncall+ws_labs
|
|
8
|
+
* @format
|
|
9
|
+
*/
|
|
10
|
+
import BaseCommand from './BaseCommand';
|
|
11
|
+
export default class CommandLoader {
|
|
12
|
+
private isLoaded;
|
|
13
|
+
private OSSModules;
|
|
14
|
+
private modules;
|
|
15
|
+
private modulePaths;
|
|
16
|
+
getModules(): Map<string, BaseCommand>;
|
|
17
|
+
getModulePaths(): Map<string, string>;
|
|
18
|
+
registerCommands(): void;
|
|
19
|
+
private registerCommandsFromDir;
|
|
20
|
+
private postRegistration;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=CommandLoader.d.ts.map
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*
|
|
8
|
+
* @emails oncall+ws_labs
|
|
9
|
+
* @format
|
|
10
|
+
*/
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
const fs_1 = __importDefault(require("fs"));
|
|
16
|
+
const path_1 = __importDefault(require("path"));
|
|
17
|
+
const core_1 = require("@memlab/core");
|
|
18
|
+
const BaseCommand_1 = __importDefault(require("./BaseCommand"));
|
|
19
|
+
const GenerateCLIDocCommand_1 = __importDefault(require("./commands/helper/GenerateCLIDocCommand"));
|
|
20
|
+
class CommandLoader {
|
|
21
|
+
constructor() {
|
|
22
|
+
this.isLoaded = false;
|
|
23
|
+
this.OSSModules = new Map();
|
|
24
|
+
this.modules = new Map();
|
|
25
|
+
this.modulePaths = new Map();
|
|
26
|
+
}
|
|
27
|
+
getModules() {
|
|
28
|
+
if (!this.isLoaded) {
|
|
29
|
+
this.registerCommands();
|
|
30
|
+
}
|
|
31
|
+
return this.modules;
|
|
32
|
+
}
|
|
33
|
+
getModulePaths() {
|
|
34
|
+
if (!this.isLoaded) {
|
|
35
|
+
this.registerCommands();
|
|
36
|
+
}
|
|
37
|
+
return this.modulePaths;
|
|
38
|
+
}
|
|
39
|
+
registerCommands() {
|
|
40
|
+
const modulesDir = path_1.default.resolve(__dirname, 'commands');
|
|
41
|
+
this.registerCommandsFromDir(modulesDir);
|
|
42
|
+
this.postRegistration();
|
|
43
|
+
}
|
|
44
|
+
registerCommandsFromDir(modulesDir) {
|
|
45
|
+
const moduleFiles = fs_1.default.readdirSync(modulesDir);
|
|
46
|
+
for (const moduleFile of moduleFiles) {
|
|
47
|
+
const modulePath = path_1.default.join(modulesDir, moduleFile);
|
|
48
|
+
// recursively import modules from subdirectories
|
|
49
|
+
if (fs_1.default.lstatSync(modulePath).isDirectory()) {
|
|
50
|
+
this.registerCommandsFromDir(modulePath);
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
// only import modules files ends with with Command.js
|
|
54
|
+
if (!moduleFile.endsWith('Command.js')) {
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
58
|
+
const module = require(modulePath);
|
|
59
|
+
const moduleConstructor = typeof module.default === 'function' ? module.default : module;
|
|
60
|
+
const moduleInstance = new moduleConstructor();
|
|
61
|
+
if (!(moduleInstance instanceof BaseCommand_1.default)) {
|
|
62
|
+
core_1.utils.haltOrThrow('loading a command that does not extend BaseCommand');
|
|
63
|
+
}
|
|
64
|
+
const commandName = moduleInstance.getCommandName();
|
|
65
|
+
const loadingOssCommand = !core_1.fileManager.isWithinInternalDirectory(modulePath);
|
|
66
|
+
// reigster OSS commands
|
|
67
|
+
if (loadingOssCommand) {
|
|
68
|
+
this.OSSModules.set(commandName, moduleInstance);
|
|
69
|
+
}
|
|
70
|
+
// register all commands
|
|
71
|
+
if (this.modules.has(commandName)) {
|
|
72
|
+
// resolve conflict
|
|
73
|
+
const ossCommandLoaded = !core_1.fileManager.isWithinInternalDirectory(this.modulePaths.get(commandName));
|
|
74
|
+
if (ossCommandLoaded === loadingOssCommand) {
|
|
75
|
+
// when both commands are open source or neither are open source
|
|
76
|
+
core_1.info.midLevel(`MemLab command ${commandName} is already registered`);
|
|
77
|
+
}
|
|
78
|
+
else if (!ossCommandLoaded && loadingOssCommand) {
|
|
79
|
+
// when open source command tries to overwrite non-open source command
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
this.modules.set(commandName, moduleInstance);
|
|
84
|
+
this.modulePaths.set(commandName, modulePath);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
postRegistration() {
|
|
88
|
+
const cliDocCommand = new GenerateCLIDocCommand_1.default();
|
|
89
|
+
const instance = this.modules.get(cliDocCommand.getCommandName());
|
|
90
|
+
if (instance) {
|
|
91
|
+
instance.setModulesMap(this.OSSModules);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
exports.default = CommandLoader;
|
package/dist/Dispatcher.d.ts
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* @format
|
|
9
9
|
*/
|
|
10
10
|
import type { ParsedArgs } from 'minimist';
|
|
11
|
-
import {
|
|
11
|
+
import type { AnyRecord, MemLabConfig } from '@memlab/core';
|
|
12
12
|
import BaseCommand from './BaseCommand';
|
|
13
13
|
declare type RunCommandOptions = {
|
|
14
14
|
isPrerequisite?: boolean;
|
|
@@ -17,7 +17,6 @@ declare type RunCommandOptions = {
|
|
|
17
17
|
};
|
|
18
18
|
declare class CommandDispatcher {
|
|
19
19
|
private modules;
|
|
20
|
-
private modulePaths;
|
|
21
20
|
private executedCommands;
|
|
22
21
|
private executingCommandStack;
|
|
23
22
|
constructor();
|
|
@@ -26,9 +25,6 @@ declare class CommandDispatcher {
|
|
|
26
25
|
private runCommand;
|
|
27
26
|
runSubCommandIfAny(command: BaseCommand, args: ParsedArgs, runCmdOpt: RunCommandOptions): Promise<void>;
|
|
28
27
|
private helper;
|
|
29
|
-
private registerBuiltInCommands;
|
|
30
|
-
private registerCommands;
|
|
31
|
-
private registerCommandsFromDir;
|
|
32
28
|
}
|
|
33
29
|
declare const _default: CommandDispatcher;
|
|
34
30
|
export default _default;
|
package/dist/Dispatcher.js
CHANGED
|
@@ -22,40 +22,23 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
22
22
|
};
|
|
23
23
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
24
|
const core_1 = require("@memlab/core");
|
|
25
|
-
const fs_1 = __importDefault(require("fs"));
|
|
26
|
-
const path_1 = __importDefault(require("path"));
|
|
27
|
-
const core_2 = require("@memlab/core");
|
|
28
|
-
const BaseCommand_1 = __importDefault(require("./BaseCommand"));
|
|
29
25
|
const HelperCommand_1 = __importDefault(require("./commands/helper/HelperCommand"));
|
|
30
|
-
const
|
|
31
|
-
const
|
|
32
|
-
const DebugOption_1 = __importDefault(require("./options/DebugOption"));
|
|
33
|
-
const SilentOption_1 = __importDefault(require("./options/SilentOption"));
|
|
34
|
-
const HelperOption_1 = __importDefault(require("./options/HelperOption"));
|
|
35
|
-
const universalOptions = [
|
|
36
|
-
new HelperOption_1.default(),
|
|
37
|
-
new VerboseOption_1.default(),
|
|
38
|
-
new SetContinuousTestOption_1.default(),
|
|
39
|
-
new DebugOption_1.default(),
|
|
40
|
-
new SilentOption_1.default(),
|
|
41
|
-
];
|
|
26
|
+
const UniversalOptions_1 = __importDefault(require("./options/lib/UniversalOptions"));
|
|
27
|
+
const CommandLoader_1 = __importDefault(require("./CommandLoader"));
|
|
42
28
|
const helperCommand = new HelperCommand_1.default();
|
|
43
|
-
helperCommand.setUniversalOptions(universalOptions);
|
|
44
29
|
class CommandDispatcher {
|
|
45
30
|
constructor() {
|
|
46
31
|
this.executedCommands = new Set();
|
|
47
32
|
this.executingCommandStack = [];
|
|
48
33
|
// auto load all command modules
|
|
49
|
-
|
|
50
|
-
this.
|
|
51
|
-
this.registerBuiltInCommands();
|
|
52
|
-
this.registerCommands();
|
|
34
|
+
const commandLoader = new CommandLoader_1.default();
|
|
35
|
+
this.modules = commandLoader.getModules();
|
|
53
36
|
}
|
|
54
37
|
dispatch(args) {
|
|
55
38
|
return __awaiter(this, void 0, void 0, function* () {
|
|
56
39
|
// triggered by `memlab` (without specific command)
|
|
57
40
|
if (!args._ || !(args._.length >= 1)) {
|
|
58
|
-
|
|
41
|
+
core_1.info.error('\n command argument missing');
|
|
59
42
|
yield this.helper(args);
|
|
60
43
|
return;
|
|
61
44
|
}
|
|
@@ -83,7 +66,7 @@ class CommandDispatcher {
|
|
|
83
66
|
}
|
|
84
67
|
parseOptions(command, config, args) {
|
|
85
68
|
return __awaiter(this, void 0, void 0, function* () {
|
|
86
|
-
const options = [...
|
|
69
|
+
const options = [...UniversalOptions_1.default, ...command.getOptions()];
|
|
87
70
|
const configFromOptions = Object.create(null);
|
|
88
71
|
for (const option of options) {
|
|
89
72
|
const ret = yield option.run(config, args);
|
|
@@ -113,7 +96,7 @@ class CommandDispatcher {
|
|
|
113
96
|
yield this.runCommand(prereq, args, Object.assign({ isPrerequisite: true }, runCmdOpt));
|
|
114
97
|
}
|
|
115
98
|
// parse command line options
|
|
116
|
-
const c = yield this.parseOptions(command,
|
|
99
|
+
const c = yield this.parseOptions(command, core_1.config, args);
|
|
117
100
|
Object.assign(runCmdOpt.configFromOptions, c);
|
|
118
101
|
const { configFromOptions } = runCmdOpt;
|
|
119
102
|
// execute command
|
|
@@ -142,7 +125,7 @@ class CommandDispatcher {
|
|
|
142
125
|
return;
|
|
143
126
|
}
|
|
144
127
|
}
|
|
145
|
-
|
|
128
|
+
core_1.info.error(`Invalid sub-command \`${args._[subCommandIndex]}\` of \`${command.getCommandName()}\`\n`);
|
|
146
129
|
yield this.helper(args, command);
|
|
147
130
|
});
|
|
148
131
|
}
|
|
@@ -156,50 +139,5 @@ class CommandDispatcher {
|
|
|
156
139
|
});
|
|
157
140
|
});
|
|
158
141
|
}
|
|
159
|
-
registerBuiltInCommands() {
|
|
160
|
-
// TBA
|
|
161
|
-
}
|
|
162
|
-
registerCommands() {
|
|
163
|
-
const modulesDir = path_1.default.resolve(__dirname, 'commands');
|
|
164
|
-
this.registerCommandsFromDir(modulesDir);
|
|
165
|
-
}
|
|
166
|
-
registerCommandsFromDir(modulesDir) {
|
|
167
|
-
const moduleFiles = fs_1.default.readdirSync(modulesDir);
|
|
168
|
-
for (const moduleFile of moduleFiles) {
|
|
169
|
-
const modulePath = path_1.default.join(modulesDir, moduleFile);
|
|
170
|
-
// recursively import modules from subdirectories
|
|
171
|
-
if (fs_1.default.lstatSync(modulePath).isDirectory()) {
|
|
172
|
-
this.registerCommandsFromDir(modulePath);
|
|
173
|
-
continue;
|
|
174
|
-
}
|
|
175
|
-
// only import modules files ends with with Command.js
|
|
176
|
-
if (!moduleFile.endsWith('Command.js')) {
|
|
177
|
-
continue;
|
|
178
|
-
}
|
|
179
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
180
|
-
const module = require(modulePath);
|
|
181
|
-
const moduleConstructor = typeof module.default === 'function' ? module.default : module;
|
|
182
|
-
const moduleInstance = new moduleConstructor();
|
|
183
|
-
if (!(moduleInstance instanceof BaseCommand_1.default)) {
|
|
184
|
-
core_1.utils.haltOrThrow('loading a command that does not extend BaseCommand');
|
|
185
|
-
}
|
|
186
|
-
const commandName = moduleInstance.getCommandName();
|
|
187
|
-
if (this.modules.has(commandName)) {
|
|
188
|
-
// resolve conflict
|
|
189
|
-
const ossCommandLoaded = !core_2.fileManager.isWithinInternalDirectory(this.modulePaths.get(commandName));
|
|
190
|
-
const loadingOssCommand = !core_2.fileManager.isWithinInternalDirectory(modulePath);
|
|
191
|
-
if (ossCommandLoaded === loadingOssCommand) {
|
|
192
|
-
// when both commands are open source or neither are open source
|
|
193
|
-
core_2.info.midLevel(`MemLab command ${commandName} is already registered`);
|
|
194
|
-
}
|
|
195
|
-
else if (!ossCommandLoaded && loadingOssCommand) {
|
|
196
|
-
// when open source command tries to overwrite non-open source command
|
|
197
|
-
continue;
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
this.modules.set(commandName, moduleInstance);
|
|
201
|
-
this.modulePaths.set(commandName, modulePath);
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
142
|
}
|
|
205
143
|
exports.default = new CommandDispatcher();
|
|
@@ -8,13 +8,15 @@
|
|
|
8
8
|
* @format
|
|
9
9
|
*/
|
|
10
10
|
import type { BaseOption, CLIOptions } from '@memlab/core';
|
|
11
|
-
import BaseCommand from '../BaseCommand';
|
|
11
|
+
import BaseCommand, { CommandCategory } from '../BaseCommand';
|
|
12
12
|
export default class MemLabRunCommand extends BaseCommand {
|
|
13
13
|
getCommandName(): string;
|
|
14
14
|
getDescription(): string;
|
|
15
15
|
getExamples(): string[];
|
|
16
16
|
getPrerequisites(): BaseCommand[];
|
|
17
17
|
getOptions(): BaseOption[];
|
|
18
|
+
getExcludedOptions(): BaseOption[];
|
|
19
|
+
getCategory(): CommandCategory;
|
|
18
20
|
run(options: CLIOptions): Promise<void>;
|
|
19
21
|
}
|
|
20
22
|
//# sourceMappingURL=MemLabRunCommand.d.ts.map
|
|
@@ -8,6 +8,29 @@
|
|
|
8
8
|
* @emails oncall+ws_labs
|
|
9
9
|
* @format
|
|
10
10
|
*/
|
|
11
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
12
|
+
if (k2 === undefined) k2 = k;
|
|
13
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
14
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
15
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
16
|
+
}
|
|
17
|
+
Object.defineProperty(o, k2, desc);
|
|
18
|
+
}) : (function(o, m, k, k2) {
|
|
19
|
+
if (k2 === undefined) k2 = k;
|
|
20
|
+
o[k2] = m[k];
|
|
21
|
+
}));
|
|
22
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
23
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
24
|
+
}) : function(o, v) {
|
|
25
|
+
o["default"] = v;
|
|
26
|
+
});
|
|
27
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
11
34
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
12
35
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
13
36
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -24,11 +47,20 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
24
47
|
const fs_1 = __importDefault(require("fs"));
|
|
25
48
|
const path_1 = __importDefault(require("path"));
|
|
26
49
|
const core_1 = require("@memlab/core");
|
|
27
|
-
const BaseCommand_1 =
|
|
50
|
+
const BaseCommand_1 = __importStar(require("../BaseCommand"));
|
|
28
51
|
const CheckLeakCommand_1 = __importDefault(require("./heap/CheckLeakCommand"));
|
|
29
52
|
const InitDirectoryCommand_1 = __importDefault(require("./InitDirectoryCommand"));
|
|
30
53
|
const TakeSnapshotCommand_1 = __importDefault(require("./snapshot/TakeSnapshotCommand"));
|
|
31
54
|
const SetWorkingDirectoryOption_1 = __importDefault(require("../options/SetWorkingDirectoryOption"));
|
|
55
|
+
const AppOption_1 = __importDefault(require("../options/AppOption"));
|
|
56
|
+
const InteractionOption_1 = __importDefault(require("../options/InteractionOption"));
|
|
57
|
+
const SkipSnapshotOption_1 = __importDefault(require("../options/SkipSnapshotOption"));
|
|
58
|
+
const RunningModeOption_1 = __importDefault(require("../options/RunningModeOption"));
|
|
59
|
+
const BaselineFileOption_1 = __importDefault(require("../options/heap/BaselineFileOption"));
|
|
60
|
+
const TargetFileOption_1 = __importDefault(require("../options/heap/TargetFileOption"));
|
|
61
|
+
const FinalFileOption_1 = __importDefault(require("../options/heap/FinalFileOption"));
|
|
62
|
+
const SnapshotDirectoryOption_1 = __importDefault(require("../options/heap/SnapshotDirectoryOption"));
|
|
63
|
+
const JSEngineOption_1 = __importDefault(require("../options/heap/JSEngineOption"));
|
|
32
64
|
class MemLabRunCommand extends BaseCommand_1.default {
|
|
33
65
|
getCommandName() {
|
|
34
66
|
return 'run';
|
|
@@ -37,7 +69,11 @@ class MemLabRunCommand extends BaseCommand_1.default {
|
|
|
37
69
|
return 'find memory leaks in web apps';
|
|
38
70
|
}
|
|
39
71
|
getExamples() {
|
|
40
|
-
return [
|
|
72
|
+
return [
|
|
73
|
+
'--scenario <TEST_SCENARIO_FILE>',
|
|
74
|
+
'--scenario /tmp/test-scenario.js',
|
|
75
|
+
'--scenario /tmp/test-scenario.js --work-dir /tmp/test-1/',
|
|
76
|
+
];
|
|
41
77
|
}
|
|
42
78
|
getPrerequisites() {
|
|
43
79
|
return [
|
|
@@ -49,6 +85,22 @@ class MemLabRunCommand extends BaseCommand_1.default {
|
|
|
49
85
|
getOptions() {
|
|
50
86
|
return [new SetWorkingDirectoryOption_1.default()];
|
|
51
87
|
}
|
|
88
|
+
getExcludedOptions() {
|
|
89
|
+
return [
|
|
90
|
+
new AppOption_1.default(),
|
|
91
|
+
new InteractionOption_1.default(),
|
|
92
|
+
new SkipSnapshotOption_1.default(),
|
|
93
|
+
new RunningModeOption_1.default(),
|
|
94
|
+
new BaselineFileOption_1.default(),
|
|
95
|
+
new TargetFileOption_1.default(),
|
|
96
|
+
new FinalFileOption_1.default(),
|
|
97
|
+
new SnapshotDirectoryOption_1.default(),
|
|
98
|
+
new JSEngineOption_1.default(),
|
|
99
|
+
];
|
|
100
|
+
}
|
|
101
|
+
getCategory() {
|
|
102
|
+
return BaseCommand_1.CommandCategory.COMMON;
|
|
103
|
+
}
|
|
52
104
|
run(options) {
|
|
53
105
|
var _a;
|
|
54
106
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -45,7 +45,7 @@ class PrintSummaryCommand extends BaseCommand_1.default {
|
|
|
45
45
|
const workDir = (_a = options.configFromOptions) === null || _a === void 0 ? void 0 : _a.workDir;
|
|
46
46
|
const summaryFile = core_2.fileManager.getLeakSummaryFile({ workDir });
|
|
47
47
|
if (!fs_extra_1.default.existsSync(summaryFile)) {
|
|
48
|
-
core_1.utils.haltOrThrow('No MemLab leak summary found. Please make sure "memlab
|
|
48
|
+
core_1.utils.haltOrThrow('No MemLab leak summary found. Please make sure "memlab find-leaks" runs successfully first.');
|
|
49
49
|
}
|
|
50
50
|
const content = fs_extra_1.default.readFileSync(summaryFile, 'UTF-8');
|
|
51
51
|
core_2.info.topLevel(content);
|
|
@@ -14,6 +14,7 @@ export default class RunMeasureCommand extends BaseCommand {
|
|
|
14
14
|
getCommandName(): string;
|
|
15
15
|
getDescription(): string;
|
|
16
16
|
getPrerequisites(): BaseCommand[];
|
|
17
|
+
getExamples(): string[];
|
|
17
18
|
getOptions(): BaseOption[];
|
|
18
19
|
run(options: CLIOptions): Promise<void>;
|
|
19
20
|
}
|
|
@@ -50,6 +50,13 @@ class RunMeasureCommand extends BaseCommand_1.default {
|
|
|
50
50
|
getPrerequisites() {
|
|
51
51
|
return [new CleanRunDataCommand_1.default(), new InitDirectoryCommand_1.default()];
|
|
52
52
|
}
|
|
53
|
+
getExamples() {
|
|
54
|
+
return [
|
|
55
|
+
'--scenario <TEST_SCENARIO_FILE>',
|
|
56
|
+
'--scenario /tmp/test-scenario.js',
|
|
57
|
+
'--scenario /tmp/test-scenario.js --work-dir /tmp/test-1/',
|
|
58
|
+
];
|
|
59
|
+
}
|
|
53
60
|
getOptions() {
|
|
54
61
|
return [
|
|
55
62
|
new NumberOfRunsOption_1.default(),
|
|
@@ -14,6 +14,7 @@ export default class FBWarmupAppCommand extends BaseCommand {
|
|
|
14
14
|
getCommandName(): string;
|
|
15
15
|
getDescription(): string;
|
|
16
16
|
getPrerequisites(): BaseCommand[];
|
|
17
|
+
getExamples(): string[];
|
|
17
18
|
getOptions(): BaseOption[];
|
|
18
19
|
run(_options: CLIOptions): Promise<void>;
|
|
19
20
|
}
|
|
@@ -43,6 +43,12 @@ class FBWarmupAppCommand extends BaseCommand_1.default {
|
|
|
43
43
|
getPrerequisites() {
|
|
44
44
|
return [new InitDirectoryCommand_1.default(), new CheckXvfbSupportCommand_1.default()];
|
|
45
45
|
}
|
|
46
|
+
getExamples() {
|
|
47
|
+
return [
|
|
48
|
+
'--scenario <TEST_SCENARIO_FILE>',
|
|
49
|
+
'--scenario /tmp/test-scenario.js',
|
|
50
|
+
];
|
|
51
|
+
}
|
|
46
52
|
getOptions() {
|
|
47
53
|
return [
|
|
48
54
|
new AppOption_1.default(),
|
|
@@ -57,9 +57,10 @@ const TraceAllObjectsOption_1 = __importDefault(require("../../options/heap/Trac
|
|
|
57
57
|
const LogTraceAsClusterOption_1 = __importDefault(require("../../options/heap/LogTraceAsClusterOption"));
|
|
58
58
|
const CleanLoggerDataCommand_1 = __importDefault(require("../CleanLoggerDataCommand"));
|
|
59
59
|
const LeakFilterFileOption_1 = __importDefault(require("../../options/heap/leak-filter/LeakFilterFileOption"));
|
|
60
|
+
const LeakClusterSizeThresholdOption_1 = __importDefault(require("../../options/heap/LeakClusterSizeThresholdOption"));
|
|
60
61
|
class CheckLeakCommand extends BaseCommand_1.default {
|
|
61
62
|
getCommandName() {
|
|
62
|
-
return '
|
|
63
|
+
return 'find-leaks';
|
|
63
64
|
}
|
|
64
65
|
getDescription() {
|
|
65
66
|
return 'find memory leaks in heap snapshots';
|
|
@@ -79,6 +80,7 @@ class CheckLeakCommand extends BaseCommand_1.default {
|
|
|
79
80
|
new JSEngineOption_1.default(),
|
|
80
81
|
new LeakFilterFileOption_1.default(),
|
|
81
82
|
new OversizeThresholdOption_1.default(),
|
|
83
|
+
new LeakClusterSizeThresholdOption_1.default(),
|
|
82
84
|
new TraceAllObjectsOption_1.default(),
|
|
83
85
|
new LogTraceAsClusterOption_1.default(),
|
|
84
86
|
];
|
|
@@ -60,7 +60,7 @@ function calculateRetainerTrace() {
|
|
|
60
60
|
}
|
|
61
61
|
class GetRetainerTraceCommand extends BaseCommand_1.default {
|
|
62
62
|
getCommandName() {
|
|
63
|
-
return '
|
|
63
|
+
return 'trace';
|
|
64
64
|
}
|
|
65
65
|
getDescription() {
|
|
66
66
|
return 'report retainer trace of a specific node, use with --nodeId';
|
|
@@ -69,7 +69,11 @@ class GetRetainerTraceCommand extends BaseCommand_1.default {
|
|
|
69
69
|
return BaseCommand_1.CommandCategory.COMMON;
|
|
70
70
|
}
|
|
71
71
|
getExamples() {
|
|
72
|
-
return [
|
|
72
|
+
return [
|
|
73
|
+
'--node-id=<HEAP_OBJECT_ID>',
|
|
74
|
+
'--node-id=@3123123',
|
|
75
|
+
'--node-id=128127',
|
|
76
|
+
];
|
|
73
77
|
}
|
|
74
78
|
getOptions() {
|
|
75
79
|
return [
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @emails oncall+ws_labs
|
|
8
|
+
* @format
|
|
9
|
+
*/
|
|
10
|
+
import type { CLIOptions } from '@memlab/core';
|
|
11
|
+
import BaseCommand from '../../BaseCommand';
|
|
12
|
+
export default class GenerateCLIDocCommand extends BaseCommand {
|
|
13
|
+
private modules;
|
|
14
|
+
private generatedCommandInIndex;
|
|
15
|
+
private universalOptions;
|
|
16
|
+
getCommandName(): string;
|
|
17
|
+
getDescription(): string;
|
|
18
|
+
isInternalCommand(): boolean;
|
|
19
|
+
setModulesMap(modules: Map<string, BaseCommand>): void;
|
|
20
|
+
run(options: CLIOptions): Promise<void>;
|
|
21
|
+
private generateDocs;
|
|
22
|
+
private writeCommandCategories;
|
|
23
|
+
private writeCategory;
|
|
24
|
+
private writeCategoryHeader;
|
|
25
|
+
private writeCommand;
|
|
26
|
+
private writeTextWithNewLine;
|
|
27
|
+
private touchFile;
|
|
28
|
+
private writeCodeBlock;
|
|
29
|
+
private writeCommandOptions;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=GenerateCLIDocCommand.d.ts.map
|