Skip to content

Instantly share code, notes, and snippets.

@ianwremmel
Created August 3, 2017 20:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ianwremmel/ad0edf01b11dd7c8898ff152ffd07853 to your computer and use it in GitHub Desktop.
Save ianwremmel/ad0edf01b11dd7c8898ff152ffd07853 to your computer and use it in GitHub Desktop.
codemod: remove wrapHandler
/**
* turns e.g.
*
* ```
* const wrapHandler = require(`../lib/wrap-handler`);
* const {list, spawn} = require(`../util/package`);
*
* module.exports = {
* command: `exec cmd [args...]`,
* desc: `Run a command in each package directory`,
* builder: {},
* handler: wrapHandler(async ({cmd, args}) => {
* for (const packageName of await list()) {
* await spawn(packageName, cmd, args);
* }
* })
* };
* ```
* into
*
* ```
* const {list, spawn} = require(`../util/package`);
*
* module.exports = {
* command: `exec cmd [args...]`,
* desc: `Run a command in each package directory`,
* builder: {},
* async handler({cmd, args}) {
* for (const packageName of await list()) {
* await spawn(packageName, cmd, args);
* }
* }
* };
* ```
*/
module.exports = function transform({source}, {jscodeshift}) {
const j = jscodeshift;
const root = jscodeshift(source);
// remove calls to wrapHandler and change the handler property to a method
// shorthand
root
.find(jscodeshift.CallExpression, {
callee: {
name: `wrapHandler`
}
})
.replaceWith((p) => {
// seems there's a bug in jscodeshift where it doesn't accept the async
// param in the functionExpression factory, so we need to do this bit of
// silliness instead
const res = jscodeshift.functionExpression(jscodeshift.identifier(`handler`), p.node.arguments[0].params, p.node.arguments[0].body);
res.async = true;
return res;
})
.forEach((p) => {
p.parentPath.node.method = true;
});
// Remove require of wrapHandler
root
.find(j.VariableDeclarator, {
id: {type: `Identifier`, name: `wrapHandler`},
init: {callee: {name: `require`}}
})
.forEach((p) => j(p).remove());
// Remove leading blank lines but ensure we have a newline at the end of the
// file
return `${root.toSource().trim()}\n`;
};
@ianwremmel
Copy link
Author

Instead of wrapping every handler, use something like the following in your yargs entrypoint.

process.on(`unhandledRejection`, (err) => {
  const cmd = `bowman ${process.argv.slice(2).join(` `)}`;
  console.error(`Failed to execute "${cmd}"`);
  console.error(err.toString());
  if (argv.debug) {
    console.error(err);
  }
  // eslint-disable-next-line no-process-exit
  process.exit(E_UNHANDLED_REJECTION);
});

@ianwremmel
Copy link
Author

Note: this doesn't handle import syntax for loading wrapHandler, but it's a small modification to add it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment