103 lines
3.0 KiB
TypeScript
103 lines
3.0 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright Google LLC All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by an MIT-style license that can be
|
|
* found in the LICENSE file at https://angular.io/license
|
|
*/
|
|
|
|
import {GitClient} from '../../utils/git/git-client';
|
|
import {FormatConfig} from '../config';
|
|
|
|
// A callback to determine if the formatter run found a failure in formatting.
|
|
export type CallbackFunc =
|
|
(file: string, code: number|NodeJS.Signals, stdout: string, stderr: string) => boolean;
|
|
|
|
// The actions a formatter can take.
|
|
export type FormatterAction = 'check'|'format';
|
|
|
|
// The metadata needed for running one of the `FormatterAction`s on a file.
|
|
interface FormatterActionMetadata {
|
|
commandFlags: string;
|
|
callback: CallbackFunc;
|
|
}
|
|
|
|
/**
|
|
* The base class for formatters to run against provided files.
|
|
*/
|
|
export abstract class Formatter {
|
|
protected git = GitClient.get();
|
|
/**
|
|
* The name of the formatter, this is used for identification in logging and for enabling and
|
|
* configuring the formatter in the config.
|
|
*/
|
|
abstract name: string;
|
|
|
|
/** The full path file location of the formatter binary. */
|
|
abstract binaryFilePath: string;
|
|
|
|
/** Metadata for each `FormatterAction` available to the formatter. */
|
|
abstract actions: {
|
|
// An action performing a check of format without making any changes.
|
|
check: FormatterActionMetadata;
|
|
// An action to format files in place.
|
|
format: FormatterActionMetadata;
|
|
};
|
|
|
|
/** The default matchers for the formatter for filtering files to be formatted. */
|
|
abstract defaultFileMatcher: string[];
|
|
|
|
constructor(protected config: FormatConfig) {}
|
|
|
|
/**
|
|
* Retrieve the command to execute the provided action, including both the binary
|
|
* and command line flags.
|
|
*/
|
|
commandFor(action: FormatterAction) {
|
|
switch (action) {
|
|
case 'check':
|
|
return `${this.binaryFilePath} ${this.actions.check.commandFlags}`;
|
|
case 'format':
|
|
return `${this.binaryFilePath} ${this.actions.format.commandFlags}`;
|
|
default:
|
|
throw Error('Unknown action type');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Retrieve the callback for the provided action to determine if an action
|
|
* failed in formatting.
|
|
*/
|
|
callbackFor(action: FormatterAction) {
|
|
switch (action) {
|
|
case 'check':
|
|
return this.actions.check.callback;
|
|
case 'format':
|
|
return this.actions.format.callback;
|
|
default:
|
|
throw Error('Unknown action type');
|
|
}
|
|
}
|
|
|
|
/** Whether the formatter is enabled in the provided config. */
|
|
isEnabled() {
|
|
return !!this.config[this.name];
|
|
}
|
|
|
|
/** Retrieve the active file matcher for the formatter. */
|
|
getFileMatcher() {
|
|
return this.getFileMatcherFromConfig() || this.defaultFileMatcher;
|
|
}
|
|
|
|
/**
|
|
* Retrieves the file matcher from the config provided to the constructor if provided.
|
|
*/
|
|
private getFileMatcherFromConfig(): string[]|undefined {
|
|
const formatterConfig = this.config[this.name];
|
|
if (typeof formatterConfig === 'boolean') {
|
|
return undefined;
|
|
}
|
|
return formatterConfig.matchers;
|
|
}
|
|
}
|