blob: ac46273f1ae5e2ed6d8cdc866f3e2001fb9eb72c [file] [log] [blame]
#!/bin/env node
/* eslint-disable no-console */
/**
* Build packages/plugins filtered by globs
*/
process.env.PATH = `./node_modules/.bin:${process.env.PATH}`;
const rimraf = require('rimraf');
const { spawnSync } = require('child_process');
const fastGlob = require('fast-glob');
const { argv } = require('yargs')
.option('lint', {
describe: 'whether to run ESLint',
type: 'boolean',
// lint is slow, so not turning it on by default
default: false,
})
.option('babel', {
describe: 'Whether to run Babel',
type: 'boolean',
default: true,
})
.option('clean', {
describe: 'Whether to clean cache',
type: 'boolean',
default: false,
})
.option('type', {
describe: 'Whether to run tsc',
type: 'boolean',
default: true,
});
const {
_: globs,
lint: shouldLint,
babel: shouldRunBabel,
clean: shouldCleanup,
type: shouldRunTyping,
} = argv;
const glob = globs.length > 1 ? `{${globs.join(',')}}` : globs[0] || '*';
const BABEL_CONFIG = '--config-file=../../babel.config.js';
// packages that do not need tsc
const META_PACKAGES = new Set(['demo', 'generator-superset']);
function run(cmd, options) {
console.log(`\n>> ${cmd}\n`);
const [p, ...args] = cmd.split(' ');
const runner = spawnSync;
const { status } = runner(p, args, { stdio: 'inherit', ...options });
if (status !== 0) {
process.exit(status);
}
}
function getPackages(packagePattern, tsOnly = false) {
let pattern = packagePattern;
if (pattern === '*' && !tsOnly) {
return `@superset-ui/!(${[...META_PACKAGES].join('|')})`;
}
if (!pattern.includes('*')) {
pattern = `*${pattern}`;
}
const packages = [
...new Set(
fastGlob
.sync([
`./node_modules/@superset-ui/${pattern}/src/**/*.${
tsOnly ? '{ts,tsx}' : '{ts,tsx,js,jsx}'
}`,
])
.map(x => x.split('/')[3])
.filter(x => !META_PACKAGES.has(x)),
),
];
if (packages.length === 0) {
throw new Error('No matching packages');
}
return `@superset-ui/${packages.length > 1 ? `{${packages.join(',')}}` : packages[0]}`;
}
let scope = getPackages(glob);
if (shouldLint) {
run(`yarn lint --fix {packages,plugins}/${scope}/{src,test}`);
}
if (shouldCleanup) {
// these modules will be installed by `npm link` but not useful for actual build
const dirtyModules = 'node_modules/@types/react,node_modules/@superset-ui';
const cachePath = shouldRunBabel
? `./node_modules/${scope}/{lib,esm,tsconfig.tsbuildinfo,${dirtyModules}}`
: `./node_modules/${scope}/{lib/**/*.d.ts,tsconfig.tsbuildinfo,${dirtyModules}}`;
console.log(`\n>> Cleaning up ${cachePath}`);
rimraf.sync(cachePath);
}
if (shouldRunBabel) {
console.log('--- Run babel --------');
const babelCommand = `lerna exec --stream --concurrency 10 --scope ${scope}
-- babel ${BABEL_CONFIG} src --extensions ".ts,.tsx,.js,.jsx" --copy-files`;
run(`${babelCommand} --out-dir lib`);
console.log('--- Run babel esm ---');
// run again with
run(`${babelCommand} --out-dir esm`, { env: { ...process.env, BABEL_OUTPUT: 'esm' } });
}
if (shouldRunTyping) {
// only run tsc for packages with ts files
scope = getPackages(glob, true);
run(`lerna exec --stream --concurrency 3 --scope ${scope} \
-- ../../scripts/tsc.sh --build`);
}