diff --git a/dev-infra/format/formatters/base-formatter.ts b/dev-infra/format/formatters/base-formatter.ts index b22eb8c968..7b6381a54b 100644 --- a/dev-infra/format/formatters/base-formatter.ts +++ b/dev-infra/format/formatters/base-formatter.ts @@ -46,7 +46,7 @@ export abstract class Formatter { /** The default matchers for the formatter for filtering files to be formatted. */ abstract defaultFileMatcher: string[]; - constructor(private config: FormatConfig) {} + constructor(protected config: FormatConfig) {} /** * Retrieve the command to execute the provided action, including both the binary diff --git a/dev-infra/format/formatters/index.ts b/dev-infra/format/formatters/index.ts index 23281974b3..3279c3c279 100644 --- a/dev-infra/format/formatters/index.ts +++ b/dev-infra/format/formatters/index.ts @@ -10,14 +10,18 @@ import {getFormatConfig} from '../config'; import {Buildifier} from './buildifier'; import {ClangFormat} from './clang-format'; +import {Prettier} from './prettier'; /** * Get all defined formatters which are active based on the current loaded config. */ export function getActiveFormatters() { const config = getFormatConfig().format; - return [new Buildifier(config), new ClangFormat(config)].filter( - formatter => formatter.isEnabled()); + return [ + new Prettier(config), + new Buildifier(config), + new ClangFormat(config), + ].filter((formatter) => formatter.isEnabled()); } // Rexport symbols used for types elsewhere. diff --git a/dev-infra/format/formatters/prettier.ts b/dev-infra/format/formatters/prettier.ts new file mode 100644 index 0000000000..b7ab1b53f8 --- /dev/null +++ b/dev-infra/format/formatters/prettier.ts @@ -0,0 +1,55 @@ +/** + * @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 {join} from 'path'; +import {exec} from 'shelljs'; + +import {error} from '../../utils/console'; + +import {Formatter} from './base-formatter'; + +/** + * Formatter for running prettier against Typescript and Javascript files. + */ +export class Prettier extends Formatter { + name = 'prettier'; + + binaryFilePath = join(this.git.baseDir, 'node_modules/.bin/prettier'); + + defaultFileMatcher = ['**/*.{t,j}s']; + + /** + * The configuration path of the pretter config, obtained during construction to prevent needing + * to discover it repeatedly for each execution. + */ + private configPath = + this.config['pretter'] ? exec(`${this.binaryFilePath} --find-config-path .`).trim() : ''; + + actions = { + check: { + commandFlags: `--config ${this.configPath} --check`, + callback: + (_: string, code: number, stdout: string) => { + return code !== 0; + }, + }, + format: { + commandFlags: `--config ${this.configPath} --write`, + callback: + (file: string, code: number, _: string, stderr: string) => { + if (code !== 0) { + error(`Error running prettier on: ${file}`); + error(stderr); + error(); + return true; + } + return false; + }, + }, + }; +} diff --git a/dev-infra/ng-dev.js b/dev-infra/ng-dev.js index 16f5dd1ba7..b0976b3f80 100755 --- a/dev-infra/ng-dev.js +++ b/dev-infra/ng-dev.js @@ -2463,6 +2463,50 @@ class ClangFormat extends Formatter { } } +/** + * @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 + */ +/** + * Formatter for running prettier against Typescript and Javascript files. + */ +class Prettier extends Formatter { + constructor() { + super(...arguments); + this.name = 'prettier'; + this.binaryFilePath = path.join(this.git.baseDir, 'node_modules/.bin/prettier'); + this.defaultFileMatcher = ['**/*.{t,j}s']; + /** + * The configuration path of the pretter config, obtained during construction to prevent needing + * to discover it repeatedly for each execution. + */ + this.configPath = this.config['pretter'] ? shelljs.exec(`${this.binaryFilePath} --find-config-path .`).trim() : ''; + this.actions = { + check: { + commandFlags: `--config ${this.configPath} --check`, + callback: (_, code, stdout) => { + return code !== 0; + }, + }, + format: { + commandFlags: `--config ${this.configPath} --write`, + callback: (file, code, _, stderr) => { + if (code !== 0) { + error(`Error running prettier on: ${file}`); + error(stderr); + error(); + return true; + } + return false; + }, + }, + }; + } +} + /** * @license * Copyright Google LLC All Rights Reserved. @@ -2475,7 +2519,11 @@ class ClangFormat extends Formatter { */ function getActiveFormatters() { const config = getFormatConfig().format; - return [new Buildifier(config), new ClangFormat(config)].filter(formatter => formatter.isEnabled()); + return [ + new Prettier(config), + new Buildifier(config), + new ClangFormat(config), + ].filter((formatter) => formatter.isEnabled()); } /** diff --git a/dev-infra/tmpl-package.json b/dev-infra/tmpl-package.json index 77ee606719..bef95947e0 100644 --- a/dev-infra/tmpl-package.json +++ b/dev-infra/tmpl-package.json @@ -46,6 +46,9 @@ "clang-format": { "optional": true }, + "prettier": { + "optional": true + }, "protractor": { "optional": true },