Skip to content

Commit fda4637

Browse files
Merge pull request #1767 from forcedotcom/release-5.0.0-beta.3
RELEASE @W-17915084@ Conducting v5.0.0-beta.3 release
2 parents b4b2744 + b012139 commit fda4637

32 files changed

+1423
-1074
lines changed

messages/action-summary-viewer.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ Configuration written to:
1818

1919
Found 0 rules.
2020

21+
# rules-action.outfile-location
22+
23+
Rules written to:
24+
2125
# rules-action.rules-total
2226

2327
Found %d rule(s) from %d engine(s):

messages/config-command.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,33 +12,33 @@ We're continually improving Salesforce Code Analyzer. Tell us what you think! Gi
1212

1313
# command.examples
1414

15-
- Display the current state of the Code Analyzer configuration using the default behavior: display top level configuration, display the engine and rule override settings associated with all the rules that have a "Recommended" tag; and automatically apply any existing custom configuration settings found in a `code-analyzer.yml` or `code-analyzer.yaml` file in the current folder:
15+
- Display the current state of the Code Analyzer configuration using the default behavior: display top level configuration, display the engine and rule override settings associated with all the rules; and automatically apply any existing custom configuration settings found in a `code-analyzer.yml` or `code-analyzer.yaml` file in the current folder:
1616

1717
<%= config.bin %> <%= command.id %>
1818

1919
- This example is identical to the previous one, assuming that `./code-analyzer.yml` exists in your current folder.
2020

21-
<%= config.bin %> <%= command.id %> --config-file ./code-analyzer.yml --rule-selector Recommended
21+
<%= config.bin %> <%= command.id %> --config-file ./code-analyzer.yml --rule-selector all
2222

2323
- Write the current state of configuration to the file `code-analyzer.yml`, including any configuration from an existing `code-analyzer.yml` file. The command preserves all values from the original config, but overwrites any comments:
2424

2525
<%= config.bin %> <%= command.id %> --config-file ./code-analyzer.yml --output-file code-analyzer.yml
2626

27-
- Display the configuration state for all rules, instead of just the recommended ones:
27+
- Display the configuration state for just the recommended rules, instead of all the rules:
2828

29-
<%= config.bin %> <%= command.id %> --rule-selector all
29+
<%= config.bin %> <%= command.id %> --rule-selector Recommended
3030

31-
- Display the configuration state associated with recommended rules that are applicable to your workspace folder, `./src`:
31+
- Display the configuration state associated with all the rules that are applicable to your workspace folder, `./src`:
3232

3333
<%= config.bin %> <%= command.id %> --workspace ./src
3434

3535
- Display any relevant configuration settings associated with the rule name 'no-undef' from the 'eslint' engine:
3636

37-
<%= config.bin %> <%= command.id %> --rule-selection eslint:no-undef
37+
<%= config.bin %> <%= command.id %> --rule-selector eslint:no-undef
3838

3939
- Load an existing configuration file called `existing-config.yml`, and then write the configuration to a new file called `new-config.yml`, the configuration state that is applicable to all rules that are relevant to the workspace located in the current folder:
4040

41-
<%= config.bin %> <%= command.id %> --config-file ./existing-config.yml --rule-selection all --workspace . --output-file ./subfolder-config.yml
41+
<%= config.bin %> <%= command.id %> --config-file ./existing-config.yml --workspace . --output-file ./subfolder-config.yml
4242

4343
# flags.workspace.summary
4444

@@ -62,9 +62,9 @@ Use the --rule-selector flag to display only the configuration associated with t
6262

6363
You can combine different criteria using colons to further filter the list; the colon works as an intersection. For example, "--rule-selector eslint:Security" reduces the output to only contain the configuration state associated with the rules from the "eslint" engine that have the "Security" tag. To add multiple rule selectors together (a union), specify the --rule-selector flag multiple times, such as "--rule-selector eslint:Recommended --rule-selector retire-js:3".
6464

65-
If you don't specify this flag, then the command uses the "Recommended" tag rule selector.
65+
If you don't specify this flag, then the command uses the "all" rule selector.
6666

67-
Run `<%= config.bin %> <%= command.id %> --rule-selector all` to display the configuration state associated with all possible rules available, and not just the recommended ones.
67+
Run `<%= config.bin %> <%= command.id %> --rule-selector Recommended` to display the configuration state associated with just the 'Recommended' rules, instead of all the rules.
6868

6969
# flags.config-file.summary
7070

messages/progress-event-listener.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,11 @@ Executing rules
1313
# execution-spinner.progress-summary
1414
%d of %d engines finished after %ds.
1515

16-
# execution-spinner.engine-status
16+
# execution-spinner.engine-progress
1717
- %s at %d% completion.
1818

19+
# execution-spinner.engine-progress-with-message
20+
- %s at %d% completion - %s
21+
1922
# execution-spinner.finished-status
2023
done. Executed rules from %s.

messages/rules-command.md

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@ We're continually improving Salesforce Code Analyzer. Tell us what you think! Gi
3232

3333
<%= config.bin %> <%= command.id %> --rule-selector eslint:all
3434

35-
- List all rules for all engines:
35+
- List the details about all rules for all engines; also write the rules in JSON format to a file called "rules.json" in the "out" folder, which must already exist:
3636

37-
<%= config.bin %> <%= command.id %> --rule-selector all
37+
<%= config.bin %> <%= command.id %> --rule-selector all --output-file ./out/rules.json --view detail
3838

3939
- Get a more accurate list of the rules that apply specifically to your workspace (all the files in the current folder):
4040

@@ -102,4 +102,16 @@ Format to display the rules in the terminal.
102102

103103
# flags.view.description
104104

105-
The format `table` is concise and shows minimal output, the format `detail` shows all available information.
105+
The format `table` is concise and shows minimal output, the format `detail` shows all available information.
106+
107+
If you specify neither --view nor --output-file, then the default table view is shown. If you specify --output-file but not --view, only summary information is shown in the terminal.
108+
109+
# flags.output-file.summary
110+
111+
Name of the file where the selected rules are written. The file format depends on the extension you specify; currently, only .json is supported for JSON-formatted output.
112+
113+
# flags.output-file.description
114+
115+
If you specify a folder, such as "--output-file ./out/rules.json", the folder must already exist or you get an error. If the file already exists, it's overwritten without prompting.
116+
117+
If you don't specify this flag, the command outputs the rules to only the terminal.

messages/rules-writer.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# error.unrecognized-file-format
2+
3+
The output file %s has an unsupported extension. Valid extension(s): .json.

messages/run-command.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,20 +126,23 @@ If you specify neither --view nor --output-file, then the default table view is
126126

127127
# flags.output-file.summary
128128

129-
Output file that contains the analysis results. The file format depends on the extension you specify, such as .csv, .html, .xml, and so on.
129+
Name of the file where the analysis results are written. The file format depends on the extension you specify, such as .csv, .html, .xml, and so on.
130130

131131
# flags.output-file.description
132132

133-
If you don't specify this flag, the command outputs the results in the terminal. Use this flag to print the results to a file; the format of the results depends on the extension you provide. For example, "--output-file results.csv" creates a comma-separated values file. You can specify one of these extensions:
133+
If you don't specify this flag, the command outputs the results to only the terminal. Use this flag to print the results to a file; the format of the results depends on the extension you provide. For example, "--output-file results.csv" creates a comma-separated values file. You can specify one of these extensions:
134134

135135
- .csv
136136
- .html or .htm
137137
- .json
138138
- .sarif or .sarif.json
139139
- .xml
140140

141-
To output the results to multiple files, specify this flag multiple times. For example: "--output-file ./out/results.json --output-file ./out/report.html" creates a JSON results file and an HTML file in the "./out" folder.
141+
To output the results to multiple files, specify this flag multiple times. For example: "--output-file results.json --output-file report.html" creates both a JSON results file and an HTML file.
142+
143+
If you specify a folder, such as "--output-file ./out/results.json", the folder must already exist or you get an error. If the file already exists, it's overwritten without prompting.
142144

143145
# error.invalid-severity-threshold
144146

145147
Expected --severity-threshold=%s to be one of: %s
148+

package.json

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,25 @@
11
{
22
"name": "@salesforce/plugin-code-analyzer",
33
"description": "Static code scanner that applies quality and security rules to Apex code, and provides feedback.",
4-
"version": "5.0.0-beta.2",
4+
"version": "5.0.0-beta.3",
55
"author": "Salesforce Code Analyzer Team",
66
"bugs": "https://github.com/forcedotcom/sfdx-scanner/issues",
77
"dependencies": {
88
"@oclif/core": "3.27.0",
9-
"@salesforce/code-analyzer-core": "0.23.0",
10-
"@salesforce/code-analyzer-engine-api": "0.18.0",
11-
"@salesforce/code-analyzer-eslint-engine": "0.20.0",
12-
"@salesforce/code-analyzer-flowtest-engine": "0.18.0",
13-
"@salesforce/code-analyzer-pmd-engine": "0.20.0",
14-
"@salesforce/code-analyzer-regex-engine": "0.18.0",
15-
"@salesforce/code-analyzer-retirejs-engine": "0.18.0",
9+
"@salesforce/code-analyzer-core": "0.25.1",
10+
"@salesforce/code-analyzer-engine-api": "0.20.0",
11+
"@salesforce/code-analyzer-eslint-engine": "0.20.1",
12+
"@salesforce/code-analyzer-flowtest-engine": "0.18.1",
13+
"@salesforce/code-analyzer-pmd-engine": "0.21.0",
14+
"@salesforce/code-analyzer-regex-engine": "0.18.1",
15+
"@salesforce/code-analyzer-retirejs-engine": "0.18.1",
16+
"@salesforce/code-analyzer-sfge-engine": "0.1.0",
1617
"@salesforce/core": "6.7.6",
1718
"@salesforce/sf-plugins-core": "5.0.13",
1819
"@salesforce/ts-types": "^2.0.12",
1920
"@types/js-yaml": "^4.0.9",
2021
"@types/node": "^22.12.0",
21-
"ansis": "^3.10.0",
22+
"ansis": "^3.17.0",
2223
"fast-glob": "^3.3.3",
2324
"js-yaml": "^4.1.0",
2425
"ts-node": "^10",

src/commands/code-analyzer/config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export default class ConfigCommand extends SfCommand<void> implements Displayabl
3434
char: 'r',
3535
multiple: true,
3636
delimiter: ',',
37-
default: ["Recommended"]
37+
default: ["all"]
3838
}),
3939
'config-file': Flags.file({
4040
summary: getMessage(BundleName.ConfigCommand, 'flags.config-file.summary'),

src/commands/code-analyzer/rules.ts

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@ import {Flags, SfCommand} from '@salesforce/sf-plugins-core';
22
import {View} from '../../Constants';
33
import {CodeAnalyzerConfigFactoryImpl} from '../../lib/factories/CodeAnalyzerConfigFactory';
44
import {EnginePluginsFactoryImpl} from '../../lib/factories/EnginePluginsFactory';
5-
import {RuleDetailDisplayer, RuleTableDisplayer} from '../../lib/viewers/RuleViewer';
5+
import {RuleDetailDisplayer, RulesNoOpDisplayer, RuleTableDisplayer} from '../../lib/viewers/RuleViewer';
66
import {RulesActionSummaryViewer} from '../../lib/viewers/ActionSummaryViewer';
7-
import {RulesAction, RulesDependencies} from '../../lib/actions/RulesAction';
7+
import {RulesAction, RulesDependencies, RulesInput} from '../../lib/actions/RulesAction';
88
import {BundleName, getMessage, getMessages} from '../../lib/messages';
99
import {Displayable, UxDisplay} from '../../lib/Display';
1010
import {LogEventDisplayer} from '../../lib/listeners/LogEventListener';
1111
import {RuleSelectionProgressSpinner} from '../../lib/listeners/ProgressEventListener';
12+
import {CompositeRulesWriter} from '../../lib/writers/RulesWriter';
1213

1314
export default class RulesCommand extends SfCommand<void> implements Displayable {
1415
// We don't need the `--json` output for this command.
@@ -42,11 +43,15 @@ export default class RulesCommand extends SfCommand<void> implements Displayable
4243
char: 'c',
4344
exists: true
4445
}),
46+
'output-file': Flags.file({
47+
summary: getMessage(BundleName.RulesCommand, 'flags.output-file.summary'),
48+
description: getMessage(BundleName.RulesCommand, 'flags.output-file.description'),
49+
char: 'f'
50+
}),
4551
view: Flags.string({
4652
summary: getMessage(BundleName.RulesCommand, 'flags.view.summary'),
4753
description: getMessage(BundleName.RulesCommand, 'flags.view.description'),
4854
char: 'v',
49-
default: View.TABLE,
5055
options: Object.values(View)
5156
})
5257
};
@@ -56,21 +61,53 @@ export default class RulesCommand extends SfCommand<void> implements Displayable
5661
this.warn(getMessage(BundleName.Shared, "warning.command-state", [getMessage(BundleName.Shared, 'label.command-state')]));
5762

5863
const parsedFlags = (await this.parse(RulesCommand)).flags;
59-
const dependencies: RulesDependencies = this.createDependencies(parsedFlags.view as View);
64+
const outputFiles = parsedFlags['output-file'] ? [parsedFlags['output-file']] : [];
65+
const view = parsedFlags.view as View | undefined;
66+
67+
const dependencies: RulesDependencies = this.createDependencies(view, outputFiles);
6068
const action: RulesAction = RulesAction.createAction(dependencies);
61-
await action.execute(parsedFlags);
69+
70+
const rulesInput: RulesInput = {
71+
'config-file': parsedFlags['config-file'],
72+
'output-file': outputFiles,
73+
'rule-selector': parsedFlags['rule-selector'],
74+
'workspace': parsedFlags['workspace'],
75+
};
76+
77+
await action.execute(rulesInput);
6278
}
6379

64-
protected createDependencies(view: View): RulesDependencies {
80+
protected createDependencies(view: View | undefined, outputFiles: string[]): RulesDependencies {
6581
const uxDisplay: UxDisplay = new UxDisplay(this, this.spinner);
66-
return {
82+
const dependencies: RulesDependencies = {
6783
configFactory: new CodeAnalyzerConfigFactoryImpl(),
6884
pluginsFactory: new EnginePluginsFactoryImpl(),
6985
logEventListeners: [new LogEventDisplayer(uxDisplay)],
7086
progressListeners: [new RuleSelectionProgressSpinner(uxDisplay)],
7187
actionSummaryViewer: new RulesActionSummaryViewer(uxDisplay),
72-
viewer: view === View.TABLE ? new RuleTableDisplayer(uxDisplay) : new RuleDetailDisplayer(uxDisplay)
88+
viewer: this.createRulesViewer(view, outputFiles, uxDisplay),
89+
writer: CompositeRulesWriter.fromFiles(outputFiles)
7390
};
91+
92+
return dependencies;
93+
}
94+
95+
/**
96+
* Creates the {@link RuleViewer} that will be called from {@link RulesAction.execute} to display rules.
97+
* If a view option is set, rules will be displayed in the specified format.
98+
* If an output file is set, rules will not display.
99+
* By default, the details display will be used.
100+
*/
101+
private createRulesViewer(view: View | undefined, outputFiles: string[] = [], uxDisplay: UxDisplay) {
102+
if (view === View.DETAIL) {
103+
return new RuleDetailDisplayer(uxDisplay);
104+
} else if (view === View.TABLE) {
105+
return new RuleTableDisplayer(uxDisplay);
106+
} else if (outputFiles.length > 0) {
107+
return new RulesNoOpDisplayer();
108+
}
109+
110+
return new RuleTableDisplayer(uxDisplay);
74111
}
75112
}
76113

0 commit comments

Comments
 (0)