2017-08-21 01:03:34 +02:00
|
|
|
#!/usr/bin/env node
|
2017-07-23 21:41:25 +02:00
|
|
|
|
2020-04-07 20:26:25 +02:00
|
|
|
/* eslint-disable global-require */
|
2020-09-19 17:36:02 +02:00
|
|
|
|
2022-07-25 13:26:29 +02:00
|
|
|
const { spawnSync } = require('child_process');
|
2022-07-26 09:32:13 +02:00
|
|
|
const { join } = require('path');
|
2020-09-19 17:36:02 +02:00
|
|
|
const { maxConcurrentTasks } = require('./utils/concurrency');
|
2022-07-25 13:26:29 +02:00
|
|
|
|
|
|
|
const spawn = (command, options = {}) => {
|
|
|
|
return spawnSync(`${command}`, {
|
|
|
|
shell: true,
|
|
|
|
stdio: 'inherit',
|
|
|
|
...options,
|
|
|
|
});
|
|
|
|
};
|
2017-08-20 23:48:27 +02:00
|
|
|
|
2019-06-06 01:57:31 +02:00
|
|
|
function run() {
|
2020-11-23 15:06:51 +01:00
|
|
|
const prompts = require('prompts');
|
2019-06-06 01:57:31 +02:00
|
|
|
const program = require('commander');
|
|
|
|
const chalk = require('chalk');
|
|
|
|
const log = require('npmlog');
|
|
|
|
|
|
|
|
log.heading = 'storybook';
|
|
|
|
const prefix = 'bootstrap';
|
|
|
|
log.addLevel('aborted', 3001, { fg: 'red', bold: true });
|
|
|
|
|
|
|
|
const main = program
|
|
|
|
.version('5.0.0')
|
|
|
|
.option('--all', `Bootstrap everything ${chalk.gray('(all)')}`);
|
|
|
|
|
|
|
|
const createTask = ({
|
|
|
|
defaultValue,
|
|
|
|
option,
|
|
|
|
name,
|
|
|
|
check = () => true,
|
|
|
|
command,
|
|
|
|
pre = [],
|
|
|
|
order,
|
|
|
|
}) => ({
|
|
|
|
value: false,
|
|
|
|
defaultValue: defaultValue || false,
|
|
|
|
option: option || undefined,
|
|
|
|
name: name || 'unnamed task',
|
|
|
|
check: check || (() => true),
|
|
|
|
order,
|
2019-04-24 12:31:01 +02:00
|
|
|
command: () => {
|
2019-06-06 01:57:31 +02:00
|
|
|
// run all pre tasks
|
|
|
|
pre
|
2020-03-27 20:04:50 +01:00
|
|
|
.map((key) => tasks[key])
|
|
|
|
.forEach((task) => {
|
2019-06-06 01:57:31 +02:00
|
|
|
if (task.check()) {
|
|
|
|
task.command();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
log.info(prefix, name);
|
|
|
|
command();
|
2019-04-24 12:31:01 +02:00
|
|
|
},
|
2019-06-06 01:57:31 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
const tasks = {
|
|
|
|
core: createTask({
|
2020-11-02 07:04:27 +08:00
|
|
|
name: `Core & Examples ${chalk.gray('(core)')}`,
|
2022-05-25 13:10:48 +02:00
|
|
|
defaultValue: false,
|
2019-06-06 01:57:31 +02:00
|
|
|
option: '--core',
|
|
|
|
command: () => {
|
|
|
|
log.info(prefix, 'yarn workspace');
|
|
|
|
},
|
2022-06-24 16:46:02 +02:00
|
|
|
pre: ['install', 'build'],
|
2019-06-06 01:57:31 +02:00
|
|
|
order: 1,
|
|
|
|
}),
|
2022-05-25 13:10:48 +02:00
|
|
|
prep: createTask({
|
|
|
|
name: `Prep for development ${chalk.gray('(prep)')}`,
|
|
|
|
defaultValue: true,
|
|
|
|
option: '--prep',
|
|
|
|
command: () => {
|
2022-08-22 20:01:07 +08:00
|
|
|
log.info(prefix, 'prepare');
|
2022-07-23 17:15:13 +02:00
|
|
|
spawn(
|
2022-08-22 20:01:07 +08:00
|
|
|
`nx run-many --target="prepare" --all --parallel --exclude=@storybook/addon-storyshots,@storybook/addon-storyshots-puppeteer -- --reset`
|
2022-07-23 17:15:13 +02:00
|
|
|
);
|
2022-05-25 13:10:48 +02:00
|
|
|
},
|
|
|
|
order: 2,
|
|
|
|
}),
|
2022-01-26 14:12:34 +01:00
|
|
|
retry: createTask({
|
|
|
|
name: `Core & Examples but only build previously failed ${chalk.gray('(core)')}`,
|
|
|
|
defaultValue: true,
|
|
|
|
option: '--retry',
|
|
|
|
command: () => {
|
2022-08-22 20:01:07 +08:00
|
|
|
log.info(prefix, 'prepare');
|
2022-01-26 14:12:34 +01:00
|
|
|
spawn(
|
2022-08-22 20:01:07 +08:00
|
|
|
`nx run-many --target=prepare --all --parallel --only-failed ${
|
2022-01-26 14:12:34 +01:00
|
|
|
process.env.CI ? `--max-parallel=${maxConcurrentTasks}` : ''
|
|
|
|
}`
|
|
|
|
);
|
|
|
|
},
|
|
|
|
order: 1,
|
|
|
|
}),
|
2019-06-06 01:57:31 +02:00
|
|
|
reset: createTask({
|
|
|
|
name: `Clean repository ${chalk.red('(reset)')}`,
|
|
|
|
defaultValue: false,
|
|
|
|
option: '--reset',
|
|
|
|
command: () => {
|
|
|
|
log.info(prefix, 'git clean');
|
2022-07-26 09:32:13 +02:00
|
|
|
spawn(`node -r esm ${join(__dirname, 'reset.js')}`);
|
2019-06-06 01:57:31 +02:00
|
|
|
},
|
|
|
|
order: 0,
|
|
|
|
}),
|
|
|
|
install: createTask({
|
|
|
|
name: `Install dependencies ${chalk.gray('(install)')}`,
|
|
|
|
defaultValue: false,
|
|
|
|
option: '--install',
|
|
|
|
command: () => {
|
2021-02-15 17:45:08 +01:00
|
|
|
const command = process.env.CI ? `yarn install --immutable` : `yarn install`;
|
2020-04-13 23:11:35 +02:00
|
|
|
spawn(command);
|
2017-06-08 09:24:12 +02:00
|
|
|
},
|
2019-06-06 01:57:31 +02:00
|
|
|
order: 1,
|
|
|
|
}),
|
|
|
|
build: createTask({
|
|
|
|
name: `Build packages ${chalk.gray('(build)')}`,
|
|
|
|
defaultValue: false,
|
|
|
|
option: '--build',
|
|
|
|
command: () => {
|
2022-05-25 13:10:48 +02:00
|
|
|
log.info(prefix, 'build');
|
2020-09-19 17:36:02 +02:00
|
|
|
spawn(
|
2022-08-22 20:01:07 +08:00
|
|
|
`nx run-many --target="prepare" --all --parallel=8 ${
|
2021-04-07 17:25:12 +02:00
|
|
|
process.env.CI ? `--max-parallel=${maxConcurrentTasks}` : ''
|
2022-05-25 13:10:48 +02:00
|
|
|
} -- --reset --optimized`
|
2020-09-19 17:36:02 +02:00
|
|
|
);
|
2019-06-06 01:57:31 +02:00
|
|
|
},
|
|
|
|
order: 2,
|
|
|
|
}),
|
|
|
|
registry: createTask({
|
|
|
|
name: `Run local registry ${chalk.gray('(reg)')}`,
|
|
|
|
defaultValue: false,
|
|
|
|
option: '--reg',
|
|
|
|
command: () => {
|
2022-08-22 17:40:30 +08:00
|
|
|
spawn('yarn local-registry --publish --open --port 6001');
|
2019-06-06 01:57:31 +02:00
|
|
|
},
|
|
|
|
order: 11,
|
|
|
|
}),
|
|
|
|
dev: createTask({
|
|
|
|
name: `Run build in watch mode ${chalk.gray('(dev)')}`,
|
|
|
|
defaultValue: false,
|
|
|
|
option: '--dev',
|
|
|
|
command: () => {
|
2022-01-26 14:12:34 +01:00
|
|
|
spawn('yarn build');
|
2019-06-06 01:57:31 +02:00
|
|
|
},
|
|
|
|
order: 9,
|
|
|
|
}),
|
|
|
|
};
|
|
|
|
|
|
|
|
const groups = {
|
2022-05-25 13:10:48 +02:00
|
|
|
main: ['prep', 'core'],
|
2022-06-24 16:46:02 +02:00
|
|
|
buildtasks: ['install', 'build'],
|
2022-08-22 16:36:22 +08:00
|
|
|
devtasks: ['dev', 'registry', 'reset'],
|
2019-06-06 01:57:31 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
Object.keys(tasks)
|
|
|
|
.reduce((acc, key) => acc.option(tasks[key].option, tasks[key].name), main)
|
|
|
|
.parse(process.argv);
|
|
|
|
|
2020-03-27 20:04:50 +01:00
|
|
|
Object.keys(tasks).forEach((key) => {
|
2019-06-06 01:57:31 +02:00
|
|
|
tasks[key].value = program[tasks[key].option.replace('--', '')] || program.all;
|
|
|
|
});
|
|
|
|
|
2020-11-23 15:06:51 +01:00
|
|
|
const createSeparator = (input) => ({
|
|
|
|
title: `- ${input}${' ---------'.substr(0, 12)}`,
|
|
|
|
disabled: true,
|
|
|
|
});
|
2019-06-06 01:57:31 +02:00
|
|
|
|
|
|
|
const choices = Object.values(groups)
|
2020-03-27 20:04:50 +01:00
|
|
|
.map((l) =>
|
|
|
|
l.map((key) => ({
|
2020-11-23 15:06:51 +01:00
|
|
|
value: tasks[key].name,
|
|
|
|
title: tasks[key].name,
|
|
|
|
selected: tasks[key].defaultValue,
|
2019-06-06 01:57:31 +02:00
|
|
|
}))
|
2017-08-23 21:15:49 +02:00
|
|
|
)
|
2020-11-23 15:06:51 +01:00
|
|
|
.reduce((acc, i, k) => acc.concat(createSeparator(Object.keys(groups)[k])).concat(i), []);
|
2019-06-06 01:57:31 +02:00
|
|
|
|
|
|
|
let selection;
|
|
|
|
if (
|
|
|
|
!Object.keys(tasks)
|
2020-03-27 20:04:50 +01:00
|
|
|
.map((key) => tasks[key].value)
|
2019-06-06 01:57:31 +02:00
|
|
|
.filter(Boolean).length
|
|
|
|
) {
|
2020-11-23 15:06:51 +01:00
|
|
|
selection = prompts([
|
|
|
|
{
|
|
|
|
type: 'multiselect',
|
|
|
|
message: 'Select the bootstrap activities',
|
|
|
|
name: 'todo',
|
|
|
|
warn: ' ',
|
|
|
|
pageSize: Object.keys(tasks).length + Object.keys(groups).length,
|
|
|
|
choices,
|
|
|
|
},
|
|
|
|
])
|
2019-06-06 01:57:31 +02:00
|
|
|
.then(({ todo }) =>
|
2020-03-27 20:04:50 +01:00
|
|
|
todo.map((name) => tasks[Object.keys(tasks).find((i) => tasks[i].name === name)])
|
2019-06-06 01:57:31 +02:00
|
|
|
)
|
2020-03-27 20:04:50 +01:00
|
|
|
.then((list) => {
|
|
|
|
if (list.find((i) => i === tasks.reset)) {
|
2020-11-23 15:06:51 +01:00
|
|
|
return prompts([
|
|
|
|
{
|
|
|
|
type: 'confirm',
|
|
|
|
message: `${chalk.red(
|
|
|
|
'DESTRUCTIVE'
|
|
|
|
)} deletes node_modules, files not present in git ${chalk.underline(
|
|
|
|
'will get trashed'
|
|
|
|
)}, except for .idea and .vscode, ${chalk.cyan('Continue?')}`,
|
|
|
|
name: 'sure',
|
|
|
|
},
|
|
|
|
]).then(({ sure }) => {
|
|
|
|
if (sure) {
|
|
|
|
return list;
|
|
|
|
}
|
2022-05-24 13:37:45 +02:00
|
|
|
throw new Error('Cleanup canceled');
|
2020-11-23 15:06:51 +01:00
|
|
|
});
|
2019-06-06 01:57:31 +02:00
|
|
|
}
|
|
|
|
return list;
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
selection = Promise.resolve(
|
|
|
|
Object.keys(tasks)
|
2020-03-27 20:04:50 +01:00
|
|
|
.map((key) => tasks[key])
|
|
|
|
.filter((item) => item.value === true)
|
2019-06-06 01:57:31 +02:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
selection
|
2020-03-27 20:04:50 +01:00
|
|
|
.then((list) => {
|
2019-06-06 01:57:31 +02:00
|
|
|
if (list.length === 0) {
|
|
|
|
log.warn(prefix, 'Nothing to bootstrap');
|
|
|
|
} else {
|
|
|
|
list
|
|
|
|
.sort((a, b) => a.order - b.order)
|
2020-03-27 20:04:50 +01:00
|
|
|
.forEach((key) => {
|
2019-06-06 01:57:31 +02:00
|
|
|
key.command();
|
2017-08-23 21:15:49 +02:00
|
|
|
});
|
2019-06-06 01:57:31 +02:00
|
|
|
process.stdout.write('\x07');
|
2017-08-23 21:15:49 +02:00
|
|
|
}
|
2019-06-06 01:57:31 +02:00
|
|
|
})
|
2020-03-27 20:04:50 +01:00
|
|
|
.catch((e) => {
|
2019-06-06 01:57:31 +02:00
|
|
|
log.aborted(prefix, chalk.red(e.message));
|
|
|
|
log.silly(prefix, e);
|
|
|
|
process.exit(1);
|
2017-08-23 21:15:49 +02:00
|
|
|
});
|
2017-06-08 09:24:12 +02:00
|
|
|
}
|
2020-04-07 20:26:25 +02:00
|
|
|
|
2022-07-25 13:26:29 +02:00
|
|
|
run();
|