Skip to content

Commit 22071d8

Browse files
feat: simplify-log-colorization (#484)
* refactor: prefer standardColors * feat: refactor log colorization logic * test: resolve ut failures * chore: remove wip test changes * fix(nuts): case-sensitive regex (#492) --------- Co-authored-by: Cristian Dominguez <[email protected]> Co-authored-by: Cristian Dominguez <[email protected]>
1 parent 6594697 commit 22071d8

File tree

21 files changed

+200
-353
lines changed

21 files changed

+200
-353
lines changed

messages/flags.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# flags.result-format.summary
2+
3+
Format of the test results.
4+
5+
# flags.code-coverage.summary
6+
7+
Retrieve code coverage results.

messages/gettest.md

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,6 @@ Provide a test run ID to display test results for an enqueued or completed async
2828

2929
ID of the test run.
3030

31-
# flags.result-format.summary
32-
33-
Format of the results.
34-
35-
# flags.code-coverage.summary
36-
37-
Retrieve code coverage results.
38-
3931
# flags.output-dir.summary
4032

4133
Directory in which to store test result files.

messages/list.md

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -21,43 +21,3 @@ To fetch a specific log from your org, obtain the ID from this command's output,
2121
# noDebugLogsFound
2222

2323
No debug logs found in org
24-
25-
# appColHeader
26-
27-
APPLICATION
28-
29-
# durationColHeader
30-
31-
DURATION (MS)
32-
33-
# idColHeader
34-
35-
ID
36-
37-
# locationColHeader
38-
39-
LOCATION
40-
41-
# sizeColHeader
42-
43-
SIZE (B)
44-
45-
# userColHeader
46-
47-
LOG USER
48-
49-
# operationColHeader
50-
51-
OPERATION
52-
53-
# requestColHeader
54-
55-
REQUEST
56-
57-
# timeColHeader
58-
59-
START TIME
60-
61-
# statusColHeader
62-
63-
STATUS

messages/runtest.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,6 @@ NOTE: The testRunCoverage value (JSON and JUnit result formats) is a percentage
3434

3535
<%= config.bin %> <%= command.id %> --test-level RunLocalTests --output-dir <path to outputdir> --target-org [email protected]
3636

37-
# flags.result-format.summary
38-
39-
Format of the test results.
40-
4137
# flags.class-names.summary
4238

4339
Apex test class names to run; default is all classes.

package.json

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,13 @@
1010
"@salesforce/core": "^7.4.1",
1111
"@salesforce/kit": "^3.1.6",
1212
"@salesforce/sf-plugins-core": "^11.1.0",
13-
"chalk": "^5.3.0",
14-
"color-convert": "^2.0.1",
15-
"color-name": "^2.0.0"
13+
"ansis": "^3.2.0"
1614
},
1715
"devDependencies": {
1816
"@oclif/plugin-command-snapshot": "^5.2.2",
1917
"@salesforce/cli-plugins-testkit": "^5.3.14",
2018
"@salesforce/dev-scripts": "^10.1.1",
2119
"@salesforce/plugin-command-reference": "^3.1.2",
22-
"@types/color-convert": "^2.0.3",
2320
"eslint-plugin-sf-plugin": "^1.18.5",
2421
"oclif": "^4.12.1",
2522
"ts-node": "^10.9.2",

src/commands/apex/get/log.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import {
1414
SfCommand,
1515
} from '@salesforce/sf-plugins-core';
1616
import { Messages } from '@salesforce/core';
17-
import { colorLogs } from '../../../utils.js';
17+
import { colorLogs } from '../../../logColorize.js';
1818

1919
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
2020
const messages = Messages.loadMessages('@salesforce/plugin-apex', 'get');

src/commands/apex/get/test.ts

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import {
1616
} from '@salesforce/sf-plugins-core';
1717
import { Messages } from '@salesforce/core';
1818
import { RunResult, TestReporter } from '../../../reporters/index.js';
19-
import { resultFormat } from '../../../utils.js';
19+
import { codeCoverageFlag, resultFormatFlag } from '../../../flags.js';
2020

2121
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
2222
const messages = Messages.loadMessages('@salesforce/plugin-apex', 'gettest');
@@ -40,26 +40,14 @@ export default class Test extends SfCommand<RunResult> {
4040
startsWith: '707',
4141
length: 'both',
4242
}),
43-
'code-coverage': Flags.boolean({
44-
aliases: ['codecoverage'],
45-
deprecateAliases: true,
46-
char: 'c',
47-
summary: messages.getMessage('flags.code-coverage.summary'),
48-
}),
43+
'code-coverage': codeCoverageFlag,
4944
'output-dir': Flags.directory({
5045
aliases: ['outputdir', 'output-directory'],
5146
deprecateAliases: true,
5247
char: 'd',
5348
summary: messages.getMessage('flags.output-dir.summary'),
5449
}),
55-
'result-format': Flags.string({
56-
deprecateAliases: true,
57-
aliases: ['resultformat'],
58-
char: 'r',
59-
summary: messages.getMessage('flags.result-format.summary'),
60-
options: resultFormat,
61-
default: 'human',
62-
}),
50+
'result-format': resultFormatFlag,
6351
};
6452

6553
public async run(): Promise<RunResult> {

src/commands/apex/list/log.ts

Lines changed: 30 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
1818
const messages = Messages.loadMessages('@salesforce/plugin-apex', 'list');
1919

2020
export type LogListResult = LogRecord[];
21+
type LogForTable = Omit<LogRecord, 'DurationMilliseconds' | 'User'> & { DurationMilliseconds: string; User: string };
2122

2223
export default class Log extends SfCommand<LogListResult> {
2324
public static readonly summary = messages.getMessage('summary');
@@ -35,61 +36,45 @@ export default class Log extends SfCommand<LogListResult> {
3536
public async run(): Promise<LogListResult> {
3637
const { flags } = await this.parse(Log);
3738

38-
const conn = flags['target-org'].getConnection(flags['api-version']);
39-
const logService = new LogService(conn);
40-
const logRecords = await logService.getLogRecords();
39+
const logService = new LogService(flags['target-org'].getConnection(flags['api-version']));
40+
const logRecords = (await logService.getLogRecords()).map(formatStartTime);
4141

4242
if (logRecords.length === 0) {
4343
this.log(messages.getMessage('noDebugLogsFound'));
4444
return [];
4545
}
4646

47-
logRecords.map((logRecord) => {
48-
logRecord.StartTime = this.formatTime(logRecord.StartTime);
49-
});
50-
5147
if (!flags.json) {
5248
// while not required to prevent table output, save a few iterations if only printing json
53-
const cleanLogs = logRecords.map((logRecord) => ({
54-
app: logRecord.Application,
55-
duration: String(logRecord.DurationMilliseconds),
56-
id: logRecord.Id,
57-
location: logRecord.Location,
58-
size: String(logRecord.LogLength),
59-
user: logRecord.LogUser.Name,
60-
operation: logRecord.Operation,
61-
request: logRecord.Request,
62-
time: logRecord.StartTime,
63-
status: logRecord.Status,
64-
}));
65-
66-
this.table(
67-
cleanLogs,
68-
{
69-
app: { header: messages.getMessage('appColHeader') },
70-
duration: { header: messages.getMessage('durationColHeader') },
71-
id: { header: messages.getMessage('idColHeader') },
72-
location: { header: messages.getMessage('locationColHeader') },
73-
size: { header: messages.getMessage('sizeColHeader') },
74-
user: { header: messages.getMessage('userColHeader') },
75-
operation: { header: messages.getMessage('operationColHeader') },
76-
request: { header: messages.getMessage('requestColHeader') },
77-
time: { header: messages.getMessage('timeColHeader') },
78-
status: { header: messages.getMessage('statusColHeader') },
79-
},
80-
{ 'no-truncate': true }
81-
);
49+
this.table(logRecords.map(formatForTable), tableHeaders, { 'no-truncate': true });
8250
}
8351

8452
return logRecords;
8553
}
86-
87-
// eslint-disable-next-line class-methods-use-this
88-
private formatTime(time: string): string {
89-
const milliIndex = time.indexOf('.');
90-
if (milliIndex !== -1) {
91-
return time.substring(0, milliIndex) + time.substring(milliIndex + 4);
92-
}
93-
return time;
94-
}
9554
}
55+
56+
const formatForTable = (logRecord: LogRecord): LogForTable => ({
57+
...logRecord,
58+
DurationMilliseconds: String(logRecord.DurationMilliseconds),
59+
User: logRecord.LogUser.Name,
60+
});
61+
62+
export const formatStartTime = (lr: LogRecord): LogRecord => ({ ...lr, StartTime: formatTime(lr.StartTime) });
63+
64+
const formatTime = (time: string): string => {
65+
const msIndex = time.indexOf('.');
66+
return msIndex !== -1 ? time.substring(0, msIndex) + time.substring(msIndex + 4) : time;
67+
};
68+
69+
const tableHeaders = {
70+
Application: { header: 'Application' },
71+
DurationMilliseconds: { header: 'Duration (ms)' },
72+
Id: { header: 'Id' },
73+
Location: { header: 'Location' },
74+
LogLength: { header: 'Size (B)' },
75+
User: { header: 'Log User' },
76+
Operation: { header: 'Operation' },
77+
Request: { header: 'Request' },
78+
StartTime: { header: 'Start Time' },
79+
Status: { header: 'Status' },
80+
};

src/commands/apex/run/test.ts

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import {
1818
import { Messages, SfError } from '@salesforce/core';
1919
import { Duration } from '@salesforce/kit';
2020
import { RunResult, TestReporter } from '../../../reporters/index.js';
21-
import { resultFormat } from '../../../utils.js';
21+
import { codeCoverageFlag, resultFormatFlag } from '../../../flags.js';
2222

2323
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
2424
const messages = Messages.loadMessages('@salesforce/plugin-apex', 'runtest');
@@ -37,12 +37,7 @@ export default class Test extends SfCommand<RunCommandResult> {
3737
'target-org': requiredOrgFlagWithDeprecations,
3838
'api-version': orgApiVersionFlagWithDeprecations,
3939
loglevel,
40-
'code-coverage': Flags.boolean({
41-
aliases: ['codecoverage'],
42-
deprecateAliases: true,
43-
char: 'c',
44-
summary: messages.getMessage('flags.code-coverage.summary'),
45-
}),
40+
'code-coverage': codeCoverageFlag,
4641
'output-dir': Flags.directory({
4742
aliases: ['outputdir', 'output-directory'],
4843
deprecateAliases: true,
@@ -65,14 +60,7 @@ export default class Test extends SfCommand<RunCommandResult> {
6560
description: messages.getMessage('flags.class-names.description'),
6661
exclusive: exclusiveTestSpecifiers.filter((specifier) => specifier !== 'class-names'),
6762
}),
68-
'result-format': Flags.string({
69-
deprecateAliases: true,
70-
aliases: ['resultformat'],
71-
char: 'r',
72-
summary: messages.getMessage('flags.result-format.summary'),
73-
options: resultFormat,
74-
default: 'human',
75-
}),
63+
'result-format': resultFormatFlag,
7664
'suite-names': arrayWithDeprecation({
7765
deprecateAliases: true,
7866
aliases: ['suitenames'],

src/commands/apex/tail/log.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import {
1414
loglevel,
1515
} from '@salesforce/sf-plugins-core';
1616
import { Connection, Messages } from '@salesforce/core';
17-
import { colorizeLog } from '../../../legacyColorization.js';
17+
import { colorLogs } from '../../../logColorize.js';
1818

1919
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
2020
const messages = Messages.loadMessages('@salesforce/plugin-apex', 'tail');
@@ -66,10 +66,11 @@ export default class Log extends SfCommand<void> {
6666
this.log(messages.getMessage('finishedTailing'));
6767
}
6868

69+
// the colorize function used to be async, but not isn't. Preserving the public method signature
70+
// eslint-disable-next-line @typescript-eslint/require-await
6971
public async logTailer(fullLog: string): Promise<void> {
7072
if (fullLog) {
71-
const output = this.color ? await colorizeLog(fullLog) : fullLog;
72-
this.log(output);
73+
this.log(this.color ? colorLogs(fullLog) : fullLog);
7374
}
7475
}
7576

0 commit comments

Comments
 (0)