Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add hooks for life cycle events: using .preAction(), .postAction() #1519

Closed
wants to merge 23 commits into from

Conversation

shadowspawn
Copy link
Collaborator

@shadowspawn shadowspawn commented May 13, 2021

Pull Request

Problem

People ask for a way to run code before the action handler with access to the parsed options. And also some requests for a hook after the action.

Main issue: #1197
Related issues: #76 #229 #936 #996 #1158 #1457

Solution

Add .preAction() and .postAction() methods:

  • supports async callbacks
  • supports multiple hooks for same event on single command

Triggered by action handler for hooked command and its subcommands.

Callback passed two Command parameters:

  • thisCommand: the command which the hook is added to, useful for working with global properties.
  • actionCommand: the command with the action handler

ChangeLog

  • add .preAction() and .postAction() hooks

@shadowspawn shadowspawn changed the title Add hooks for life cycle events: .beforeAction(), .afterAction() Add hooks for life cycle events: using .beforeAction(), .afterAction() May 13, 2021
@shadowspawn shadowspawn changed the base branch from master to release/8.x May 13, 2021 08:06
@shadowspawn shadowspawn changed the title Add hooks for life cycle events: using .beforeAction(), .afterAction() Add hooks for life cycle events: using .preAction(), .postAction() May 14, 2021
@shadowspawn
Copy link
Collaborator Author

shadowspawn commented May 14, 2021

This is a rework of the signature for life cycle events from #1514:

  • multiple named methods instead of a single hook with named events
  • pass parameters instead of context hash

This gives a cleaner callback, especially when caller only cares about thisCommand, but increased chance of confusion between the two parameters.

So looks like:

program
   .preAction((thisCommand, actionCommand) => {});
   .postAction((thisCommand, actionCommand) => {});

instead of

program
   .hook('beforeAction', (context) => {});
   .hook('afterAction', (context) => {});

@shadowspawn shadowspawn marked this pull request as ready for review May 14, 2021 08:06
@shadowspawn shadowspawn added this to the v8.0.0 milestone May 14, 2021
@shadowspawn
Copy link
Collaborator Author

shadowspawn commented May 15, 2021

For an example of the alternative approach of a single hook routine which is passed an event name rather than separately named methods for the hooks, see:

https://www.fastify.io/docs/latest/Hooks/

A key reason for the single hook approach is if there are going to be lots of hooks. The pattern is similar to eventEmitter and .on(event, ....). fastify describes 13 hooks.

@shadowspawn
Copy link
Collaborator Author

shadowspawn commented May 16, 2021

For interest, also noticed in the fastify docs:

Hook functions are invoked with this bound to the associated Fastify instance.

Commander does the same with the action callback, and EventEmitter does this with listeners. Because it does not work with arrow functions, I have not been treating this as the main way of passing in command context.

@shadowspawn shadowspawn marked this pull request as draft May 16, 2021 02:40
@shadowspawn
Copy link
Collaborator Author

I am quite liking how fastify looks, and I like including "hook" in the wording as it is how this sort of pattern is often described.

Thinking of switching back to hook! This time with parameters:

program
   .hook('preAction', (thisCommand, actionCommand) => {});
   .hook('postAction', (thisCommand, actionCommand) => {});

@shadowspawn shadowspawn removed this from the v8.0.0 milestone May 16, 2021
@shadowspawn shadowspawn deleted the feature/hook-renamed branch May 20, 2021 07:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant