@memlab/cli 1.0.23 → 1.0.25

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.
Files changed (52) hide show
  1. package/dist/BaseCommand.d.ts +4 -3
  2. package/dist/BaseCommand.js +11 -1
  3. package/dist/Dispatcher.js +6 -0
  4. package/dist/commands/MemLabRunCommand.d.ts +2 -2
  5. package/dist/commands/RunMeasureCommand.d.ts +2 -2
  6. package/dist/commands/RunMeasureCommand.js +3 -2
  7. package/dist/commands/WarmupAppCommand.d.ts +2 -2
  8. package/dist/commands/WarmupAppCommand.js +2 -0
  9. package/dist/commands/heap/CheckLeakCommand.d.ts +12 -1
  10. package/dist/commands/heap/CheckLeakCommand.js +71 -9
  11. package/dist/commands/heap/DiffLeakCommand.d.ts +13 -2
  12. package/dist/commands/heap/DiffLeakCommand.js +49 -25
  13. package/dist/commands/heap/GetRetainerTraceCommand.d.ts +2 -2
  14. package/dist/commands/heap/HeapAnalysisCommand.d.ts +2 -2
  15. package/dist/commands/heap/interactive/InteractiveHeapCommand.d.ts +2 -2
  16. package/dist/commands/heap/interactive/InteractiveHeapExploreCommand.d.ts +2 -2
  17. package/dist/commands/heap/interactive/ui-components/CliScreen.d.ts +5 -0
  18. package/dist/commands/heap/interactive/ui-components/CliScreen.js +51 -11
  19. package/dist/commands/heap/interactive/ui-components/HeapViewController.d.ts +2 -0
  20. package/dist/commands/heap/interactive/ui-components/HeapViewController.js +5 -1
  21. package/dist/commands/heap/interactive/ui-components/HeapViewUtils.d.ts +2 -0
  22. package/dist/commands/heap/interactive/ui-components/HeapViewUtils.js +25 -21
  23. package/dist/commands/heap/interactive/ui-components/ListComponent.js +2 -1
  24. package/dist/commands/helper/GenerateCLIDocCommand.js +16 -8
  25. package/dist/commands/helper/HelperCommand.d.ts +7 -4
  26. package/dist/commands/helper/HelperCommand.js +34 -27
  27. package/dist/commands/helper/lib/DocUtils.d.ts +19 -0
  28. package/dist/commands/helper/lib/DocUtils.js +39 -0
  29. package/dist/commands/snapshot/TakeSnapshotCommand.d.ts +2 -2
  30. package/dist/commands/snapshot/TakeSnapshotCommand.js +2 -0
  31. package/dist/commands/snapshot/WarmupAndSnapshotCommand.d.ts +3 -1
  32. package/dist/commands/snapshot/WarmupAndSnapshotCommand.js +23 -0
  33. package/dist/lib/CLIUtils.d.ts +22 -0
  34. package/dist/lib/CLIUtils.js +129 -0
  35. package/dist/options/MLClusteringOption.d.ts +1 -0
  36. package/dist/options/MLClusteringOption.js +4 -0
  37. package/dist/options/NumberOfRunsOption.d.ts +4 -2
  38. package/dist/options/NumberOfRunsOption.js +12 -4
  39. package/dist/options/SetMaxClusterSampleSizeOption.d.ts +19 -0
  40. package/dist/options/SetMaxClusterSampleSizeOption.js +49 -0
  41. package/dist/options/e2e/SetChromiumBinaryOption.d.ts +18 -0
  42. package/dist/options/e2e/SetChromiumBinaryOption.js +43 -0
  43. package/dist/options/experiment/SetControlWorkDirOption.d.ts +3 -2
  44. package/dist/options/experiment/SetControlWorkDirOption.js +25 -6
  45. package/dist/options/experiment/SetTreatmentWorkDirOption.js +6 -0
  46. package/dist/options/heap/SetTraceContainsFilterOption.d.ts +18 -0
  47. package/dist/options/heap/SetTraceContainsFilterOption.js +42 -0
  48. package/dist/options/heap/TraceAllObjectsOption.d.ts +4 -2
  49. package/dist/options/heap/TraceAllObjectsOption.js +32 -4
  50. package/dist/options/lib/OptionConstant.d.ts +6 -0
  51. package/dist/options/lib/OptionConstant.js +3 -0
  52. package/package.json +1 -1
@@ -0,0 +1,129 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.alignTextInBlock = exports.getBlankSpaceString = exports.argsToString = exports.filterAndGetUndefinedArgs = exports.READABLE_TEXT_WIDTH = exports.READABLE_CMD_FLAG_WIDTH = void 0;
7
+ const string_width_1 = __importDefault(require("string-width"));
8
+ const core_1 = require("@memlab/core");
9
+ const OptionConstant_1 = __importDefault(require("../options/lib/OptionConstant"));
10
+ const breakableSymbolOnRight = new Set([
11
+ ' ',
12
+ '\t',
13
+ ',',
14
+ '.',
15
+ ':',
16
+ ';',
17
+ '!',
18
+ '?',
19
+ ')',
20
+ ']',
21
+ '}',
22
+ '>',
23
+ ]);
24
+ const breakableSymbolOnLeft = new Set([' ', '\t', '(', '[', '{', '<']);
25
+ exports.READABLE_CMD_FLAG_WIDTH = 70;
26
+ exports.READABLE_TEXT_WIDTH = 150;
27
+ function filterAndGetUndefinedArgs(cliArgs) {
28
+ const ret = Object.create(null);
29
+ const memlabFBOptionNames = new Set(Object.values(Object.assign({}, OptionConstant_1.default.optionNames)));
30
+ for (const optionName of Object.keys(cliArgs)) {
31
+ if (optionName === '_') {
32
+ continue;
33
+ }
34
+ if (memlabFBOptionNames.has(optionName)) {
35
+ continue;
36
+ }
37
+ ret[optionName] = cliArgs[optionName];
38
+ }
39
+ return ret;
40
+ }
41
+ exports.filterAndGetUndefinedArgs = filterAndGetUndefinedArgs;
42
+ function argsToString(args) {
43
+ let ret = '';
44
+ for (const optionName of Object.keys(args)) {
45
+ if (optionName === '_') {
46
+ continue;
47
+ }
48
+ const value = args[optionName];
49
+ if (value === true) {
50
+ ret += `--${optionName} `;
51
+ }
52
+ else if (Array.isArray(value)) {
53
+ value.forEach(v => {
54
+ ret += `--${optionName}=${v} `;
55
+ });
56
+ }
57
+ else {
58
+ ret += `--${optionName}=${value} `;
59
+ }
60
+ }
61
+ return ret.trim();
62
+ }
63
+ exports.argsToString = argsToString;
64
+ function getBlankSpaceString(length) {
65
+ let ret = '';
66
+ for (let i = 0; i < length; ++i) {
67
+ ret += ' ';
68
+ }
69
+ return ret;
70
+ }
71
+ exports.getBlankSpaceString = getBlankSpaceString;
72
+ function alignTextInBlock(text, options) {
73
+ var _a, _b;
74
+ const indent = (_a = options.leftIndent) !== null && _a !== void 0 ? _a : 0;
75
+ const maxLineWidth = Math.min(exports.READABLE_TEXT_WIDTH, (_b = options.lineLength) !== null && _b !== void 0 ? _b : process.stdout.columns);
76
+ if (indent < 0 || maxLineWidth <= 0 || indent >= maxLineWidth) {
77
+ throw core_1.utils.haltOrThrow('invalid indent or maximum line width');
78
+ }
79
+ const indentString = getBlankSpaceString(indent);
80
+ const inputLines = text.split('\n');
81
+ const outputLines = [];
82
+ while (inputLines.length > 0) {
83
+ const line = inputLines.shift();
84
+ // if the current line can fit in cmd row
85
+ if ((0, string_width_1.default)(indentString + line) <= maxLineWidth) {
86
+ outputLines.push(indentString + line);
87
+ continue;
88
+ }
89
+ // otherwise split the current line
90
+ const intendedSplitPoint = maxLineWidth - indent;
91
+ const splitLines = splitIntoReadableSubstrings(line, intendedSplitPoint);
92
+ const [firstLine, restLine] = splitLines;
93
+ outputLines.push(indentString + firstLine);
94
+ inputLines.unshift(restLine);
95
+ }
96
+ return outputLines.join('\n');
97
+ }
98
+ exports.alignTextInBlock = alignTextInBlock;
99
+ function splitIntoReadableSubstrings(text, intendedSplitPoint) {
100
+ if (intendedSplitPoint >= text.length) {
101
+ return [text];
102
+ }
103
+ let splitPoint = intendedSplitPoint;
104
+ while (splitPoint > 0) {
105
+ const ch = text[splitPoint];
106
+ if (breakableSymbolOnLeft.has(ch)) {
107
+ break;
108
+ }
109
+ if (splitPoint - 1 > 0 &&
110
+ breakableSymbolOnRight.has(text[splitPoint - 1])) {
111
+ break;
112
+ }
113
+ --splitPoint;
114
+ }
115
+ if (splitPoint <= 0) {
116
+ splitPoint = intendedSplitPoint;
117
+ }
118
+ // if the second line starts with a ' ',
119
+ // skip the empty space
120
+ const firstLine = text.substring(0, splitPoint);
121
+ let secondLine = text.substring(splitPoint);
122
+ if (secondLine.startsWith(' ')) {
123
+ secondLine = secondLine.substring(1);
124
+ }
125
+ if (secondLine.length === 0) {
126
+ return [firstLine];
127
+ }
128
+ return [firstLine, secondLine];
129
+ }
@@ -13,6 +13,7 @@ import { BaseOption } from '@memlab/core';
13
13
  export default class MLClusteringOption extends BaseOption {
14
14
  getOptionName(): string;
15
15
  getDescription(): string;
16
+ static hasOptionSet(args: ParsedArgs): boolean;
16
17
  parse(config: MemLabConfig, args: ParsedArgs): Promise<void>;
17
18
  }
18
19
  //# sourceMappingURL=MLClusteringOption.d.ts.map
@@ -30,6 +30,10 @@ class MLClusteringOption extends core_1.BaseOption {
30
30
  getDescription() {
31
31
  return 'use machine learning algorithms for clustering leak traces (by default, traces are clustered by heuristics)';
32
32
  }
33
+ static hasOptionSet(args) {
34
+ const name = OptionConstant_1.default.optionNames.ML_CLUSTERING;
35
+ return args[name] != null;
36
+ }
33
37
  parse(config, args) {
34
38
  return __awaiter(this, void 0, void 0, function* () {
35
39
  const name = this.getOptionName();
@@ -8,13 +8,15 @@
8
8
  * @oncall web_perf_infra
9
9
  */
10
10
  import type { ParsedArgs } from 'minimist';
11
- import type { AnyRecord, MemLabConfig } from '@memlab/core';
11
+ import type { AnyRecord, MemLabConfig, Optional } from '@memlab/core';
12
12
  import { BaseOption } from '@memlab/core';
13
13
  export default class NumberOfRunsOption extends BaseOption {
14
- static DEFAULT_NUM_RUNS: number;
14
+ private defaultRunNumber;
15
+ constructor(runNumber?: number);
15
16
  getOptionName(): string;
16
17
  getDescription(): string;
17
18
  getExampleValues(): string[];
19
+ static getParsedOption(configFromOptions: Optional<AnyRecord>): number;
18
20
  parse(config: MemLabConfig, args: ParsedArgs): Promise<AnyRecord>;
19
21
  }
20
22
  //# sourceMappingURL=NumberOfRunsOption.d.ts.map
@@ -23,7 +23,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
23
23
  Object.defineProperty(exports, "__esModule", { value: true });
24
24
  const core_1 = require("@memlab/core");
25
25
  const OptionConstant_1 = __importDefault(require("./lib/OptionConstant"));
26
+ const DEFAULT_NUM_RUNS = 10;
26
27
  class NumberOfRunsOption extends core_1.BaseOption {
28
+ constructor(runNumber = DEFAULT_NUM_RUNS) {
29
+ super();
30
+ this.defaultRunNumber = DEFAULT_NUM_RUNS;
31
+ this.defaultRunNumber = runNumber;
32
+ }
27
33
  getOptionName() {
28
34
  return OptionConstant_1.default.optionNames.RUN_NUM;
29
35
  }
@@ -33,16 +39,18 @@ class NumberOfRunsOption extends core_1.BaseOption {
33
39
  getExampleValues() {
34
40
  return ['5'];
35
41
  }
42
+ static getParsedOption(configFromOptions) {
43
+ const { numOfRuns } = configFromOptions !== null && configFromOptions !== void 0 ? configFromOptions : {};
44
+ const n = parseInt(`${numOfRuns}`, 10);
45
+ return isNaN(n) ? DEFAULT_NUM_RUNS : n;
46
+ }
36
47
  parse(config, args) {
37
48
  return __awaiter(this, void 0, void 0, function* () {
38
49
  const ret = Object.create(null);
39
50
  const name = this.getOptionName();
40
- ret.numOfRuns = args[name]
41
- ? args[name] | 0
42
- : NumberOfRunsOption.DEFAULT_NUM_RUNS;
51
+ ret.numOfRuns = args[name] != null ? args[name] | 0 : this.defaultRunNumber;
43
52
  return ret;
44
53
  });
45
54
  }
46
55
  }
47
56
  exports.default = NumberOfRunsOption;
48
- NumberOfRunsOption.DEFAULT_NUM_RUNS = 10;
@@ -0,0 +1,19 @@
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
+ * @format
8
+ * @oncall web_perf_infra
9
+ */
10
+ import type { ParsedArgs } from 'minimist';
11
+ import type { MemLabConfig } from '@memlab/core';
12
+ import { BaseOption } from '@memlab/core';
13
+ export default class SetMaxClusterSampleSizeOption extends BaseOption {
14
+ getOptionName(): string;
15
+ getDescription(): string;
16
+ getExampleValues(): string[];
17
+ parse(config: MemLabConfig, args: ParsedArgs): Promise<void>;
18
+ }
19
+ //# sourceMappingURL=SetMaxClusterSampleSizeOption.d.ts.map
@@ -0,0 +1,49 @@
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
+ * @format
9
+ * @oncall web_perf_infra
10
+ */
11
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
12
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
13
+ return new (P || (P = Promise))(function (resolve, reject) {
14
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
15
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
16
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
17
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
18
+ });
19
+ };
20
+ var __importDefault = (this && this.__importDefault) || function (mod) {
21
+ return (mod && mod.__esModule) ? mod : { "default": mod };
22
+ };
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ const core_1 = require("@memlab/core");
25
+ const OptionConstant_1 = __importDefault(require("./lib/OptionConstant"));
26
+ class SetMaxClusterSampleSizeOption extends core_1.BaseOption {
27
+ getOptionName() {
28
+ return OptionConstant_1.default.optionNames.MAX_CLUSTER_SAMPLE_SIZE;
29
+ }
30
+ getDescription() {
31
+ return ('specify the max number of leak traces as input to leak trace ' +
32
+ 'clustering algorithm. Big sample size will preserve more complete ' +
33
+ 'inforrmation, but may risk out-of-memory crash.');
34
+ }
35
+ getExampleValues() {
36
+ return ['5000', '10000'];
37
+ }
38
+ parse(config, args) {
39
+ return __awaiter(this, void 0, void 0, function* () {
40
+ if (args[this.getOptionName()]) {
41
+ const sampleSize = parseInt(args[this.getOptionName()], 10);
42
+ if (!isNaN(sampleSize)) {
43
+ config.maxSamplesForClustering = sampleSize;
44
+ }
45
+ }
46
+ });
47
+ }
48
+ }
49
+ exports.default = SetMaxClusterSampleSizeOption;
@@ -0,0 +1,18 @@
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
+ * @format
8
+ * @oncall web_perf_infra
9
+ */
10
+ import type { ParsedArgs } from 'minimist';
11
+ import { MemLabConfig } from '@memlab/core';
12
+ import { BaseOption } from '@memlab/core';
13
+ export default class SetChromiumBinaryOption extends BaseOption {
14
+ getOptionName(): string;
15
+ getDescription(): string;
16
+ parse(config: MemLabConfig, args: ParsedArgs): Promise<void>;
17
+ }
18
+ //# sourceMappingURL=SetChromiumBinaryOption.d.ts.map
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
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 path_1 = __importDefault(require("path"));
16
+ const fs_1 = __importDefault(require("fs"));
17
+ const core_1 = require("@memlab/core");
18
+ const OptionConstant_1 = __importDefault(require("../lib/OptionConstant"));
19
+ class SetChromiumBinaryOption extends core_1.BaseOption {
20
+ getOptionName() {
21
+ return OptionConstant_1.default.optionNames.CHROMIUM_BINARY;
22
+ }
23
+ getDescription() {
24
+ return 'set the chromium binary for E2E run';
25
+ }
26
+ parse(config, args) {
27
+ return __awaiter(this, void 0, void 0, function* () {
28
+ const name = this.getOptionName();
29
+ const arg = args[name];
30
+ if (arg) {
31
+ const binaryPath = path_1.default.resolve(process.cwd(), arg);
32
+ if (!fs_1.default.existsSync(binaryPath)) {
33
+ throw core_1.utils.haltOrThrow(`Chromium binary does not exist: ${binaryPath}`);
34
+ }
35
+ if (config.verbose) {
36
+ core_1.info.lowLevel(`Using ${binaryPath} as Chromium binary for E2E run`);
37
+ }
38
+ config.puppeteerConfig.executablePath = binaryPath;
39
+ }
40
+ });
41
+ }
42
+ }
43
+ exports.default = SetChromiumBinaryOption;
@@ -8,13 +8,14 @@
8
8
  * @oncall web_perf_infra
9
9
  */
10
10
  import type { ParsedArgs } from 'minimist';
11
- import type { MemLabConfig } from '@memlab/core';
11
+ import type { MemLabConfig, Nullable } from '@memlab/core';
12
12
  import { BaseOption } from '@memlab/core';
13
13
  export default class SetControlWorkDirOption extends BaseOption {
14
14
  getOptionName(): string;
15
15
  getDescription(): string;
16
+ protected extractAndCheckWorkDirs(args: ParsedArgs): Nullable<string[]>;
16
17
  parse(config: MemLabConfig, args: ParsedArgs): Promise<{
17
- controlWorkDir?: string;
18
+ controlWorkDirs?: Nullable<string[]>;
18
19
  }>;
19
20
  }
20
21
  //# sourceMappingURL=SetControlWorkDirOption.d.ts.map
@@ -21,6 +21,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
21
21
  return (mod && mod.__esModule) ? mod : { "default": mod };
22
22
  };
23
23
  Object.defineProperty(exports, "__esModule", { value: true });
24
+ const fs_1 = __importDefault(require("fs"));
24
25
  const core_1 = require("@memlab/core");
25
26
  const OptionConstant_1 = __importDefault(require("../lib/OptionConstant"));
26
27
  class SetControlWorkDirOption extends core_1.BaseOption {
@@ -30,14 +31,32 @@ class SetControlWorkDirOption extends core_1.BaseOption {
30
31
  getDescription() {
31
32
  return 'set the working directory of the control run';
32
33
  }
34
+ extractAndCheckWorkDirs(args) {
35
+ let dirs = [];
36
+ const name = this.getOptionName();
37
+ const flagValue = args[name];
38
+ if (!flagValue) {
39
+ return null;
40
+ }
41
+ if (Array.isArray(flagValue)) {
42
+ dirs = flagValue;
43
+ }
44
+ else {
45
+ dirs = [flagValue];
46
+ }
47
+ for (const dir of dirs) {
48
+ if (fs_1.default.existsSync(dir)) {
49
+ core_1.fileManager.createDefaultVisitOrderMetaFile({
50
+ workDir: dir,
51
+ });
52
+ }
53
+ }
54
+ return dirs;
55
+ }
33
56
  parse(config, args) {
34
57
  return __awaiter(this, void 0, void 0, function* () {
35
- const name = this.getOptionName();
36
- const ret = {};
37
- if (args[name]) {
38
- ret.controlWorkDir = args[name];
39
- }
40
- return ret;
58
+ const dirs = this.extractAndCheckWorkDirs(args);
59
+ return { controlWorkDirs: dirs };
41
60
  });
42
61
  }
43
62
  }
@@ -21,6 +21,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
21
21
  return (mod && mod.__esModule) ? mod : { "default": mod };
22
22
  };
23
23
  Object.defineProperty(exports, "__esModule", { value: true });
24
+ const fs_1 = __importDefault(require("fs"));
24
25
  const core_1 = require("@memlab/core");
25
26
  const OptionConstant_1 = __importDefault(require("../lib/OptionConstant"));
26
27
  class SetTreatmentWorkDirOption extends core_1.BaseOption {
@@ -36,6 +37,11 @@ class SetTreatmentWorkDirOption extends core_1.BaseOption {
36
37
  const ret = {};
37
38
  if (args[name]) {
38
39
  ret.treatmentWorkDir = args[name];
40
+ if (fs_1.default.existsSync(ret.treatmentWorkDir)) {
41
+ core_1.fileManager.createDefaultVisitOrderMetaFile({
42
+ workDir: ret.treatmentWorkDir,
43
+ });
44
+ }
39
45
  }
40
46
  return ret;
41
47
  });
@@ -0,0 +1,18 @@
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
+ * @format
8
+ * @oncall web_perf_infra
9
+ */
10
+ import type { ParsedArgs } from 'minimist';
11
+ import type { MemLabConfig } from '@memlab/core';
12
+ import { BaseOption } from '@memlab/core';
13
+ export default class SetTraceContainsFilterOption extends BaseOption {
14
+ getOptionName(): string;
15
+ getDescription(): string;
16
+ parse(config: MemLabConfig, args: ParsedArgs): Promise<void>;
17
+ }
18
+ //# sourceMappingURL=SetTraceContainsFilterOption.d.ts.map
@@ -0,0 +1,42 @@
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
+ * @format
9
+ * @oncall web_perf_infra
10
+ */
11
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
12
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
13
+ return new (P || (P = Promise))(function (resolve, reject) {
14
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
15
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
16
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
17
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
18
+ });
19
+ };
20
+ var __importDefault = (this && this.__importDefault) || function (mod) {
21
+ return (mod && mod.__esModule) ? mod : { "default": mod };
22
+ };
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ const core_1 = require("@memlab/core");
25
+ const OptionConstant_1 = __importDefault(require("../lib/OptionConstant"));
26
+ class SetTraceContainsFilterOption extends core_1.BaseOption {
27
+ getOptionName() {
28
+ return OptionConstant_1.default.optionNames.TRACE_CONTAINS;
29
+ }
30
+ getDescription() {
31
+ return 'set the node name or edge name to filter leak traces that contain the name';
32
+ }
33
+ parse(config, args) {
34
+ return __awaiter(this, void 0, void 0, function* () {
35
+ const filterName = args[this.getOptionName()];
36
+ if (filterName != null) {
37
+ config.filterTraceByName = filterName;
38
+ }
39
+ });
40
+ }
41
+ }
42
+ exports.default = SetTraceContainsFilterOption;
@@ -8,11 +8,13 @@
8
8
  * @oncall web_perf_infra
9
9
  */
10
10
  import type { ParsedArgs } from 'minimist';
11
- import type { MemLabConfig } from '@memlab/core';
12
- import { BaseOption } from '@memlab/core';
11
+ import { MemLabConfig } from '@memlab/core';
12
+ import { BaseOption, TraceObjectMode } from '@memlab/core';
13
13
  export default class TraceAllObjectsOption extends BaseOption {
14
14
  getOptionName(): string;
15
15
  getDescription(): string;
16
+ getAvailableOptions(): Array<string>;
17
+ getMode(optionValue: string): TraceObjectMode;
16
18
  parse(config: MemLabConfig, args: ParsedArgs): Promise<void>;
17
19
  }
18
20
  //# sourceMappingURL=TraceAllObjectsOption.d.ts.map
@@ -22,20 +22,48 @@ 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 core_2 = require("@memlab/core");
25
26
  const OptionConstant_1 = __importDefault(require("../lib/OptionConstant"));
26
- class TraceAllObjectsOption extends core_1.BaseOption {
27
+ const OversizeThresholdOption_1 = __importDefault(require("./OversizeThresholdOption"));
28
+ const optionMapping = new Map([
29
+ ['selected-js-objects', core_2.TraceObjectMode.SelectedJSObjects],
30
+ ['default', core_2.TraceObjectMode.Default],
31
+ ]);
32
+ class TraceAllObjectsOption extends core_2.BaseOption {
27
33
  getOptionName() {
28
34
  return OptionConstant_1.default.optionNames.TRACE_ALL_OBJECTS;
29
35
  }
30
36
  getDescription() {
31
- return 'dump retainer trace for all allocated objects (ignore the leak filter)';
37
+ return ('dump retainer trace for all allocated objects (ignore the leak filter), ' +
38
+ `available option modes: ${this.getAvailableOptions().join(', ')}`);
39
+ }
40
+ getAvailableOptions() {
41
+ return Array.from(optionMapping.keys()).map(mode => `--${this.getOptionName()}=${mode}`);
42
+ }
43
+ getMode(optionValue) {
44
+ // if the user specified an option value (--flag=value instead of --flag)
45
+ if (typeof optionValue === 'boolean') {
46
+ return optionMapping.get('default');
47
+ }
48
+ if (!optionMapping.has(optionValue)) {
49
+ throw core_1.utils.haltOrThrow(`Unknown option value ${optionValue}. ` +
50
+ `Available options: ${this.getAvailableOptions().join(', ')}`);
51
+ }
52
+ return optionMapping.get(optionValue);
32
53
  }
33
54
  parse(config, args) {
34
55
  return __awaiter(this, void 0, void 0, function* () {
35
- if (args[this.getOptionName()]) {
36
- config.oversizeObjectAsLeak = true;
56
+ const optionValue = args[this.getOptionName()];
57
+ if (optionValue == null) {
58
+ return;
59
+ }
60
+ config.oversizeObjectAsLeak = true;
61
+ const overSizeOptionName = new OversizeThresholdOption_1.default().getOptionName();
62
+ // oversize option will set the oversize threshold
63
+ if (!args[overSizeOptionName]) {
37
64
  config.oversizeThreshold = 0;
38
65
  }
66
+ config.traceAllObjectsMode = this.getMode(optionValue);
39
67
  });
40
68
  }
41
69
  }
@@ -14,6 +14,7 @@ declare const optionConstants: {
14
14
  CLEAN_UP_SNAPSHOT: string;
15
15
  CONTINUS_TEST: string;
16
16
  CONTROL_WORK_DIR: string;
17
+ CHROMIUM_BINARY: string;
17
18
  DEVICE: string;
18
19
  DISABLE_WEB_SECURITY: string;
19
20
  DISABLE_XVFB: string;
@@ -27,6 +28,7 @@ declare const optionConstants: {
27
28
  LEAK_FILTER: string;
28
29
  LOCAL_PUPPETEER: string;
29
30
  LOG_SCRIPT: string;
31
+ MAX_CLUSTER_SAMPLE_SIZE: string;
30
32
  ML_CLUSTERING: string;
31
33
  ML_CLUSTERING_MAX_DF: string;
32
34
  ML_LINKAGE_MAX_DIST: string;
@@ -49,6 +51,7 @@ declare const optionConstants: {
49
51
  SNAPSHOT_DIR: string;
50
52
  TARGET: string;
51
53
  TRACE_ALL_OBJECTS: string;
54
+ TRACE_CONTAINS: string;
52
55
  TRACE_OBJECT_SIZE_ABOVE: string;
53
56
  TREATMENT_WORK_DIR: string;
54
57
  USER_AGENT: string;
@@ -71,6 +74,7 @@ declare const _default: {
71
74
  CLEAN_UP_SNAPSHOT: string;
72
75
  CONTINUS_TEST: string;
73
76
  CONTROL_WORK_DIR: string;
77
+ CHROMIUM_BINARY: string;
74
78
  DEVICE: string;
75
79
  DISABLE_WEB_SECURITY: string;
76
80
  DISABLE_XVFB: string;
@@ -84,6 +88,7 @@ declare const _default: {
84
88
  LEAK_FILTER: string;
85
89
  LOCAL_PUPPETEER: string;
86
90
  LOG_SCRIPT: string;
91
+ MAX_CLUSTER_SAMPLE_SIZE: string;
87
92
  ML_CLUSTERING: string;
88
93
  ML_CLUSTERING_MAX_DF: string;
89
94
  ML_LINKAGE_MAX_DIST: string;
@@ -106,6 +111,7 @@ declare const _default: {
106
111
  SNAPSHOT_DIR: string;
107
112
  TARGET: string;
108
113
  TRACE_ALL_OBJECTS: string;
114
+ TRACE_CONTAINS: string;
109
115
  TRACE_OBJECT_SIZE_ABOVE: string;
110
116
  TREATMENT_WORK_DIR: string;
111
117
  USER_AGENT: string;
@@ -16,6 +16,7 @@ const optionNames = {
16
16
  CLEAN_UP_SNAPSHOT: 'clean-up-snapshot',
17
17
  CONTINUS_TEST: 'ContinuousTest',
18
18
  CONTROL_WORK_DIR: 'control-work-dir',
19
+ CHROMIUM_BINARY: 'chromium-binary',
19
20
  DEVICE: 'device',
20
21
  DISABLE_WEB_SECURITY: 'disable-web-security',
21
22
  DISABLE_XVFB: 'disable-xvfb',
@@ -29,6 +30,7 @@ const optionNames = {
29
30
  LEAK_FILTER: 'leak-filter',
30
31
  LOCAL_PUPPETEER: 'local-puppeteer',
31
32
  LOG_SCRIPT: 'log-script',
33
+ MAX_CLUSTER_SAMPLE_SIZE: 'max-cluster-sample-size',
32
34
  ML_CLUSTERING: 'ml-clustering',
33
35
  ML_CLUSTERING_MAX_DF: 'ml-clustering-max-df',
34
36
  ML_LINKAGE_MAX_DIST: 'ml-linkage-max-dist',
@@ -51,6 +53,7 @@ const optionNames = {
51
53
  SNAPSHOT_DIR: 'snapshot-dir',
52
54
  TARGET: 'target',
53
55
  TRACE_ALL_OBJECTS: 'trace-all-objects',
56
+ TRACE_CONTAINS: 'trace-contains',
54
57
  TRACE_OBJECT_SIZE_ABOVE: 'trace-object-size-above',
55
58
  TREATMENT_WORK_DIR: 'treatment-work-dir',
56
59
  USER_AGENT: 'user-agent',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memlab/cli",
3
- "version": "1.0.23",
3
+ "version": "1.0.25",
4
4
  "license": "MIT",
5
5
  "description": "command line interface for memlab",
6
6
  "author": "Liang Gong <lgong@fb.com>",