diff --git a/cabal2nix/cabal2nix.cabal b/cabal2nix/cabal2nix.cabal index 35964acb..81832c85 100644 --- a/cabal2nix/cabal2nix.cabal +++ b/cabal2nix/cabal2nix.cabal @@ -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 diff --git a/cabal2nix/src/Distribution/Nixpkgs/Haskell/Hackage.hs b/cabal2nix/src/Distribution/Nixpkgs/Haskell/Hackage.hs index 4ed8aa50..9e52beb4 100644 --- a/cabal2nix/src/Distribution/Nixpkgs/Haskell/Hackage.hs +++ b/cabal2nix/src/Distribution/Nixpkgs/Haskell/Hackage.hs @@ -1,6 +1,7 @@ module Distribution.Nixpkgs.Haskell.Hackage ( HackageDB, PackageData, VersionData(..) , hackageTarball, readTarball, parsePackageData + , latestPreferredVersion ) where @@ -23,9 +24,18 @@ 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 @@ -33,13 +43,14 @@ readTarball ts p = do 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) diff --git a/cabal2nix/src/Distribution/Nixpkgs/Haskell/PackageSourceSpec.hs b/cabal2nix/src/Distribution/Nixpkgs/Haskell/PackageSourceSpec.hs index f08ea37b..282c3284 100644 --- a/cabal2nix/src/Distribution/Nixpkgs/Haskell/PackageSourceSpec.hs +++ b/cabal2nix/src/Distribution/Nixpkgs/Haskell/PackageSourceSpec.hs @@ -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) diff --git a/hackage-db/CHANGELOG.md b/hackage-db/CHANGELOG.md index fa76e46a..8efe62ab 100644 --- a/hackage-db/CHANGELOG.md +++ b/hackage-db/CHANGELOG.md @@ -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 diff --git a/hackage-db/example/show-package-versions.hs b/hackage-db/example/show-package-versions.hs index 7db81dfa..4f34f74f 100644 --- a/hackage-db/example/show-package-versions.hs +++ b/hackage-db/example/show-package-versions.hs @@ -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) diff --git a/hackage-db/hackage-db.cabal b/hackage-db/hackage-db.cabal index e53a71ce..c6dd0e4e 100644 --- a/hackage-db/hackage-db.cabal +++ b/hackage-db/hackage-db.cabal @@ -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 diff --git a/hackage-db/src/Distribution/Hackage/DB.hs b/hackage-db/src/Distribution/Hackage/DB.hs index 5e096c10..85d86001 100644 --- a/hackage-db/src/Distribution/Hackage/DB.hs +++ b/hackage-db/src/Distribution/Hackage/DB.hs @@ -5,7 +5,7 @@ -} module Distribution.Hackage.DB - ( HackageDB, PackageData, VersionData(..) + ( HackageDB, PackageData(..), VersionData(..) , readTarball, parseTarball, hackageTarball ) where diff --git a/hackage-db/src/Distribution/Hackage/DB/Parsed.hs b/hackage-db/src/Distribution/Hackage/DB/Parsed.hs index c4dec644..934fb83f 100644 --- a/hackage-db/src/Distribution/Hackage/DB/Parsed.hs +++ b/hackage-db/src/Distribution/Hackage/DB/Parsed.hs @@ -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) @@ -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