Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cabal2nix/cabal2nix.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ library
, directory
, distribution-nixpkgs >= 1.7 && <1.8
, filepath
, hackage-db >= 2.0.1
, hackage-db >= 2.2.0
, hopenssl >= 2
, hpack >= 0.29.6
, language-nix
Expand Down
13 changes: 12 additions & 1 deletion cabal2nix/src/Distribution/Nixpkgs/Haskell/Hackage.hs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
module Distribution.Nixpkgs.Haskell.Hackage
( HackageDB, PackageData, VersionData(..)
, hackageTarball, readTarball, parsePackageData
, latestPreferredVersion
)
where

Expand All @@ -23,23 +24,33 @@ data VersionData = VersionData
{ cabalFile :: !GenericPackageDescription
, cabalFileSha256 :: !String
, tarballSha256 :: !(Maybe String)
, preferred :: !Bool
}
deriving (Show)

-- Look up the latest preferred version. If there are no preferred versions, use the latest one.
latestPreferredVersion :: PackageData -> Maybe VersionData
latestPreferredVersion pd
| Map.null pd = Nothing -- TODO: shouldn't happen, more specific error?
| otherwise = Just $ snd $ Map.findMax (if Map.null ppd then pd else ppd)
where
ppd = Map.filter preferred pd

readTarball :: Maybe UTCTime -> FilePath -> IO HackageDB
readTarball ts p = do
dbu <- U.readTarball ts p
let dbp = P.parseDB dbu
return (mapWithKey (parsePackageData dbu) dbp)

parsePackageData :: U.HackageDB -> PackageName -> P.PackageData -> PackageData
parsePackageData dbu pn = mapWithKey (parseVersionData (dbu ! pn))
parsePackageData dbu pn = mapWithKey (parseVersionData (dbu ! pn)) . P.versions

parseVersionData :: U.PackageData -> Version -> P.VersionData -> VersionData
parseVersionData pdu v vd = VersionData
{ cabalFile = P.cabalFile vd
, cabalFileSha256 = printSHA256 (digest (digestByName "sha256") file)
, tarballSha256 = Map.lookup "sha256" (P.tarballHashes vd)
, preferred = P.preferred vd
}
where
file = U.cabalFile (U.versions pdu ! v)
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ fromDB hackageDBIO pkg = do

lookupVersion :: DB.Map Version DB.VersionData -> Maybe DB.VersionData
-- No version is specified, pick latest one
lookupVersion m | version == nullVersion = fmap snd (listToMaybe (DB.toDescList m))
lookupVersion m | version == nullVersion = DB.latestPreferredVersion m
lookupVersion m = DB.lookup version m

readFileMay :: FilePath -> IO (Maybe String)
Expand Down
17 changes: 17 additions & 0 deletions hackage-db/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
# Revision history for hackage-db

## 2.2.0 (unreleased)

* `Distribution.Hackage.DB.Parsed.parsePackageData` no longer filters out
package versions that are not preferred. This means that the list of
available versions will no longer differ between the `Parsed` and
`Unparsed` modules. This is a **breaking change**.
To restore the old behavior, use the `preferred` field of `VersionData`
to filter the `versions` map (see below).
* `Distribution.Hackage.DB.Parsed.PackageData` has been changed from a type
alias to a sum type. Its previous content is the new `versions` field.
This is an **API breaking change**.
* `Distribution.Hackage.DB.Parsed.VersionData` gains a new field, `preferred`
which describes whether the package version in question matches the
`preferred-versions` range given also exposed via the `preferredVersions`
field of `Distribution.Hackage.DB.Parsed.PackageData`.
This is an **API breaking change**.

## 2.1.3

* `hackageTarball` / `cabalStateDir` now support overriding the cabal directory
Expand Down
2 changes: 1 addition & 1 deletion hackage-db/example/show-package-versions.hs
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ main = do
db <- hackageTarball >>= readTarball Nothing
pkgs <- getArgs
forM_ pkgs $ \pkg -> do
let vs = maybe [] Map.keys (Map.lookup (mkPackageName pkg) db)
let vs = maybe [] (Map.keys . versions) (Map.lookup (mkPackageName pkg) db)
putStrLn $ pkg ++ ": " ++ unwords (fmap display vs)
2 changes: 1 addition & 1 deletion hackage-db/hackage-db.cabal
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: hackage-db
version: 2.1.3
version: 2.2.0
synopsis: Access cabal-install's Hackage database via Data.Map
description: This library provides convenient access to the local copy of the Hackage
database that \"cabal update\" creates. Check out
Expand Down
2 changes: 1 addition & 1 deletion hackage-db/src/Distribution/Hackage/DB.hs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
-}

module Distribution.Hackage.DB
( HackageDB, PackageData, VersionData(..)
( HackageDB, PackageData(..), VersionData(..)
, readTarball, parseTarball, hackageTarball
)
where
Expand Down
17 changes: 10 additions & 7 deletions hackage-db/src/Distribution/Hackage/DB/Parsed.hs
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,14 @@ import GHC.Generics ( Generic )

type HackageDB = Map PackageName PackageData

type PackageData = Map Version VersionData
data PackageData = PackageData { versions :: !(Map Version VersionData)
, preferredVersions :: !VersionRange
}
deriving (Show, Eq, Generic)

data VersionData = VersionData { cabalFile :: !GenericPackageDescription
, tarballHashes :: !(Map String String)
, preferred :: !Bool
}
deriving (Show, Eq, Generic)

Expand All @@ -48,19 +52,18 @@ parseDB :: U.HackageDB -> HackageDB
parseDB = Map.mapWithKey parsePackageData

parsePackageData :: PackageName -> U.PackageData -> PackageData
parsePackageData pn (U.PackageData pv vs') =
parsePackageData pn (U.PackageData pv vs) =
mapException (\e -> HackageDBPackageName pn (e :: SomeException)) $
Map.mapWithKey (parseVersionData pn) $
Map.filterWithKey (\v _ -> v `withinRange` vr) vs'
PackageData (Map.mapWithKey (parseVersionData pn vr) vs) vr
where
PackageVersionConstraint _ vr
| BSS.null pv = PackageVersionConstraint pn anyVersion
| otherwise = parseBS "preferred version range" pv

parseVersionData :: PackageName -> Version -> U.VersionData -> VersionData
parseVersionData pn v (U.VersionData cf m) =
parseVersionData :: PackageName -> VersionRange -> Version -> U.VersionData -> VersionData
parseVersionData pn vr v (U.VersionData cf m) =
mapException (\e -> HackageDBPackageVersion v (e :: SomeException)) $
VersionData gpd (parseMetaData pn v m)
VersionData gpd (parseMetaData pn v m) (v `withinRange` vr)
where
gpd = fromMaybe (throw (InvalidCabalFile (show (pn,v)))) $
parseGenericPackageDescriptionMaybe cf
Expand Down
Loading