mirror of
https://github.com/cdepillabout/stacklock2nix.git
synced 2024-10-04 01:48:25 +03:00
Merge pull request #42 from TeofilC/wip/casa
Fetch cabal file revisions from casa
This commit is contained in:
commit
8d5111af35
@ -185,12 +185,14 @@ let
|
||||
# file.
|
||||
resolverParsed = readYAML resolverRawYaml;
|
||||
|
||||
fetchCabalFileRevision =
|
||||
let
|
||||
args =
|
||||
lib.optionalAttrs (all-cabal-hashes != null) { inherit all-cabal-hashes; };
|
||||
in
|
||||
callPackage ./fetchCabalFileRevision.nix args;
|
||||
# Fetch cabal revisions from the stackage content addressable store.
|
||||
fetchCabalFileRevision = {name, version, hash}:
|
||||
fetchurl {
|
||||
pname = "${name}-cabal";
|
||||
inherit version;
|
||||
url = "https://casa.stackage.org/${hash}";
|
||||
sha256 = hash;
|
||||
};
|
||||
|
||||
# Replace the `.cabal` file in a given Haskell package with the revision
|
||||
# specified by the given hash.
|
||||
|
@ -1,50 +0,0 @@
|
||||
|
||||
{ all-cabal-hashes, curl, coreutils, lib, stdenvNoCC, writeShellScript }:
|
||||
|
||||
# Fetch the revision of a `.cabal` file for a given Haskell package from
|
||||
# Hackage.
|
||||
|
||||
{ # Haskell package.
|
||||
#
|
||||
# name :: String
|
||||
#
|
||||
# Example: `"lens"`
|
||||
name
|
||||
, # Version
|
||||
#
|
||||
# version :: String
|
||||
#
|
||||
# Example: `"5.0.1"`
|
||||
version
|
||||
, # Hash of the revised `.cabal` file from Hackage.
|
||||
#
|
||||
# hash :: String
|
||||
#
|
||||
# Example: "63ed57e4d54c583ae2873d6892ef690942d90030864d0b772413a1458e98159f"
|
||||
hash
|
||||
}:
|
||||
|
||||
stdenvNoCC.mkDerivation {
|
||||
|
||||
name = "${name}-${version}-cabal-file";
|
||||
|
||||
outputHashAlgo = "sha256";
|
||||
outputHash = hash;
|
||||
outputHashMode = "flat";
|
||||
|
||||
nativeBuildInputs = [
|
||||
coreutils # TODO: needed for seq. remove this dependency.
|
||||
curl
|
||||
];
|
||||
|
||||
nixpkgsVersion = lib.trivial.release;
|
||||
|
||||
builder = ./fetchCabalFileRevisionBuilder.sh;
|
||||
|
||||
# Arguments used in builder script.
|
||||
|
||||
haskPkgName = name;
|
||||
haskPkgVer = version;
|
||||
haskPkgHash = hash;
|
||||
all_cabal_hashes = all-cabal-hashes;
|
||||
}
|
@ -1,136 +0,0 @@
|
||||
|
||||
# This script gets the following arguments:
|
||||
#
|
||||
# $haskPkgName: The name of the haskell package to look for.
|
||||
#
|
||||
# $haskPkgVer: The version of the haskell package to look for.
|
||||
#
|
||||
# $haskPkgHash: The hash of the specific revision of the .cabal file to look for.
|
||||
#
|
||||
# $all_cabal_hashes: A path to the all-cabal-hashes derivation.
|
||||
|
||||
source $stdenv/setup
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Try to extract the .cabal file for the given revision
|
||||
#
|
||||
# Arguments:
|
||||
# (none)
|
||||
#
|
||||
# Returns:
|
||||
# 0: If the given .cabal revision was found in the tarball.
|
||||
# non-zero: If the given .cabal revision was not found in the tarball.
|
||||
#
|
||||
# Side effects:
|
||||
# Creates the file "./${haskPkgName}.cabal" if the given revision was found
|
||||
# in the tarball.
|
||||
find_cabal_file_in_all_cabal_hashes () {
|
||||
if [ -d "${all_cabal_hashes}" ]; then
|
||||
# all-cabal-hashes is a directory. Directly reference the .cabal file need.
|
||||
cp "${all_cabal_hashes}/${haskPkgName}/${haskPkgVer}/${haskPkgName}.cabal" ./
|
||||
else
|
||||
# all-cabal-hashes is a tarball. Try to pull out the .cabal file we need.
|
||||
tar --wildcards --extract --file "${all_cabal_hashes}" \
|
||||
--gzip --strip-components=3 "*/${haskPkgName}/${haskPkgVer}/${haskPkgName}.cabal"
|
||||
fi
|
||||
}
|
||||
|
||||
# Test the hash of the file "./${haskPkgName}.cabal" to see if it is equal to
|
||||
# the passed-in hash.
|
||||
#
|
||||
# Arguments:
|
||||
# (none)
|
||||
#
|
||||
# Returns:
|
||||
# 0: If the hashes are equal.
|
||||
# non-zero: If the hashes are not equal
|
||||
#
|
||||
# Side effects:
|
||||
# (none)
|
||||
test_hash () {
|
||||
fileSha=$(sha256sum "${haskPkgName}.cabal" | cut -d' ' -f1)
|
||||
[[ "$fileSha" == "${haskPkgHash}" ]]
|
||||
}
|
||||
|
||||
# Copies the "./${haskPkgName}.cabal" file to "$out" and exits.
|
||||
#
|
||||
# Arguments:
|
||||
# (none)
|
||||
#
|
||||
# Returns:
|
||||
# (none)
|
||||
#
|
||||
# Side effects:
|
||||
# Exits
|
||||
copy_cabal_file_to_out_and_exit () {
|
||||
cp "${haskPkgName}.cabal" "$out"
|
||||
exit 0
|
||||
}
|
||||
|
||||
# TODO: check if all-cabal-hashes is a directory, and don't do this in that case
|
||||
|
||||
|
||||
# This will look for the given revision of the cabal file in
|
||||
# all-cabal-hashes. This will loop while incrementing the revision ID to
|
||||
# look for.
|
||||
#
|
||||
# If a .cabal file is found with the correct hash, it is used. Otherwise,
|
||||
# this loop ends when there are no more revision IDs available for the
|
||||
# package/version.
|
||||
if find_cabal_file_in_all_cabal_hashes; then
|
||||
# We successfully extracted the tar file, now we see if it has the
|
||||
# correct hash.
|
||||
if test_hash ; then
|
||||
# The file has the correct hash
|
||||
copy_cabal_file_to_out_and_exit
|
||||
fi
|
||||
|
||||
# Remove the .cabal file because the hash doesn't match.
|
||||
rm "${haskPkgName}.cabal"
|
||||
fi
|
||||
|
||||
echo "Couldn't find .cabal file revision for ${haskPkgName}-${haskPkgVer} in all-cabal-hashes. Fetching from Hackage..."
|
||||
|
||||
curlVersion=$(curl -V | head -1 | cut -d' ' -f2)
|
||||
|
||||
curl=(
|
||||
curl
|
||||
--location
|
||||
--max-redirs 20
|
||||
--retry 3
|
||||
--disable-epsv
|
||||
--cookie-jar cookies
|
||||
--user-agent "curl/$curlVersion Nixpkgs/$nixpkgsVersion"
|
||||
--insecure
|
||||
)
|
||||
|
||||
# This is pretty dumb.
|
||||
#
|
||||
# The snapshot/resolver specified in a stack.yaml contains the hash of the
|
||||
# revised `.cabal` file that should be used for each package, but it
|
||||
# doesn't contain the _number_ of the revision the hash belongs to.
|
||||
# Unfortunately, Hackage only provides a way to download a `.cabal` file
|
||||
# based on a revision number (not a revised `.cabal` file given a hash).
|
||||
#
|
||||
# So the following code attempts to download each revised `.cabal` file for
|
||||
# a version of a package, one-by-one, hash it, and check whether the hash
|
||||
# matches the hash we are looking for. If it does, we're good to go.
|
||||
#
|
||||
# In theory, this should always succeed, since the Stackage snapshots
|
||||
# will only reference `.cabal` file revisions from Hackage. In practice,
|
||||
# I've never seen this fail to find a revision, but who knows what weird
|
||||
# things go on in the edge-cases of Hackage.
|
||||
|
||||
for hackageRevisionId in $(seq 0 20) ; do
|
||||
echo "$hackageRevisionId"
|
||||
revisionUrl="https://hackage.haskell.org/package/${haskPkgName}-${haskPkgVer}/revision/${hackageRevisionId}.cabal"
|
||||
"${curl[@]}" -L "$revisionUrl" > "${haskPkgName}.cabal"
|
||||
if test_hash ; then
|
||||
copy_cabal_file_to_out_and_exit
|
||||
fi
|
||||
rm "${haskPkgName}.cabal"
|
||||
done
|
||||
|
||||
echo "ERROR: Could not find cabal file revision for ${haskPkgName}-${haskPkgVer} with hash ${haskPkgHash} in Hackage"
|
||||
exit 1
|
Loading…
Reference in New Issue
Block a user