commitizen / cz-cli

The commitizen command line utility. #BlackLivesMatter
http://commitizen.github.io/cz-cli/
MIT License
16.7k stars 547 forks source link

Add adapters-repo hooks #63

Open jimthedev opened 8 years ago

jimthedev commented 8 years ago

As an adapter author, I want to be able to have my adapter be configurable (data) and also be able to tap into hook functions (events). I want repo maintainers to be able to define paths to hooks in a similar manor to what we let adapter maintainers do in the commitizen cli-adapter relationship. In the cli-adapter relationship there is really just one hook (prompter) that runs the prompter method of the adapter. Ideally we'd have more hooks available to allow the cli-adapter-repo chain to be solid and configurable.

I would imagine that both the cli-adapter and the adapter-repo relationship need more hooks to be effective. I'm not really sure exactly what points people would want to tap into but this is something I'd love to hear more about from adapter maintainers.

Specifically, if I maintain cz-conventional-widgets, I might decide that I want someone who maintains the AwesomeWidgetBuilder repo to be able to define the following in their package.json:

{
  config: {
    commitizen: {

      // HOOKS: All hooks are exports of one file, hooks is an array, with index 0 being the path
      hooks: ['myfile.js', 'init', 'bootstrap'];

      // -- OR --

      // HOOKS: Each hook is in its own file, hooks is an object
      hooks: {

        // SIMPLE HOOK ITEMS: the exported bootstrap method gets run from myRepoCzSettings.js
        "bootstrap": "./myRepoCzBootstrap.js",
        "end": "./myRepoCzEnd.js",

        // -- OR --

        // ADVANCED HOOK ITEMS: an object is used and we call mySweetInitFunction in the init hook
        "init": {
          path: "./myCzRepoInit.js",
          function: "mySweetInitFunction"
        }

      }
    }
  }
}

This way my adapter and any other adapters that follow my interface can make calls into the repo paths and expect to get data back from the repo.

Note that because the config paths are not scoped to a specific adapter but rather to a series of hooks, an adapter that uses a different commit style could still implement the interface and serve the repo owner. Specifically, if I use the widgetReader interface hooks then I can use either cz-conventional-changelog or cz-smart-commit without having an issue so long as the adapters follow the interface an calls certain hooks at expected times in the execution flow.

jimthedev commented 8 years ago

Hello @kentcdodds @leonardoanalista @rebelliard @tjoskar @mcwhittemore!

Since you're all adapter authors, have worked with adapters or have inquired about information provided to adapters by commitizen I wanted to reach out to you to gather feedback on this hooks api. My goal of the above hooks api is to allow for adapters and repos to interact but retain the highly configurable nature of commitizen. I know you all probably have different use-cases but before I implement something like this I'd want to make sure to cover any of the things you might like to see from 3.0.0 or scrap it now if there's a better solution out there.

In addition to implementing any features that make it easier for your adapter to call these hooks I will make sure your adapter gets passed the following:

If you have any feedback, further questions, or additional information you'd like to be passed, please let me know so I can look into how feasible it would be.

Thanks!

Jim

kentcdodds commented 8 years ago

I don't see any issues with this proposal for my use case. As far as the config api, getting the order right can be a real pain. Objects don't do order very well, arrays do. Just my thoughts there :-)

jimthedev commented 8 years ago

Thanks Kent. To be clear, hooks fire order would always need to be managed by the adapter author. We would have recommendations like bootstrap should fire before init should fire before end. The only reason to use an array syntax here is for convenience so that you can use shorthand if all of the repo hooks are exported from the same single-file module.

kentcdodds commented 8 years ago

Ah, I see, makes sense :-) In that case I prefer the object version :-)

leonardoanalista commented 8 years ago

@jimthedev thanks for looping me in. Sometimes, I like to see the staged files before I go ahead with the commit. Before commitizen, I used to run git commit, then type my commit message. When I see the files I have a clue about what I ma about to commit. This is not a major thing as I can just to a git status before git cz. I am going to present the tool to a group of people. I let you know if we come up with any special use case. cheers Leonardo

mcwhittemore commented 8 years ago

The branch name, package.json and cli version sound great to me.

I'm a bit confused about hook order. Are you saying that as an adapter author I decide the order hooks are run in or that commitizen will handle hook order? If commitizen is handling it, I'd say hooks should have names like hooks in git. If commitizen isn't handling it, I'm struggling to understand the reason for hooks. Are they a standard interface all adapter authors agree too? Sounds like something I could give my users via package.json modification. What am I missing here?