Bladeren bron

First version of prettier checks in toolkit (#17964)

Dominik Prokop 6 jaren geleden
bovenliggende
commit
8219fdf7c0

+ 9 - 1
packages/grafana-toolkit/README.md

@@ -123,7 +123,15 @@ Using themes: TODO, for now please refer to [internal guide](../../style_guides/
 
 > NOTE: We do not support Emotion's `css` prop. Use className instead!
 
-## Prettier [todo]
+## Prettier
+When `plugin:build` task is performed we run Prettier check. In order for your IDE to pickup our Prettier config we suggest creating `.prettierrc.js` file in the root directory of your plugin with following contents:
+
+```js
+module.exports = {
+  ...require("./node_modules/@grafana/toolkit/src/config/prettier.plugin.config.json"),
+};
+```
+
 
 ## Development mode [todo]
 `grafana-toolkit plugin:dev [--watch]`

+ 3 - 3
packages/grafana-toolkit/package.json

@@ -26,7 +26,6 @@
     "@types/jest": "24.0.13",
     "@types/jest-cli": "^23.6.0",
     "@types/node": "^12.0.4",
-    "@types/prettier": "^1.16.4",
     "@types/react-dev-utils": "^9.0.1",
     "@types/semver": "^6.0.0",
     "@types/webpack": "4.4.34",
@@ -53,7 +52,7 @@
     "postcss-flexbugs-fixes": "4.1.0",
     "postcss-loader": "3.0.0",
     "postcss-preset-env": "6.6.0",
-    "prettier": "^1.17.1",
+    "prettier": "^1.18.2",
     "react-dev-utils": "^9.0.1",
     "replace-in-file": "^4.1.0",
     "replace-in-file-webpack-plugin": "^1.0.6",
@@ -76,6 +75,7 @@
     "@types/lodash": "4.14.119"
   },
   "devDependencies": {
-    "@types/glob": "^7.1.1"
+    "@types/glob": "^7.1.1",
+    "@types/prettier": "^1.16.4"
   }
 }

+ 55 - 4
packages/grafana-toolkit/src/cli/tasks/plugin.build.ts

@@ -4,15 +4,19 @@ import execa = require('execa');
 import path = require('path');
 import fs = require('fs');
 import glob = require('glob');
+import util = require('util');
+import { Linter, Configuration, RuleFailure } from 'tslint';
+import * as prettier from 'prettier';
 
 import { useSpinner } from '../utils/useSpinner';
-import { Linter, Configuration, RuleFailure } from 'tslint';
 import { testPlugin } from './plugin/tests';
 import { bundlePlugin as bundleFn, PluginBundleOptions } from './plugin/bundle';
+
 interface PrecommitOptions {}
 
 export const bundlePlugin = useSpinner<PluginBundleOptions>('Compiling...', async options => await bundleFn(options));
 
+const readFileAsync = util.promisify(fs.readFile);
 // @ts-ignore
 export const clean = useSpinner<void>('Cleaning', async () => await execa('rimraf', [`${process.cwd()}/dist`]));
 
@@ -36,20 +40,67 @@ const typecheckPlugin = useSpinner<void>('Typechecking', async () => {
   await execa('tsc', ['--noEmit']);
 });
 
+const getTypescriptSources = () => {
+  const globPattern = path.resolve(process.cwd(), 'src/**/*.+(ts|tsx)');
+  return glob.sync(globPattern);
+};
+
+const getStylesSources = () => {
+  const globPattern = path.resolve(process.cwd(), 'src/**/*.+(scss|css)');
+  return glob.sync(globPattern);
+};
+
+const prettierCheckPlugin = useSpinner<void>('Prettier check', async () => {
+  const prettierConfig = require(path.resolve(__dirname, '../../config/prettier.plugin.config.json'));
+  const sources = [...getStylesSources(), ...getTypescriptSources()];
+
+  const promises = sources.map((s, i) => {
+    return new Promise<{ path: string; failed: boolean }>((resolve, reject) => {
+      fs.readFile(s, (err, data) => {
+        let failed = false;
+        if (err) {
+          throw new Error(err.message);
+        }
+
+        if (
+          !prettier.check(data.toString(), {
+            ...prettierConfig,
+            filepath: s,
+          })
+        ) {
+          failed = true;
+        }
+
+        resolve({
+          path: s,
+          failed,
+        });
+      });
+    });
+  });
+
+  const results = await Promise.all(promises);
+  const failures = results.filter(r => r.failed);
+  if (failures.length) {
+    console.log('\nFix Prettier issues in following files:');
+    failures.forEach(f => console.log(f.path));
+    throw new Error('Prettier failed');
+  }
+});
+
 // @ts-ignore
 const lintPlugin = useSpinner<void>('Linting', async () => {
   let tsLintConfigPath = path.resolve(process.cwd(), 'tslint.json');
   if (!fs.existsSync(tsLintConfigPath)) {
     tsLintConfigPath = path.resolve(__dirname, '../../config/tslint.plugin.json');
   }
-  const globPattern = path.resolve(process.cwd(), 'src/**/*.+(ts|tsx)');
-  const sourcesToLint = glob.sync(globPattern);
   const options = {
     fix: true, // or fail
     formatter: 'json',
   };
 
   const configuration = Configuration.findConfiguration(tsLintConfigPath).results;
+  const sourcesToLint = getTypescriptSources();
 
   const lintResults = sourcesToLint
     .map(fileName => {
@@ -81,9 +132,9 @@ const lintPlugin = useSpinner<void>('Linting', async () => {
 });
 
 const pluginBuildRunner: TaskRunner<PrecommitOptions> = async () => {
-  // console.log('asasas')
   await clean();
   await prepare();
+  await prettierCheckPlugin();
   // @ts-ignore
   await lintPlugin();
   await testPlugin({ updateSnapshot: false, coverage: false });

+ 5 - 0
packages/grafana-toolkit/src/config/prettier.plugin.config.json

@@ -0,0 +1,5 @@
+{
+  "trailingComma": "es5",
+  "singleQuote": true,
+  "printWidth": 150
+}

+ 1 - 0
packages/grafana-toolkit/src/config/tslint.plugin.json

@@ -1,4 +1,5 @@
 {
+  "extends": ["tslint-config-prettier"],
   "rules": {
     "array-type": [true, "array-simple"],
     "arrow-return-shorthand": true,

+ 1 - 1
yarn.lock

@@ -12726,7 +12726,7 @@ prettier@1.16.4:
   version "1.16.4"
   resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.16.4.tgz#73e37e73e018ad2db9c76742e2647e21790c9717"
 
-prettier@^1.17.1:
+prettier@^1.18.2:
   version "1.18.2"
   resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.18.2.tgz#6823e7c5900017b4bd3acf46fe9ac4b4d7bda9ea"
   integrity sha512-OeHeMc0JhFE9idD4ZdtNibzY0+TPHSpSSb9h8FqtP+YnoZZ1sl8Vc9b1sasjfymH3SonAF4QcA2+mzHPhMvIiw==