1{-# LANGUAGE OverloadedStrings #-}
2{-# LANGUAGE TemplateHaskell #-}
6import Control.Lens hiding ( (<.>) )
9import Data.ByteString.Char8 ( ByteString )
10import qualified Data.ByteString.Char8 as BS
14import Data.String.UTF8 ( toString, fromRep )
15import Distribution.Nixpkgs.Hashes
16import Distribution.Nixpkgs.Haskell.OrphanInstances ( )
17import Distribution.Package
18import Distribution.PackageDescription
19import Distribution.PackageDescription.Parse ( parseGenericPackageDescription, ParseResult(..) )
20import Distribution.Text
21import Distribution.Version
22import OpenSSL.Digest ( digest, digestByName )
23import System.Directory
26type Hackage = Map PackageName (Set Version)
28readHackage :: FilePath -> IO Hackage
29readHackage path = getSubDirs path >>= foldM discoverPackageVersions mempty
31 discoverPackageVersions :: Hackage -> String -> IO Hackage
32 discoverPackageVersions db pkg = do
33 vs <- getSubDirs (path </> pkg)
34 return (Map.insert (mkPackageName pkg) (Set.fromList (Prelude.map fromString vs)) db)
36getSubDirs :: FilePath -> IO [FilePath]
38 let isDirectory p = doesDirectoryExist (path </> p)
39 getDirectoryContents path >>= filterM isDirectory . Prelude.filter (\x -> head x /= '.')
41decodeUTF8 :: ByteString -> String
42decodeUTF8 = toString . fromRep
44type SHA256Hash = String
46readPackage :: FilePath -> PackageIdentifier -> IO (GenericPackageDescription, SHA256Hash)
47readPackage dirPrefix (PackageIdentifier name version) = do
48 let cabalFile = dirPrefix </> unPackageName name </> display version </> unPackageName name <.> "cabal"
49 buf <- BS.readFile cabalFile
50 cabal <- case parseGenericPackageDescription (decodeUTF8 buf) of
51 ParseOk _ a -> return a
52 ParseFailed err -> fail (cabalFile ++ ": " ++ show err)
53 return (cabal, printSHA256 (digest (digestByName "sha256") buf))
56 data Meta = Meta { hashes :: Map String String
57 , locations :: [String]
63instance FromJSON Meta where
64 parseJSON (Object v) = Meta
65 <$> v .: "package-hashes"
66 <*> v .: "package-locations"
67 <*> v .: "package-size"
68 parseJSON o = fail ("invalid Cabal metadata: " ++ show o)
70readPackageMeta :: FilePath -> PackageIdentifier -> IO Meta
71readPackageMeta dirPrefix (PackageIdentifier name version) = do
72 let metaFile = dirPrefix </> unPackageName name </> display version </> unPackageName name <.> "json"
73 buf <- BS.readFile metaFile
74 case eitherDecodeStrict buf of
75 Left msg -> fail (metaFile ++ ": " ++ msg)
76 Right x -> return $ over (hashes . ix "SHA256") (printSHA256 . packHex) x
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list