forked from NixOS/cabal2nix
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathHackageGit.hs
More file actions
71 lines (61 loc) · 2.56 KB
/
Copy pathHackageGit.hs
File metadata and controls
71 lines (61 loc) · 2.56 KB
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
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TemplateHaskell #-}
module HackageGit
( Hackage, readHackage, readPackage, readPackageMeta
, SHA256Hash, hashes
)
where
import Control.Lens hiding ( (<.>) )
import Control.Monad
import Data.Aeson
import qualified Data.ByteString.Char8 as BS
import Data.Map as Map
import Data.Set as Set
import Data.String
import Distribution.Nixpkgs.Hashes
import Distribution.Nixpkgs.Haskell.OrphanInstances ( )
import Distribution.Package
import Distribution.PackageDescription
import Distribution.PackageDescription.Parsec ( parseGenericPackageDescriptionMaybe )
import Distribution.Text
import Distribution.Version
import OpenSSL.Digest ( digest, digestByName )
import System.Directory
import System.FilePath
type Hackage = Map PackageName (Set Version)
readHackage :: FilePath -> IO Hackage
readHackage path = getSubDirs path >>= foldM discoverPackageVersions mempty
where
discoverPackageVersions :: Hackage -> String -> IO Hackage
discoverPackageVersions db pkg = do
vs <- getSubDirs (path </> pkg)
return (Map.insert (mkPackageName pkg) (Set.fromList (Prelude.map fromString vs)) db)
getSubDirs :: FilePath -> IO [FilePath]
getSubDirs path = do
let isDirectory p = doesDirectoryExist (path </> p)
getDirectoryContents path >>= filterM isDirectory . Prelude.filter (\x -> head x /= '.')
type SHA256Hash = String
readPackage :: FilePath -> PackageIdentifier -> IO (GenericPackageDescription, SHA256Hash)
readPackage dirPrefix (PackageIdentifier name version) = do
let cabalFile = dirPrefix </> unPackageName name </> display version </> unPackageName name <.> "cabal"
buf <- BS.readFile cabalFile
cabal <- case parseGenericPackageDescriptionMaybe buf of
Just a -> return a
Nothing -> fail ("cannot parse cabal file " ++ cabalFile)
return (cabal, printSHA256 (digest (digestByName "sha256") buf))
declareLenses [d|
data Meta = Meta { hashes :: Map String String
}
deriving (Show)
|]
instance FromJSON Meta where
parseJSON (Object v) = Meta
<$> v .: "package-hashes"
parseJSON o = fail ("invalid Cabal metadata: " ++ show o)
readPackageMeta :: FilePath -> PackageIdentifier -> IO Meta
readPackageMeta dirPrefix (PackageIdentifier name version) = do
let metaFile = dirPrefix </> unPackageName name </> display version </> unPackageName name <.> "json"
buf <- BS.readFile metaFile
case eitherDecodeStrict buf of
Left msg -> fail (metaFile ++ ": " ++ msg)
Right x -> return $ over (hashes . ix "SHA256") (printSHA256 . packHex) x