├── README.md ├── git-d8ci ├── post-commit └── pre-commit /README.md: -------------------------------------------------------------------------------- 1 | # Drupal core committer git hooks 2 | 3 | ## About this project 4 | This project performs automated checks (e.g. file permissions, PHP/CSS/JS coding standards) before/after performing a commit, to ensure regressions are not accidentally committed. 5 | 6 | ## Project setup 7 | 8 | _How do I, as a developer, start working on the project?_ 9 | 10 | This project depends on: 11 | 12 | 1. [git] (https://git-scm.com/downloads) 13 | 1. [composer](https://getcomposer.org/download/) 14 | 1. Drupal 10 15 | 1. Running composer install in the root directory of the repository you have checked out 16 | 1. Running yarn install in the core directory of the repository you have checked out 17 | 18 | ### Optional dependencies 19 | 1. [Homebrew](http://brew.sh/) (You can use homebrew to install many of the dependencies above.) 20 | 1. pbcopy & pbpaste 21 | 1. cowsay (```brew install cowsay```) 22 | 23 | 24 | ## How to install 25 | 26 | 1. Clone the respository into any directory; for example your home directory: 27 | 28 | ```` 29 | cd ~; git clone https://github.com/alexpott/d8githooks.git 30 | ```` 31 | 32 | 1. Navigate to the `.git/hooks` directory inside the Drupal 8 clone from which you commit patches 33 | 34 | ```` 35 | cd ~/Sites/8.x/.git/hooks 36 | ```` 37 | 38 | 1. Create symlinks to pre-commit and post-commit files: 39 | 40 | ``` 41 | ln -sfn ~/d8githooks/pre-commit pre-commit; 42 | ln -sfn ~/d8githooks/post-commit post-commit; 43 | ```` 44 | 45 | 1. Mark the hooks as executable. 46 | 47 | ```` 48 | chmod u+x pre-commit; chmod u+x post-commit 49 | ```` 50 | 51 | To test that it's working, introduce a file permissions error and then attempt to commit a text change: 52 | 53 | ```` 54 | cd ~/Sites/8.x 55 | composer install 56 | chmod 777 core/core.services.yml 57 | echo 'test' >> core/core.services.yml 58 | git add core/core.services.yml 59 | git commit -m "Test." 60 | ```` 61 | 62 | You should see the error: 63 | 64 | ```` 65 | git pre-commit check failed: file core/core.services.yml should be 644 not 777 66 | ```` 67 | 68 | ## Troubleshooting 69 | 70 | ### Using core's Coder dev dependency 71 | 72 | If you previously installed PHPCS or Coder globally according to instructions on https://www.drupal.org/node/1419988 and your pre-commit hook starts failing silently, you may need to do: 73 | 74 | ```` 75 | composer global remove drupal/coder 76 | composer global remove phpcs 77 | composer install 78 | ```` 79 | 80 | This change is required because a canonical version of Coder is now added as a core dev dependency. 81 | 82 | ### Manually checking or fixing a PHP standard 83 | 84 | To manually test the standard on a particular file prior to commit: 85 | 86 | 1. Apply any relevant patch (including fixes, newly configured rules, etc.) 87 | 2. From within the repository, run: 88 | 89 | ```` 90 | composer install 91 | ```` 92 | 93 | 3. From the root of the repository, run: 94 | 95 | ```` 96 | composer run phpcs -- core/path/to/file.php 97 | ```` 98 | 99 | You can confirm that the check is working properly by (e.g.) adding an unused use statement to the file and ensuring it raises an error. 100 | 101 | Similarly, to use phpcbf to fix a file, run: 102 | 103 | ```` 104 | composer run phpcbf -- core/path/to/file.php 105 | ```` 106 | 107 | Note that in some cases the enabled core rules are not enough to fix errors correctly! You can also check: 108 | 109 | ```` 110 | vendor/bin/phpcs --standard=Drupal core/path/to/file.php 111 | ```` 112 | 113 | Be aware, however, that this may introduce out-of-scope changes as it will run rules that core does not yet comply with. 114 | 115 | ### Troubleshooting eslint 116 | 117 | ```` 118 | sudo npm update -g 119 | ```` 120 | 121 | If you previously installed yarn from Homebrew or another non-npm package manager: 122 | ```` 123 | brew uninstall yarn 124 | npm install -g corepack 125 | corepack enable 126 | ```` 127 | 128 | ## How to use 129 | @todo something about what standard message(s) to copy/paste. 130 | -------------------------------------------------------------------------------- /git-d8ci: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Instructions for set up: 4 | # 1. Put this in a file named git-d8ci in your $PATH 5 | # 2. chmod a+x git-d8ci 6 | 7 | # Instructions for use: 8 | # 1. Goto Drupal checkout on a branch you want to commit to. 9 | # 2. Apply the patch you want to commit and review it 10 | # 3. git d8ci OTHER_BRANCHES_TO_COMMIT_TO "commit message" 11 | # 4. Remember to use the push command it prepares for you at the end. Automatic pushes are not done to allow review. 12 | # Example command (whilst on 8.1.x): git d8ci 8.0.x 'Issue #2608072 by ameymudras: "Object of type "@class" cannot be printed." exception message should not be translated' 13 | # Example command (whilst on 8.2.x): git d8ci 8.1.x,8.0.x 'Issue #2608072 by ameymudras: "Object of type "@class" cannot be printed." exception message should not be translated' 14 | 15 | # Ensure there is something to commit. 16 | git diff --quiet --exit-code --cached 17 | CHANGES=$? 18 | if [[ "$CHANGES" == "0" ]] ; then 19 | echo "There's nothing to commit" 1>&2 && exit 1 20 | fi 21 | 22 | # Ensure we exit as soon as there is an error 23 | set -e 24 | 25 | branches=$1 26 | test -z $branches && echo "Other branch to commit to required." 1>&2 && exit 1 27 | 28 | branches=$(echo $branches | tr "," "\n") 29 | 30 | message=$2 31 | test -z "$message" && echo "Commit message required." 1>&2 && exit 1 32 | if ! [[ "$message" =~ ^Issue ]]; then 33 | echo "Message \"$message\" should start with 'Issue'." 1>&2 && exit 1 34 | fi 35 | 36 | for branch in $branches 37 | do 38 | # Check branch exists 39 | if ! git rev-parse --verify $branch >/dev/null 2>&1; then 40 | echo "git branch $branch not found." && exit 1 41 | fi 42 | done 43 | 44 | first_branch=`git rev-parse --abbrev-ref HEAD` 45 | 46 | # Commit patch to the first branch 47 | git commit -m "$message" 48 | commit_hash=`git log -n 1 --pretty=format:"%H"` 49 | short_commit_hash=`git log -n 1 --pretty=format:"%h"` 50 | push_message="Use the following command to push the changes: git push origin $first_branch" 51 | 52 | thanks_message="Committed and pushed $short_commit_hash to $first_branch" 53 | echo $TEXT | pbcopy 54 | 55 | for branch in $branches 56 | do 57 | # Cherry pick to the other branches. The -x option adds an additional line to the commit message linking back to the original commit. 58 | git checkout $branch 59 | git pull --rebase 60 | git cherry-pick -x $commit_hash 61 | branch_hash=`git log -n 1 --pretty=format:"%h"` 62 | thanks_message="$thanks_message and $branch_hash to $branch" 63 | push_message="$push_message $branch" 64 | done 65 | 66 | git checkout $first_branch 67 | echo "$push_message" 68 | 69 | echo "$thanks_message. Thanks!" | pbcopy 70 | -------------------------------------------------------------------------------- /post-commit: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | command_exists () { 3 | type "$1" &> /dev/null ; 4 | } 5 | 6 | REV=`git rev-parse --verify HEAD | head -c7` 7 | BRANCH=`git rev-parse --symbolic --abbrev-ref HEAD` 8 | TEXT="Committed $REV and pushed to $BRANCH. Thanks!" 9 | if command_exists pbcopy ; then 10 | echo $TEXT | pbcopy 11 | fi 12 | if command_exists cowsay ; then 13 | # Bug in cowsay's text wrapping :( 14 | cowsay -W 200 $TEXT 15 | else 16 | printf "$TEXT\n" 17 | fi 18 | printf "\n*** Does it need a change record? ***\n" 19 | printf "*** Should it be in the release notes? ***\n" 20 | -------------------------------------------------------------------------------- /pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | TOP_LEVEL=$(git rev-parse --show-toplevel); 4 | 5 | if [ -a "$TOP_LEVEL/core/scripts/dev/commit-code-check.sh" ] ; then 6 | $TOP_LEVEL/core/scripts/dev/commit-code-check.sh --cached 7 | exit $?; 8 | else 9 | echo "Can not find $TOP_LEVEL/core/scripts/dev/commit-code-check.sh" 10 | exit 1 11 | fi 12 | --------------------------------------------------------------------------------