diff --git a/tools/hooks/README.md b/tools/hooks/README.md new file mode 100644 index 0000000000..b15fb493d8 --- /dev/null +++ b/tools/hooks/README.md @@ -0,0 +1,41 @@ +# Git Integration Hooks + +This folder contains installable scripts for [Git hooks] and [merge drivers]. +Use of these hooks and drivers is optional and they must be installed +explicitly before they take effect. + +To install the current set of hooks, or update if new hooks are added, run +`install.bat` (Windows) or `install.sh` (Unix-like) as appropriate. + +Hooks expect a Unix-like environment on the backend. Usually this is handled +automatically by GUI tools like TortoiseGit and GitHub for Windows, but +[Git for Windows] is an option if you prefer to use a CLI even on Windows. + +## Current Hooks + +* **Pre-commit**: Runs [mapmerge2] on changed maps, if any. +* **DMI merger**: Attempts to [fix icon conflicts] when performing a git merge. + If it succeeds, the file is marked merged. If it fails, it logs what states + are still in conflict and adds them to the .dmi file, where the desired + resolution can be chosen. + +## Adding New Hooks + +New [Git hooks] may be added by creating a file named `.hook` in +this directory. Git determines what hooks are available and what their names +are. The install script copies the `.hook` file into `.git/hooks`, so editing +the `.hook` file will require a reinstall. + +New [merge drivers] may be added by adding a shell script named `.merge` +and updating `.gitattributes` in the root of the repository to include the line +`*. merge=`. The install script will set up the merge driver to point +to the `.merge` file directly, and editing it will not require a reinstall. + +`tools/hooks/python.sh` may be used as a trampoline to ensure that the correct +version of Python is found. + +[Git hooks]: https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks +[merge drivers]: https://git-scm.com/docs/gitattributes#_performing_a_three_way_merge +[Git for Windows]: https://gitforwindows.org/ +[mapmerge2]: ../mapmerge2/README.md +[fix icon conflicts]: ../mapmerge2/merge_driver_dmi.py diff --git a/tools/hooks/dmi.merge b/tools/hooks/dmi.merge new file mode 100644 index 0000000000..4e2717867e --- /dev/null +++ b/tools/hooks/dmi.merge @@ -0,0 +1,2 @@ +#!/bin/bash +exec tools/hooks/python.sh -m merge_driver_dmi "$@" diff --git a/tools/hooks/install.bat b/tools/hooks/install.bat new file mode 100644 index 0000000000..7a11129a2a --- /dev/null +++ b/tools/hooks/install.bat @@ -0,0 +1,16 @@ +@echo off +cd %~dp0 +for %%f in (*.hook) do ( + echo Installing hook: %%~nf + copy %%f ..\..\.git\hooks\%%~nf >nul +) +for %%f in (*.merge) do ( + echo Installing merge driver: %%~nf + echo [merge "%%~nf"]^ + + driver = tools/hooks/%%f %%P %%O %%A %%B %%L >> ..\..\.git\config +) +echo Installing Python dependencies +python -m pip install -r ..\mapmerge2\requirements.txt +echo Done +pause diff --git a/tools/hooks/install.sh b/tools/hooks/install.sh new file mode 100644 index 0000000000..ccc4cf5227 --- /dev/null +++ b/tools/hooks/install.sh @@ -0,0 +1,15 @@ +#!/bin/bash +set -e +shopt -s nullglob +cd "$(dirname "$0")" +for f in *.hook; do + echo Installing hook: ${f%.hook} + cp $f ../../.git/hooks/${f%.hook} +done +for f in *.merge; do + echo Installing merge driver: ${f%.merge} + git config --replace-all merge.${f%.merge}.driver "tools/hooks/$f %P %O %A %B %L" +done +echo Installing Python dependencies +./python.sh -m pip install -r ../mapmerge2/requirements.txt +echo "Done" diff --git a/tools/hooks/pre-commit.hook b/tools/hooks/pre-commit.hook new file mode 100644 index 0000000000..7eccda6f58 --- /dev/null +++ b/tools/hooks/pre-commit.hook @@ -0,0 +1,2 @@ +#!/bin/bash +exec tools/hooks/python.sh -m precommit diff --git a/tools/hooks/python.sh b/tools/hooks/python.sh new file mode 100644 index 0000000000..32557070f4 --- /dev/null +++ b/tools/hooks/python.sh @@ -0,0 +1,17 @@ +#!/bin/bash +set -e +if command -v python3 >/dev/null 2>&1; then + PY=python3 +else + PY=python +fi +PATHSEP=$($PY - <<'EOF' +import sys, os +if sys.version_info.major != 3 or sys.version_info.minor < 6: + sys.stderr.write("Python 3.6+ is required: " + sys.version + "\n") + exit(1) +print(os.pathsep) +EOF +) +export PYTHONPATH=tools/mapmerge2/${PATHSEP}${PYTHONPATH} +$PY "$@"