Commit d745a66a by Steven Vachon Committed by GitHub

@grafana/toolkit: cleanup (#27906)

* Simplify `useSpinner` to run immediately, instead of returning a function

* Removed unnecessary exports

* Avoid mutating input arguments
parent f60f1c3f
// @ts-ignore // @ts-ignore
import * as _ from 'lodash'; import * as _ from 'lodash';
import { Task, TaskRunner } from './task'; import { Task } from './task';
import GithubClient from '../utils/githubClient'; import GithubClient from '../utils/githubClient';
import difference from 'lodash/difference'; import difference from 'lodash/difference';
import chalk from 'chalk'; import chalk from 'chalk';
...@@ -46,9 +46,8 @@ const getPackageChangelog = (packageName: string, issues: any[]) => { ...@@ -46,9 +46,8 @@ const getPackageChangelog = (packageName: string, issues: any[]) => {
return markdown; return markdown;
}; };
const changelogTaskRunner: TaskRunner<ChangelogOptions> = useSpinner<ChangelogOptions>( const changelogTaskRunner = ({ milestone }: ChangelogOptions) =>
'Generating changelog', useSpinner('Generating changelog', async () => {
async ({ milestone }) => {
const githubClient = new GithubClient(); const githubClient = new GithubClient();
const client = githubClient.client; const client = githubClient.client;
...@@ -106,8 +105,7 @@ const changelogTaskRunner: TaskRunner<ChangelogOptions> = useSpinner<ChangelogOp ...@@ -106,8 +105,7 @@ const changelogTaskRunner: TaskRunner<ChangelogOptions> = useSpinner<ChangelogOp
markdown += getPackageChangelog('grafana-ui', grafanaUiIssues); markdown += getPackageChangelog('grafana-ui', grafanaUiIssues);
console.log(markdown); console.log(markdown);
} });
);
function getMarkdownLineForIssue(item: any) { function getMarkdownLineForIssue(item: any) {
const githubGrafanaUrl = 'https://github.com/grafana/grafana'; const githubGrafanaUrl = 'https://github.com/grafana/grafana';
......
...@@ -5,28 +5,29 @@ import * as path from 'path'; ...@@ -5,28 +5,29 @@ import * as path from 'path';
import chalk from 'chalk'; import chalk from 'chalk';
import { useSpinner } from '../utils/useSpinner'; import { useSpinner } from '../utils/useSpinner';
import { Task, TaskRunner } from './task'; import { Task, TaskRunner } from './task';
import { cloneDeep } from 'lodash';
import globby from 'globby'; import globby from 'globby';
import series from 'p-series'; import series from 'p-series';
let distDir: string, cwd: string; let distDir: string, cwd: string;
export const clean = useSpinner('Cleaning', () => execa('npm', ['run', 'clean'])); const clean = () => useSpinner('Cleaning', () => execa('npm', ['run', 'clean']));
const compile = useSpinner('Compiling sources', () => execa('tsc', ['-p', './tsconfig.build.json'])); const compile = () => useSpinner('Compiling sources', () => execa('tsc', ['-p', './tsconfig.build.json']));
const rollup = useSpinner('Bundling', () => execa('npm', ['run', 'bundle'])); const bundle = () => useSpinner('Bundling', () => execa('npm', ['run', 'bundle']));
interface SavePackageOptions { interface SavePackageOptions {
path: string; path: string;
pkg: {}; pkg: {};
} }
export const savePackage = useSpinner<SavePackageOptions>( const savePackage = ({ path, pkg }: SavePackageOptions) =>
'Updating package.json', useSpinner('Updating package.json', () => fs.writeFile(path, JSON.stringify(pkg, null, 2)));
({ path, pkg }: SavePackageOptions) => fs.writeFile(path, JSON.stringify(pkg, null, 2))
);
const preparePackage = async (pkg: any) => { const preparePackage = async (pkg: any) => {
pkg = cloneDeep(pkg); // avoid mutations
pkg.main = 'index.js'; pkg.main = 'index.js';
pkg.types = 'index.d.ts'; pkg.types = 'index.d.ts';
...@@ -58,7 +59,7 @@ const moveFiles = () => { ...@@ -58,7 +59,7 @@ const moveFiles = () => {
return useSpinner(`Moving ${files.join(', ')} files`, () => { return useSpinner(`Moving ${files.join(', ')} files`, () => {
const promises = files.map(file => fs.copyFile(`${cwd}/${file}`, `${distDir}/${file}`)); const promises = files.map(file => fs.copyFile(`${cwd}/${file}`, `${distDir}/${file}`));
return Promise.all(promises); return Promise.all(promises);
})(); });
}; };
const moveStaticFiles = async (pkg: any) => { const moveStaticFiles = async (pkg: any) => {
...@@ -67,7 +68,7 @@ const moveStaticFiles = async (pkg: any) => { ...@@ -67,7 +68,7 @@ const moveStaticFiles = async (pkg: any) => {
const staticFiles = await globby('src/**/*.{png,svg,gif,jpg}'); const staticFiles = await globby('src/**/*.{png,svg,gif,jpg}');
const promises = staticFiles.map(file => fs.copyFile(file, file.replace(/^src/, 'compiled'))); const promises = staticFiles.map(file => fs.copyFile(file, file.replace(/^src/, 'compiled')));
await Promise.all(promises); await Promise.all(promises);
})(); });
} }
}; };
...@@ -93,7 +94,7 @@ const buildTaskRunner: TaskRunner<PackageBuildOptions> = async ({ scope }) => { ...@@ -93,7 +94,7 @@ const buildTaskRunner: TaskRunner<PackageBuildOptions> = async ({ scope }) => {
await clean(); await clean();
await compile(); await compile();
await moveStaticFiles(pkg); await moveStaticFiles(pkg);
await rollup(); await bundle();
await preparePackage(pkg); await preparePackage(pkg);
await moveFiles(); await moveFiles();
}; };
......
...@@ -22,9 +22,10 @@ interface Fixable { ...@@ -22,9 +22,10 @@ interface Fixable {
fix?: boolean; fix?: boolean;
} }
export const bundlePlugin = useSpinner<PluginBundleOptions>('Compiling...', async options => await bundleFn(options)); const bundlePlugin = (options: PluginBundleOptions) => useSpinner('Compiling...', () => bundleFn(options));
export const clean = useSpinner('Cleaning', async () => await rimraf(`${process.cwd()}/dist`)); // @ts-ignore
const clean = () => useSpinner('Cleaning', () => rimraf(`${process.cwd()}/dist`));
const copyIfNonExistent = (srcPath: string, destPath: string) => const copyIfNonExistent = (srcPath: string, destPath: string) =>
copyFile(srcPath, destPath, COPYFILE_EXCL) copyFile(srcPath, destPath, COPYFILE_EXCL)
...@@ -35,8 +36,9 @@ const copyIfNonExistent = (srcPath: string, destPath: string) => ...@@ -35,8 +36,9 @@ const copyIfNonExistent = (srcPath: string, destPath: string) =>
} }
}); });
export const prepare = useSpinner('Preparing', async () => { export const prepare = () =>
await Promise.all([ useSpinner('Preparing', () =>
Promise.all([
// Remove local dependencies for @grafana/data/node_modules // Remove local dependencies for @grafana/data/node_modules
// See: https://github.com/grafana/grafana/issues/26748 // See: https://github.com/grafana/grafana/issues/26748
rimraf(resolvePath(__dirname, 'node_modules/@grafana/data/node_modules')), rimraf(resolvePath(__dirname, 'node_modules/@grafana/data/node_modules')),
...@@ -51,22 +53,19 @@ export const prepare = useSpinner('Preparing', async () => { ...@@ -51,22 +53,19 @@ export const prepare = useSpinner('Preparing', async () => {
resolvePath(__dirname, '../../config/prettier.plugin.rc.js'), resolvePath(__dirname, '../../config/prettier.plugin.rc.js'),
resolvePath(process.cwd(), '.prettierrc.js') resolvePath(process.cwd(), '.prettierrc.js')
), ),
]); ])
);
// Nothing is returned
});
// @ts-ignore // @ts-ignore
const typecheckPlugin = useSpinner('Typechecking', async () => { const typecheckPlugin = () => useSpinner('Typechecking', () => execa('tsc', ['--noEmit']));
await execa('tsc', ['--noEmit']);
});
const getTypescriptSources = () => globby(resolvePath(process.cwd(), 'src/**/*.+(ts|tsx)')); const getTypescriptSources = () => globby(resolvePath(process.cwd(), 'src/**/*.+(ts|tsx)'));
// @ts-ignore // @ts-ignore
const getStylesSources = () => globby(resolvePath(process.cwd(), 'src/**/*.+(scss|css)')); const getStylesSources = () => globby(resolvePath(process.cwd(), 'src/**/*.+(scss|css)'));
export const lintPlugin = useSpinner<Fixable>('Linting', async ({ fix } = {}) => { export const lintPlugin = ({ fix }: Fixable = {}) =>
useSpinner('Linting', async () => {
try { try {
// Show a warning if the tslint file exists // Show a warning if the tslint file exists
await access(resolvePath(process.cwd(), 'tslint.json')); await access(resolvePath(process.cwd(), 'tslint.json'));
...@@ -110,7 +109,7 @@ export const lintPlugin = useSpinner<Fixable>('Linting', async ({ fix } = {}) => ...@@ -110,7 +109,7 @@ export const lintPlugin = useSpinner<Fixable>('Linting', async ({ fix } = {}) =>
console.log('\n'); console.log('\n');
throw new Error(`${errorCount + warningCount} linting errors found in ${results.length} files`); throw new Error(`${errorCount + warningCount} linting errors found in ${results.length} files`);
} }
}); });
export const pluginBuildRunner: TaskRunner<PluginBuildOptions> = async ({ coverage }) => { export const pluginBuildRunner: TaskRunner<PluginBuildOptions> = async ({ coverage }) => {
await prepare(); await prepare();
......
...@@ -7,11 +7,11 @@ import { lintPlugin } from './plugin.build'; ...@@ -7,11 +7,11 @@ import { lintPlugin } from './plugin.build';
import execa = require('execa'); import execa = require('execa');
import path = require('path'); import path = require('path');
const bundlePlugin = useSpinner<PluginBundleOptions>('Bundling plugin in dev mode', options => { const bundlePlugin = (options: PluginBundleOptions) =>
return bundleFn(options); useSpinner('Bundling plugin in dev mode', () => bundleFn(options));
});
const yarnlink = useSpinner('Linking local toolkit', async () => { const yarnlink = () =>
useSpinner('Linking local toolkit', async () => {
try { try {
// Make sure we are not using package.json defined toolkit // Make sure we are not using package.json defined toolkit
await execa('yarn', ['remove', '@grafana/toolkit']); await execa('yarn', ['remove', '@grafana/toolkit']);
...@@ -29,9 +29,7 @@ const yarnlink = useSpinner('Linking local toolkit', async () => { ...@@ -29,9 +29,7 @@ const yarnlink = useSpinner('Linking local toolkit', async () => {
await execa('yarn', args); await execa('yarn', args);
console.log('Added dependencies required by local @grafana/toolkit. Do not checkin this package.json!'); console.log('Added dependencies required by local @grafana/toolkit. Do not checkin this package.json!');
});
return Promise.resolve();
});
const pluginDevRunner: TaskRunner<PluginBundleOptions> = async options => { const pluginDevRunner: TaskRunner<PluginBundleOptions> = async options => {
if (options.yarnlink) { if (options.yarnlink) {
......
...@@ -5,7 +5,8 @@ import path = require('path'); ...@@ -5,7 +5,8 @@ import path = require('path');
interface UpdatePluginTask {} interface UpdatePluginTask {}
const updateCiConfig = useSpinner<any>('Updating CircleCI config', async () => { const updateCiConfig = () =>
useSpinner('Updating CircleCI config', async () => {
const ciConfigPath = path.join(process.cwd(), '.circleci'); const ciConfigPath = path.join(process.cwd(), '.circleci');
if (!fs.existsSync(ciConfigPath)) { if (!fs.existsSync(ciConfigPath)) {
fs.mkdirSync(ciConfigPath); fs.mkdirSync(ciConfigPath);
...@@ -14,10 +15,8 @@ const updateCiConfig = useSpinner<any>('Updating CircleCI config', async () => { ...@@ -14,10 +15,8 @@ const updateCiConfig = useSpinner<any>('Updating CircleCI config', async () => {
const sourceFile = path.join('node_modules/@grafana/toolkit/config/circleci', 'config.yml'); const sourceFile = path.join('node_modules/@grafana/toolkit/config/circleci', 'config.yml');
const destFile = path.join(ciConfigPath, 'config.yml'); const destFile = path.join(ciConfigPath, 'config.yml');
fs.copyFileSync(sourceFile, destFile); fs.copyFileSync(sourceFile, destFile);
}); });
const pluginUpdateRunner: TaskRunner<UpdatePluginTask> = async () => { const pluginUpdateRunner: TaskRunner<UpdatePluginTask> = () => updateCiConfig();
await updateCiConfig({});
};
export const pluginUpdateTask = new Task<UpdatePluginTask>('Update Plugin', pluginUpdateRunner); export const pluginUpdateTask = new Task<UpdatePluginTask>('Update Plugin', pluginUpdateRunner);
...@@ -58,7 +58,8 @@ const gitUrlParse = (url: string): { owner: string; name: string } => { ...@@ -58,7 +58,8 @@ const gitUrlParse = (url: string): { owner: string; name: string } => {
throw `Could not find a suitable git repository. Received [${url}]`; throw `Could not find a suitable git repository. Received [${url}]`;
}; };
const prepareRelease = useSpinner<any>('Preparing release', async ({ dryrun, verbose }) => { const prepareRelease = ({ dryrun, verbose }: any) =>
useSpinner('Preparing release', async () => {
const ciDir = getCiFolder(); const ciDir = getCiFolder();
const distDir = path.resolve(ciDir, 'dist'); const distDir = path.resolve(ciDir, 'dist');
const distContentDir = path.resolve(distDir, getPluginId()); const distContentDir = path.resolve(distDir, getPluginId());
...@@ -136,7 +137,7 @@ const prepareRelease = useSpinner<any>('Preparing release', async ({ dryrun, ver ...@@ -136,7 +137,7 @@ const prepareRelease = useSpinner<any>('Preparing release', async ({ dryrun, ver
process.exit(-1); process.exit(-1);
} }
} }
}); });
interface GithubPublishReleaseOptions { interface GithubPublishReleaseOptions {
commitHash?: string; commitHash?: string;
...@@ -145,13 +146,11 @@ interface GithubPublishReleaseOptions { ...@@ -145,13 +146,11 @@ interface GithubPublishReleaseOptions {
gitRepoName: string; gitRepoName: string;
} }
const createRelease = useSpinner<GithubPublishReleaseOptions>( const createRelease = ({ commitHash, githubUser, githubToken, gitRepoName }: GithubPublishReleaseOptions) =>
'Creating release', useSpinner('Creating release', async () => {
async ({ commitHash, githubUser, githubToken, gitRepoName }) => {
const gitRelease = new GitHubRelease(githubToken, githubUser, gitRepoName, await releaseNotes(), commitHash); const gitRelease = new GitHubRelease(githubToken, githubUser, gitRepoName, await releaseNotes(), commitHash);
return gitRelease.release(); return gitRelease.release();
} });
);
export interface GithubPublishOptions { export interface GithubPublishOptions {
dryrun?: boolean; dryrun?: boolean;
......
...@@ -9,7 +9,7 @@ export interface PluginBundleOptions { ...@@ -9,7 +9,7 @@ export interface PluginBundleOptions {
yarnlink?: boolean; yarnlink?: boolean;
} }
// export const bundlePlugin = useSpinner<PluginBundleOptions>('Bundle plugin', ({ watch }) => { // export const bundlePlugin = ({ watch, production }: PluginBundleOptions) => useSpinner('Bundle plugin', async () => {
export const bundlePlugin = async ({ watch, production }: PluginBundleOptions) => { export const bundlePlugin = async ({ watch, production }: PluginBundleOptions) => {
const compiler = webpack( const compiler = webpack(
await loadWebpackConfig({ await loadWebpackConfig({
......
...@@ -97,21 +97,26 @@ export const promptPluginDetails = async (name?: string) => { ...@@ -97,21 +97,26 @@ export const promptPluginDetails = async (name?: string) => {
}; };
}; };
export const fetchTemplate = useSpinner<{ type: PluginType; dest: string }>( export const fetchTemplate = ({ type, dest }: { type: PluginType; dest: string }) =>
'Fetching plugin template...', useSpinner('Fetching plugin template...', async () => {
async ({ type, dest }) => {
const url = RepositoriesPaths[type]; const url = RepositoriesPaths[type];
if (!url) { if (!url) {
throw new Error('Unknown plugin type'); throw new Error('Unknown plugin type');
} }
await simpleGit.clone(url, dest); await simpleGit.clone(url, dest);
} });
);
export const prepareJsonFiles = useSpinner<{ type: PluginType; pluginDetails: PluginDetails; pluginPath: string }>( export const prepareJsonFiles = ({
'Saving package.json and plugin.json files', type,
async ({ type, pluginDetails, pluginPath }) => { pluginDetails,
pluginPath,
}: {
type: PluginType;
pluginDetails: PluginDetails;
pluginPath: string;
}) =>
useSpinner('Saving package.json and plugin.json files', async () => {
const packageJsonPath = path.resolve(pluginPath, 'package.json'); const packageJsonPath = path.resolve(pluginPath, 'package.json');
const pluginJsonPath = path.resolve(pluginPath, 'src/plugin.json'); const pluginJsonPath = path.resolve(pluginPath, 'src/plugin.json');
const packageJson: any = JSON.parse(readFileSync(packageJsonPath, 'utf8')); const packageJson: any = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
...@@ -146,12 +151,10 @@ export const prepareJsonFiles = useSpinner<{ type: PluginType; pluginDetails: Pl ...@@ -146,12 +151,10 @@ export const prepareJsonFiles = useSpinner<{ type: PluginType; pluginDetails: Pl
return fs.writeFile(filePath, JSON.stringify(f, null, 2)); return fs.writeFile(filePath, JSON.stringify(f, null, 2));
}) })
); );
} });
);
export const removeGitFiles = useSpinner<string>('Cleaning', async pluginPath => export const removeGitFiles = (pluginPath: string) =>
rmdir(`${path.resolve(pluginPath, '.git')}`) useSpinner('Cleaning', async () => rmdir(`${path.resolve(pluginPath, '.git')}`));
);
/* eslint-disable no-console */ /* eslint-disable no-console */
export const formatPluginDetails = (details: PluginDetails) => { export const formatPluginDetails = (details: PluginDetails) => {
......
...@@ -10,9 +10,8 @@ export interface PluginTestOptions { ...@@ -10,9 +10,8 @@ export interface PluginTestOptions {
testNamePattern?: string; testNamePattern?: string;
} }
export const testPlugin = useSpinner<PluginTestOptions>( export const testPlugin = ({ updateSnapshot, coverage, watch, testPathPattern, testNamePattern }: PluginTestOptions) =>
'Running tests', useSpinner('Running tests', async () => {
async ({ updateSnapshot, coverage, watch, testPathPattern, testNamePattern }) => {
const testConfig = loadJestPluginConfig(); const testConfig = loadJestPluginConfig();
const cliConfig = { const cliConfig = {
...@@ -38,5 +37,4 @@ export const testPlugin = useSpinner<PluginTestOptions>( ...@@ -38,5 +37,4 @@ export const testPlugin = useSpinner<PluginTestOptions>(
throw new Error('Tests failed'); throw new Error('Tests failed');
} }
} }
} });
);
...@@ -8,26 +8,21 @@ const path = require('path'); ...@@ -8,26 +8,21 @@ const path = require('path');
let distDir: string, cwd: string; let distDir: string, cwd: string;
// @ts-ignore const clean = () => useSpinner('Cleaning', () => execa('npm', ['run', 'clean']));
export const clean = useSpinner('Cleaning', async () => await execa('npm', ['run', 'clean']));
// @ts-ignore const compile = () =>
const compile = useSpinner('Compiling sources', async () => { useSpinner('Compiling sources', async () => {
try { try {
await execa('tsc', ['-p', './tsconfig.json']); await execa('tsc', ['-p', './tsconfig.json']);
} catch (e) { } catch (e) {
console.log(e); console.log(e);
throw e; throw e;
} }
}); });
// @ts-ignore const savePackage = ({ path, pkg }: { path: string; pkg: {} }) =>
export const savePackage = useSpinner<{ useSpinner('Updating package.json', async () => {
path: string; new Promise((resolve, reject) => {
pkg: {};
// @ts-ignore
}>('Updating package.json', async ({ path, pkg }) => {
return new Promise((resolve, reject) => {
fs.writeFile(path, JSON.stringify(pkg, null, 2), err => { fs.writeFile(path, JSON.stringify(pkg, null, 2), err => {
if (err) { if (err) {
reject(err); reject(err);
...@@ -36,7 +31,7 @@ export const savePackage = useSpinner<{ ...@@ -36,7 +31,7 @@ export const savePackage = useSpinner<{
resolve(); resolve();
}); });
}); });
}); });
const preparePackage = async (pkg: any) => { const preparePackage = async (pkg: any) => {
pkg.bin = { pkg.bin = {
...@@ -63,7 +58,7 @@ const copyFiles = () => { ...@@ -63,7 +58,7 @@ const copyFiles = () => {
'src/config/styles.mock.js', 'src/config/styles.mock.js',
'src/config/jest.plugin.config.local.js', 'src/config/jest.plugin.config.local.js',
]; ];
// @ts-ignore
return useSpinner(`Moving ${files.join(', ')} files`, async () => { return useSpinner(`Moving ${files.join(', ')} files`, async () => {
const promises = files.map(file => { const promises = files.map(file => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
...@@ -82,12 +77,11 @@ const copyFiles = () => { ...@@ -82,12 +77,11 @@ const copyFiles = () => {
}); });
await Promise.all(promises); await Promise.all(promises);
})(); });
}; };
const copySassFiles = () => { const copySassFiles = () => {
const files = ['_variables.generated.scss', '_variables.dark.generated.scss', '_variables.light.generated.scss']; const files = ['_variables.generated.scss', '_variables.dark.generated.scss', '_variables.light.generated.scss'];
// @ts-ignore
return useSpinner(`Copy scss files ${files.join(', ')} files`, async () => { return useSpinner(`Copy scss files ${files.join(', ')} files`, async () => {
const sassDir = path.resolve(cwd, '../../public/sass/'); const sassDir = path.resolve(cwd, '../../public/sass/');
const promises = files.map(file => { const promises = files.map(file => {
...@@ -104,7 +98,7 @@ const copySassFiles = () => { ...@@ -104,7 +98,7 @@ const copySassFiles = () => {
}); });
await Promise.all(promises); await Promise.all(promises);
})(); });
}; };
interface ToolkitBuildOptions {} interface ToolkitBuildOptions {}
......
import ora = require('ora'); import ora from 'ora';
type FnToSpin<T> = (options: T) => Promise<any>; export const useSpinner = async (label: string, fn: () => Promise<any>, killProcess = true) => {
const spinner = ora(label);
export function useSpinner<T = void>(spinnerLabel: string, fn: FnToSpin<T>, killProcess = true) {
return async (options: T) => {
const spinner = ora(spinnerLabel);
spinner.start(); spinner.start();
try { try {
await fn(options); await fn();
spinner.succeed(); spinner.succeed();
} catch (e) { } catch (e) {
console.trace(e); // eslint-disable-line no-console console.trace(e); // eslint-disable-line no-console
...@@ -16,5 +13,4 @@ export function useSpinner<T = void>(spinnerLabel: string, fn: FnToSpin<T>, kill ...@@ -16,5 +13,4 @@ export function useSpinner<T = void>(spinnerLabel: string, fn: FnToSpin<T>, kill
process.exit(1); process.exit(1);
} }
} }
}; };
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment