MikeH
MikeH

Reputation: 103

Pre-receive hook, Bash + Git

Trying to write a pre-receive hook for a bitbucket server repo.

The repo consists of only json files:

default.json
/subdirectory/overwrite.json

The default.json file has a series of key/value pairs that the overwrite.json file should have an exact duplicate of key but not value.

ie: default.json = { myKey:"someValue"} , overwrite.json = { myKey: "someOtherValue" }

when a dev commits "overwrite.json", I need the pre-receive to compare the file to what is on the server to ensure that the keys match (cannot have a key/value that is not defined in default.json)

Here is the pre-receive hook code so far:

#>******************************************************
while read line
do
    echo "[INFO] Reading in stdin"
    # if line is not empty
    if [[ -n "${line// }" ]]; then
        # Split the line into an array.
        IFS=' ' read -r -a array <<< "$line"
        # This is the standard Git behaviour for pre-receive:
        parentsha=${array[0]}
        currentsha=${array[1]}
        ref=${array[2]}
        echo "[INFO] "
        echo "[INFO] Current line: "
        echo "[INFO] > Parent sha: $parentsha"
        echo "[INFO] > Current sha: $currentsha"
        echo "[INFO] Ref: $ref"
    fi
done
git show
echo "[INFO] END of pre-receive script 21"
exit 0

The above code produces the sha values for the change, and I can see the actual change of the file(s), but I'm kind of lost from here on to read in the actual committed files and how to compare the files to what is on the server

Upvotes: 2

Views: 87

Answers (1)

larsks
larsks

Reputation: 312650

While it's possible to solve this with a Bash script, you'll need an external tool like jq to parse your JSON files to extract the keys. It would probably be easier to use another language (Python, Perl, Ruby, whatever) that has a native JSON parser.

Anyway, here's one way of solving it. In the code below:

  • We use mapfile to extract the list of keys in default.json into an array variable default
  • We use mapfile to extract the list of keys in subdirectory/overwrite.json into an array variable overrides
  • We iterate over the list of keys in $overrides, checking each one against the list of keys in $default.
#!/bin/bash

while read -r -a ref; do
    mapfile -t default <<< $(git show ${ref[1]}:default.json | jq -r 'keys[]')
    mapfile -t overrides <<< $(git show ${ref[1]}:subdirectory/overwrite.json | jq -r 'keys[]')

    for key in "${overrides[@]}"; do
        found=0
        for defkey in "${default[@]}"; do
            if [[ $defkey = $key ]]; then
                found=1
                break
            fi
        done

        if [[ $found -ne 1 ]]; then
            echo "ERROR: key $key not in default.json" >&2
            exit 1
        fi
    done
done

Upvotes: 2

Related Questions