[infra] Add pre-commit hook to run flatten_buildbucket_cfg.

This will make it easy to keep the generated files up to date.

Bug: IN-702 #comment
Change-Id: Ia8274989b40a21b8f5cf40b13b2aeabe061082ab
diff --git a/infra b/infra
index 46b21f9..22131d3 100644
--- a/infra
+++ b/infra
@@ -17,7 +17,8 @@
     <project name="fuchsia-infra/config"
              path="fuchsia-infra/config"
              remote="https://fuchsia.googlesource.com/infra/config"
-             gerrithost="https://fuchsia-review.googlesource.com"/>
+             gerrithost="https://fuchsia-review.googlesource.com"
+             githooks="manifest/infra-git-hooks"/>
     <project name="fuchsia-infra/prebuilt"
              path="fuchsia-infra/prebuilt"
              remote="https://fuchsia.googlesource.com/infra/prebuilt"
diff --git a/infra-git-hooks/pre-commit b/infra-git-hooks/pre-commit
new file mode 100755
index 0000000..471d8df
--- /dev/null
+++ b/infra-git-hooks/pre-commit
@@ -0,0 +1,50 @@
+#!/usr/bin/env bash
+set -o errexit
+set -o pipefail
+set -o xtrace
+
+# Updates generated configs if source configs have been modified.
+
+generated_file() {
+  echo "${1}" | sed "s:services/\(cr-buildbucket.*\.cfg\):services/generated/\1:"
+}
+
+# Assume directory layout as created by infra manifest, and CWD is inside a
+# config dir, like fuchsia-infra/config.
+FLATTEN_TOOL="../../fuchsia-infra/prebuilt/tools/flatten_buildbucket_cfg/flatten_buildbucket_cfg"
+if [[ ! -x "${FLATTEN_TOOL}" ]]; then
+  echo "Expected the following path to be an executable file, but it's not: ${FLATTEN_TOOL}"
+  exit 1
+fi
+
+# STATUS_FILES is an array where each element is:
+# "STATUS FILE_PATH", where STATUS is one of the args to --diff-filter.
+# https://git-scm.com/docs/git-diff#git-diff---diff-filterACDMRTUXB82308203
+mapfile -t STATUS_FILES < <(git diff --cached --name-status --diff-filter=AMDR)
+
+for STATUS_FILE in "${STATUS_FILES[@]}"; do
+  # Split "STATUS FILE_PATH" into an array of >= 2 elements.
+  read -r -a STATUS_FILE_ARR <<< ${STATUS_FILE}
+  STATUS=${STATUS_FILE_ARR[0]}
+  FILE=${STATUS_FILE_ARR[1]}
+  if [[ "${FILE}" == services/cr-buildbucket*.cfg ]]; then
+    GENERATED_FILE=$(generated_file ${FILE})
+    if [[ "${STATUS}" == D && -e "${GENERATED_FILE}" ]]; then
+      rm "${GENERATED_FILE}"
+      git add "${GENERATED_FILE}"
+    elif [[ "${STATUS}" == R* ]]; then
+      [[ -e "${GENERATED_FILE}" ]] && git rm "${GENERATED_FILE}"
+      # If it's a rename, STATUS_FILE_ARR should have a 3rd element:
+      # the new name of the file.
+      # Proceed as if we're adding the new name of the file.
+      FILE=${STATUS_FILE_ARR[2]}
+      GENERATED_FILE=$(generated_file ${FILE})
+      STATUS="A"
+    fi
+    if [[ "${STATUS}" =~ [AM] ]]; then
+      mkdir -p $(dirname "${GENERATED_FILE}")
+      "${FLATTEN_TOOL}" "${FILE}" > "${GENERATED_FILE}"
+      git add "${GENERATED_FILE}"
+    fi
+  fi
+done