about summary refs log tree commit diff
path: root/pkgs/build-support/setup-hooks/set-source-date-epoch-to-latest.sh
blob: a9a0dc689086ca9bb182cbbf37fe9e2a386596c3 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
updateSourceDateEpoch() {
    local path="$1"
    # Avoid passing option-looking directory to find. The example is diffoscope-269:
    #   https://salsa.debian.org/reproducible-builds/diffoscope/-/issues/378
    [[ $path == -* ]] && path="./$path"

    # Get the last modification time of all regular files, sort them,
    # and get the most recent. Maybe we should use
    # https://github.com/0-wiz-0/findnewest here.
    local -a res=($(find "$path" -type f -not -newer "$NIX_BUILD_TOP/.." -printf '%T@ %p\0' \
                    | sort -n --zero-terminated | tail -n1 --zero-terminated | head -c -1))
    local time="${res[0]//\.[0-9]*/}" # remove the fraction part
    local newestFile="${res[1]}"

    # Update $SOURCE_DATE_EPOCH if the most recent file we found is newer.
    if [ "${time:-0}" -gt "$SOURCE_DATE_EPOCH" ]; then
        echo "setting SOURCE_DATE_EPOCH to timestamp $time of file $newestFile"
        export SOURCE_DATE_EPOCH="$time"

        # Warn if the new timestamp is too close to the present. This
        # may indicate that we were being applied to a file generated
        # during the build, or that an unpacker didn't restore
        # timestamps properly.
        local now="$(date +%s)"
        if [ "$time" -gt $((now - 60)) ]; then
            echo "warning: file $newestFile may be generated; SOURCE_DATE_EPOCH may be non-deterministic"
        fi
    fi
}

postUnpackHooks+=(_updateSourceDateEpochFromSourceRoot)

_updateSourceDateEpochFromSourceRoot() {
    if [ -n "$sourceRoot" ]; then
        updateSourceDateEpoch "$sourceRoot"
    fi
}