summaryrefslogtreecommitdiffstats
path: root/pkgs/build-support/fetchfossil/nix-prefetch-fossil
blob: 32762f86425f26efa3f611bb02db7db843f41933 (plain)
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#!/bin/sh -e

url=
rev=
expHash=
hashType="${NIX_HASH_ALGO:-sha256}"

# Parse command line arguments
argi=0
argfun=""
for arg; do
    if test -z "$argfun"; then
        case $arg in
            --url) argfun=set_url;;
            --rev) argfun=set_rev;;
            --hash) argfun=set_expHash;;
            --help|-h)
                echo "Usage: nix-prefetch-fossil [options] [URL [REVISION [EXPECTED-HASH]]]"
                echo ""
                echo "Options:"
                echo "  --url URL       Fossil repository URL"
                echo "  --rev REV       Fossil revision/tag/branch (default: trunk)"
                echo "  --hash HASH     Expected hash"
                echo "  --help          Show this help message"
                exit 0
                ;;
            *)
                argi=$((argi + 1))
                case $argi in
                    1) url=$arg;;
                    2) rev=$arg;;
                    3) expHash=$arg;;
                    *) echo "Too many arguments" >&2; exit 1;;
                esac
                ;;
        esac
    else
        case $argfun in
            set_*)
                var=${argfun#set_}
                eval "$var='$arg'"
                ;;
        esac
        argfun=""
    fi
done

if test -z "$url"; then
    echo "error: URL is required" >&2
    echo "Usage: nix-prefetch-fossil [URL [REVISION [EXPECTED-HASH]]]" >&2
    exit 1
fi

# Default to trunk if no revision specified
if test -z "$rev"; then
    rev="trunk"
fi

# If the hash was given, check if we already have it in store
if test -n "$expHash"; then
    finalPath=$(nix-store --print-fixed-path --recursive "$hashType" "$expHash" fossil-archive)
    if nix-store --check-validity "$finalPath" 2> /dev/null; then
        echo "$expHash"
        exit 0
    fi
fi

# Create temporary directory for cloning
tmpPath="$(mktemp -d --tmpdir fossil-checkout-tmp-XXXXXXXX)"
cleanup() { rm -rf "$tmpPath"; }
trap cleanup EXIT

# Fossil wants to write global configuration to $HOME/.fossil
# We'll let it write to the temp directory instead
export HOME="$tmpPath"

echo "Fetching Fossil repository $url at revision $rev..." >&2

# Clone the repository
fossil clone -A $(whoami) "$url" "$tmpPath/fossil-clone.fossil" >&2

# Create directory for checkout
checkoutDir="$tmpPath/checkout"
mkdir -p "$checkoutDir"

# Open the repository at the specified revision
cd "$checkoutDir"
fossil open "$tmpPath/fossil-clone.fossil" "$rev" >&2

# Get the actual commit hash and date
checkoutLine=$(fossil info | grep ^checkout:)
# Remove 'checkout:' prefix & remove whitespace
checkoutData=$(echo "$checkoutLine" | sed 's/^checkout:[[:space:]]*//' | tr -s ' ')
# Extract fields: HASH YYYY-MM-DD HH:MM:SS UTC
actualRev=$(echo "$checkoutData" | cut -d' ' -f1)
# Get datetime parts
rawDate=$(echo "$checkoutData" | cut -d' ' -f2)
rawTime=$(echo "$checkoutData" | cut -d' ' -f3)
# Combine into ISO 8601 RFC 3339 format
actualDatetime="${rawDate}T${rawTime}Z"
cd - >/dev/null

# Remove the fossil checkout file
rm -f "$checkoutDir/.fslckout"

# Calculate the hash
hash=$(nix-hash --type "$hashType" --base32 "$checkoutDir")
echo "hash is $hash" >&2

# Add to store if we don't have an expected hash or if it matches
if test -z "$expHash" || test "$expHash" = "$hash"; then
    finalPath=$(nix-store --add-fixed --recursive "$hashType" "$checkoutDir")
    echo "path is $finalPath" >&2
elif test -n "$expHash" && test "$expHash" != "$hash"; then
    echo "error: hash mismatch for Fossil repository $url" >&2
    echo "  expected: $expHash" >&2
    echo "  actual:   $hash" >&2
    exit 1
fi

# Output JSON result
cat <<EOF
{
  "url": "$url",
  "rev": "$actualRev",
  "date": "$actualDatetime",
  "path": "$finalPath",
  "$hashType": "$hash",
  "hash": "$(nix-hash --to-sri --type $hashType $hash)"
}
EOF