Skip to content

Commit 379511a

Browse files
authored
Merge pull request #1649 from forcedotcom/d/W-16891765-b
NEW @W-16891765@ Config action mentions outfile
2 parents 1b6b60d + b03d267 commit 379511a

File tree

16 files changed

+198
-15
lines changed

16 files changed

+198
-15
lines changed

messages/action-summary-viewer.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# common.summary-header
2+
3+
Summary
4+
5+
# common.logfile-location
6+
7+
Additional log information written to:
8+
9+
# config-action.no-outfiles
10+
11+
No output file was specified.
12+
13+
# config-action.outfile-location
14+
15+
Configuration written to:

messages/config-model.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,6 @@ Empty object used because rule selection returned no rules
1212

1313
# template.yaml.no-rules-selected
1414
Remove this empty object {} when you are ready to specify your first rule override
15+
16+
# template.common.end-of-config
17+
END OF CODE ANALYZER CONFIGURATION

src/commands/code-analyzer/config.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {Flags, SfCommand} from '@salesforce/sf-plugins-core';
22
import {ConfigAction, ConfigDependencies} from '../../lib/actions/ConfigAction';
33
import {ConfigFileWriter} from '../../lib/writers/ConfigWriter';
44
import {ConfigStyledYamlViewer} from '../../lib/viewers/ConfigViewer';
5+
import {ConfigActionSummaryViewer} from '../../lib/viewers/ActionSummaryViewer';
56
import {CodeAnalyzerConfigFactoryImpl} from '../../lib/factories/CodeAnalyzerConfigFactory';
67
import {EnginePluginsFactoryImpl} from '../../lib/factories/EnginePluginsFactory';
78
import {BundleName, getMessage, getMessages} from '../../lib/messages';
@@ -70,6 +71,7 @@ export default class ConfigCommand extends SfCommand<void> implements Displayabl
7071
logEventListeners: [new LogEventDisplayer(uxDisplay)],
7172
progressEventListeners: [new RuleSelectionProgressSpinner(uxDisplay)],
7273
modelGenerator: modelGeneratorFunction,
74+
actionSummaryViewer: new ConfigActionSummaryViewer(uxDisplay),
7375
viewer: new ConfigStyledYamlViewer(uxDisplay)
7476
};
7577
if (outputFile) {

src/lib/actions/ConfigAction.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {ConfigViewer} from '../viewers/ConfigViewer';
77
import {createWorkspace} from '../utils/WorkspaceUtil';
88
import {LogEventListener, LogEventLogger} from '../listeners/LogEventListener';
99
import {ProgressEventListener} from '../listeners/ProgressEventListener';
10+
import {ConfigActionSummaryViewer} from '../viewers/ActionSummaryViewer';
1011
import {ConfigModel, ConfigModelGeneratorFunction, ConfigContext} from '../models/ConfigModel';
1112

1213
export type ConfigDependencies = {
@@ -16,11 +17,13 @@ export type ConfigDependencies = {
1617
logEventListeners: LogEventListener[];
1718
progressEventListeners: ProgressEventListener[];
1819
writer?: ConfigWriter;
20+
actionSummaryViewer: ConfigActionSummaryViewer;
1921
viewer: ConfigViewer;
2022
};
2123

2224
export type ConfigInput = {
2325
'config-file'?: string;
26+
'output-file'?: string;
2427
'rule-selector': string[];
2528
workspace?: string[];
2629
};
@@ -38,7 +41,8 @@ export class ConfigAction {
3841
const defaultConfig: CodeAnalyzerConfig = CodeAnalyzerConfig.withDefaults();
3942

4043
// We always add a Logger Listener to the appropriate listeners list, because we should always be logging.
41-
const logEventLogger: LogEventLogger = new LogEventLogger(await LogFileWriter.fromConfig(userConfig));
44+
const logFileWriter: LogFileWriter = await LogFileWriter.fromConfig(userConfig);
45+
const logEventLogger: LogEventLogger = new LogEventLogger(logFileWriter);
4246
this.dependencies.logEventListeners.push(logEventLogger);
4347

4448
// The User's config produces one Core.
@@ -118,7 +122,10 @@ export class ConfigAction {
118122
const configModel: ConfigModel = this.dependencies.modelGenerator(relevantEngines, userConfigContext, defaultConfigContext);
119123

120124
this.dependencies.viewer.view(configModel);
121-
await this.dependencies.writer?.write(configModel);
125+
const fileWritten: boolean = this.dependencies.writer
126+
? await this.dependencies.writer.write(configModel)
127+
: false;
128+
this.dependencies.actionSummaryViewer.view(logFileWriter.getLogDestination(), fileWritten ? input['output-file'] : undefined);
122129
return Promise.resolve();
123130
}
124131

src/lib/messages.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {Tokens} from '@salesforce/core/lib/messages';
55
Messages.importMessagesDirectory(__dirname);
66

77
export enum BundleName {
8+
ActionSummaryViewer = 'action-summary-viewer',
89
ConfigCommand = 'config-command',
910
ConfigModel = 'config-model',
1011
ConfigWriter = 'config-writer',

src/lib/models/ConfigModel.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,9 @@ abstract class YamlFormatter {
114114
this.toYamlRuleOverrides() + '\n' +
115115
'\n' +
116116
this.toYamlComment(topLevelDescription.fieldDescriptions!.engines) + '\n' +
117-
this.toYamlEngineOverrides() + '\n';
117+
this.toYamlEngineOverrides() + '\n' +
118+
'\n' +
119+
this.toYamlSectionHeadingComment(getMessage(BundleName.ConfigModel, 'template.common.end-of-config')) + '\n';
118120
}
119121

120122
private toYamlRuleOverrides(): string {
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import {Display} from '../Display';
2+
import {toStyledHeader, indent} from '../utils/StylingUtil';
3+
import {BundleName, getMessage} from '../messages';
4+
5+
abstract class AbstractActionSummaryViewer {
6+
protected readonly display: Display;
7+
8+
protected constructor(display: Display) {
9+
this.display = display;
10+
}
11+
12+
protected displaySummaryHeader(): void {
13+
this.display.displayLog(toStyledHeader(getMessage(BundleName.ActionSummaryViewer, 'common.summary-header')));
14+
}
15+
16+
protected displayLineSeparator(): void {
17+
this.display.displayLog("");
18+
}
19+
20+
protected displayLogFileInfo(logFile: string): void {
21+
this.display.displayLog(getMessage(BundleName.ActionSummaryViewer, 'common.logfile-location'));
22+
this.display.displayLog(indent(logFile));
23+
}
24+
}
25+
26+
export class ConfigActionSummaryViewer extends AbstractActionSummaryViewer {
27+
public constructor(display: Display) {
28+
super(display);
29+
}
30+
31+
public view(logFile: string, outfile?: string): void {
32+
this.displaySummaryHeader();
33+
this.displayLineSeparator();
34+
35+
if (outfile) {
36+
this.displayOutfile(outfile);
37+
} else {
38+
this.display.displayLog(getMessage(BundleName.ActionSummaryViewer, 'config-action.no-outfiles'));
39+
}
40+
this.displayLineSeparator();
41+
42+
this.displayLogFileInfo(logFile);
43+
}
44+
45+
private displayOutfile(outfile: string): void {
46+
this.display.displayLog(getMessage(BundleName.ActionSummaryViewer, 'config-action.outfile-location'));
47+
this.display.displayLog(indent(outfile));
48+
}
49+
}

src/lib/writers/ConfigWriter.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {Display} from '../Display';
66
import {exists} from '../utils/FileUtil';
77

88
export interface ConfigWriter {
9-
write(model: ConfigModel): Promise<void>;
9+
write(model: ConfigModel): Promise<boolean>;
1010
}
1111

1212
export class ConfigFileWriter implements ConfigWriter {
@@ -20,10 +20,13 @@ export class ConfigFileWriter implements ConfigWriter {
2020
this.display = display;
2121
}
2222

23-
public async write(model: ConfigModel): Promise<void> {
23+
public async write(model: ConfigModel): Promise<boolean> {
2424
// Only write to the file if it doesn't already exist, or if the user confirms that they want to overwrite it.
2525
if (!(await exists(this.file)) || await this.display.confirm(getMessage(BundleName.ConfigWriter, 'prompt.overwrite-existing-file', [this.file]))) {
2626
fs.writeFileSync(this.file, model.toFormattedOutput(this.format));
27+
return true;
28+
} else {
29+
return false;
2730
}
2831
}
2932

test/commands/code-analyzer/config.test.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ describe('`code-analyzer config` tests', () => {
177177
expect(createActionSpy).toHaveBeenCalled();
178178
expect(fromFileSpy).toHaveBeenCalled();
179179
expect(receivedFile).toEqual(inputValue);
180+
expect(receivedActionInput).toHaveProperty('output-file', inputValue);
180181
});
181182

182183
it('Can be referenced by its shortname, -f', async () => {
@@ -186,6 +187,7 @@ describe('`code-analyzer config` tests', () => {
186187
expect(createActionSpy).toHaveBeenCalled();
187188
expect(fromFileSpy).toHaveBeenCalled();
188189
expect(receivedFile).toEqual(inputValue);
190+
expect(receivedActionInput).toHaveProperty('output-file', inputValue);
189191
});
190192

191193
it('Cannot be supplied multiple times', async () => {
@@ -201,6 +203,7 @@ describe('`code-analyzer config` tests', () => {
201203
expect(executeSpy).toHaveBeenCalled();
202204
expect(createActionSpy).toHaveBeenCalled();
203205
expect(fromFileSpy).not.toHaveBeenCalled();
206+
expect(receivedActionInput['output-file']).toBeUndefined();
204207
});
205208

206209
});
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
=== Summary
2+
3+
No output file was specified.
4+
5+
Additional log information written to:

0 commit comments

Comments
 (0)