{"id":18029077,"url":"https://github.com/edisonywh/committee","last_synced_at":"2025-08-03T17:38:08.075Z","repository":{"id":57484990,"uuid":"213426418","full_name":"edisonywh/committee","owner":"edisonywh","description":"️⚡️ Supercharged git hooks manager in pure Elixir","archived":false,"fork":false,"pushed_at":"2023-03-01T13:37:58.000Z","size":49,"stargazers_count":62,"open_issues_count":4,"forks_count":6,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-11-30T09:20:47.212Z","etag":null,"topics":["elixir","git","git-hooks"],"latest_commit_sha":null,"homepage":"","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/edisonywh.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-10-07T15:58:33.000Z","updated_at":"2024-04-29T09:43:39.000Z","dependencies_parsed_at":"2022-09-02T00:01:45.083Z","dependency_job_id":null,"html_url":"https://github.com/edisonywh/committee","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edisonywh%2Fcommittee","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edisonywh%2Fcommittee/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edisonywh%2Fcommittee/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edisonywh%2Fcommittee/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/edisonywh","download_url":"https://codeload.github.com/edisonywh/committee/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230374118,"owners_count":18216041,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["elixir","git","git-hooks"],"created_at":"2024-10-30T09:07:49.559Z","updated_at":"2024-12-19T04:07:25.973Z","avatar_url":"https://github.com/edisonywh.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Committee\n\n[![Build Status](https://github.com/edisonywh/committee/workflows/CI/badge.svg)](https://github.com/edisonywh/committee/actions)\n\n\u003e **Reminder**: While `Committee` is working great for my own use-case, there can be occasional bugs every now and then, if your workflow rely heavily on a Git workflow, proceed at your own risk. Otherwise a PR is very much welcomed!\n---\n\nCommittee is a supercharged ⚡️ git hooks manager in pure Elixir.\n\nWhat does supercharged mean? This is what supercharged means.\n\nSupercharged means:\n\n- You get to write ***code*** with your git hooks.\n- You get to write ***Elixir*** code with your git hooks.\n- You get to write ***any*** Elixir code with your git hooks.\n- ***Any. Elixir. Code. ⚡️***\n\n[Read on](https://github.com/edisonywh/committee#usage) to find out more!\n\n## Installation\n\nGet the latest version from [Hex](https://hex.pm/packages/committee)\n\n```elixir\ndef deps do\n  [\n    {:committee, \"~\u003e 1.0.0\", only: :dev, runtime: false}\n  ]\nend\n```\n\n## Usage\n\n*Documentation can be also be found over on [HexDocs](https://hexdocs.pm/committee).*\n\nAfter installing `Committee`, all you have to do is run\n\n\u003e `mix committee.install`\n\n*Your existing git hooks will be backed-up and renamed from `hook` to `hook.old`*\n\nYou should see a `.committee.exs` file being generated, that's where you'll be writing your hooks.\n\nThe file should look something like this:\n\n```elixir\ndefmodule YourApp.Commit do\n  use Committee\n  import Committee.Helpers, only: [staged_files: 0]\n\n  # ...\n  # ...\n  #\n  # ## Example:\n  #\n  #   def pre_commit do\n  #     System.cmd(\"mix\", [\"format\"] ++ staged_files())\n  #     System.cmd(\"git\", [\"add\"] ++ staged_files())\n  #   end\n  #\n  # ...\n  #\nend\n```\n\nTo run code for a hook, write a function with the same name (in `snake_case`) as that hook. For a full list of git hooks in the wild, [checkout this list over here](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks).\n\nTo **abort** a commit, return in the form of `{:halt, reason}`.\nTo **print** a success message, return in the form of `{:ok, message}`.\n\nIf you find that Committee does not do what you want (do let me know how to improve!) and you want to stop using it, you can run the built-in uninstallation task: `mix committee.uninstall`. **This will restore your existing hooks backup too**.\n\nFor a list of `Committee` supported hooks, checkout `Committee.__hooks__/0`\nFor a list of `Committee` provided helpers (such as `staged_files/0`, `branch_name/0`, checkout `Committee.Helpers`)\n\n*Currently only `pre_commit` and `post_commit` are supported, this is mostly because I haven't tested the other ones, rather than any technical limitation, but I don't see why it won't work for the others. PRs are welcomed!*\n\n### What are git hooks?\nIf you're reading this, you're probably familiar with Git. We are all used to terms like `commit`, `rebase`, but did you know that Git ships with the ability to run a hook/callback when you run these actions?\n\nThis effectively means you can write code that gets executed when you do a `git commit`, or when you're commencing a `rebase`. Exciting innit? :)\n\n### What is `Committee` trying to solve?\nGit hooks are great, but in my experience, there are two issues with them:\n\n#### 1) Hassle to set-up\nI find that it's not exactly straightforward to write git hooks, here's my own flow of writing a git hook (true story):\n\n- read up about the amazing git hooks (like you're doing now)\n- navigate into `.git/hooks`\n- `vim pre-commit`\n- *writes in bash* \u003csup\u003e1\u003c/sup\u003e\n- make `pre-commit` into an executable.\n- *Wait, how do you make it into an exectuable?*\n- *googles for 5 mins*\n- Ah, `chmod +x pre-commit`\n\nI wanted an easier process for myself, but also read on to find out more.\n\n#### 2) Difficult to share with team\nGit hooks live in the `.git/hooks/` folder, and **`.git` folder isn't versioned**, this means that whatever you've just done in the [previous step](https://github.com/edisonywh/committee#step-1) would not work for your other team members.\n\nNo biggie aye? You just have to get **each and every one** of your teammate to repeat step 1.\n\nDid I also mentioned that if you decided to update the `pre-commit` script (for example, you have a change in branchs' naming convention), you'd have to again, convince everyone in your team to repeat step 1?\n\n*Yup.*\n\n#### Get yourself a `Committee`!\n\nThe premise of `Committee` is simple, it solves the aforementioned problems like so:\n\n\u003e Hassle to set-up\n\nWell for starters, you don't have to write any bash script\u003csup\u003e1\u003c/sup\u003e. Bash scripts are great, but wouldn't you rather write Elixir?\n\nAlso, you dont have to care about things like making a file executable. `Committee` will handle that for you :)\n\n\u003e Difficult to share with team\n\n`Committee` exposes an easy mix task to install itself.\n\nTo share it with your team, all you have to do is to put `mix committee.install` in one of your onboarding script. **It's a one-time installation**, and from then on, any updates you make to `.committee.exs` (`Committee`'s configuration file) will become **immediately available to your team mates**.\n\n*No fuss, no muss.*\n\n### What are some alternatives?\n\n#### Husky\nHusky is great, it's a popular git hook manager in JavaScript-land. It is not limited to just JS, it also works for any other languages, including Elixir.\n\nThe only downside is that you'd need to set up `package.json` to include the `husky` dependency. I figured not every Elixir project would have `package.json` (for example when developing a library), hence `Committee`.\n\nHusky is a much more battle-proven solution, and works for most scenarios (especially if you already have a `package.json`), so definitely go for that if suits your use case.\n\n#### Lefthook\nA project from Evil Martian. This project is really interesting, it is written in Go, works for any language by using a language-agnostic `.yml` config file. I like the idea that it's taking.\n\nI was really contemplating using Lefthook, but I decided to take up a sort of challenge to come up with an Elixir-like hook manager, so well here we are..\n\n#### Other Elixir Alternatives\nThere are few more Elixir-centric packages, like:\n\n- [husky-elixir](https://github.com/spencerdcarlson/husky-elixir) (I'm not sure if it's officially affliated with the JavaScript library)\n- [elixir_git_hooks](https://github.com/qgadrian/elixir_git_hooks)\n- [elixir-pre-commit](https://github.com/dwyl/elixir-pre-commit)\n\nThey all look great, but all hinges on using `config.exs` to do configuration \u003csup\u003e*Now that I'm writing this out, I realised I'm the outlier here..*\u003c/sup\u003e, which works, but I decided to be a little bit more creative, and take this Elixir thing a step further.\n\nThus born `Committee`, which allows you to write any Elixir code in a `.committee.exs` file, because why not?\n\n\u003e \u003csup\u003e1\u003c/sup\u003e This is not always the case, you can change the [shebang](https://en.wikipedia.org/wiki/Shebang_(Unix)) to run your code with other shell/languages, such as `ruby`.\n\n---\n\n## Contributions\nContributions are very welcomed, but please first [open an issue](https://github.com/edisonywh/committee/issues/new) so we can align and discuss before any development begins.\n\n## License\nView [License](https://github.com/edisonywh/committee/blob/master/LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fedisonywh%2Fcommittee","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fedisonywh%2Fcommittee","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fedisonywh%2Fcommittee/lists"}