mirror of
https://github.com/commercialhaskell/stackage-server.git
synced 2026-01-12 12:18:29 +01:00
108 lines
3.9 KiB
Haskell
108 lines
3.9 KiB
Haskell
module Data.Hackage.Views where
|
|
|
|
import ClassyPrelude.Yesod
|
|
import Distribution.Package
|
|
import Distribution.PackageDescription
|
|
import Distribution.Version (anyVersion, intersectVersionRanges, earlierVersion, Version (..), simplifyVersionRange, VersionRange (..))
|
|
import Distribution.Text (simpleParse)
|
|
import Types hiding (Version (..))
|
|
import qualified Types
|
|
import Model
|
|
import Data.NonNull (fromNullable) -- FIXME expose from ClassyPrelude
|
|
import Data.Hackage (UploadHistory)
|
|
|
|
viewUnchanged :: Monad m
|
|
=> packageName -> version -> time
|
|
-> GenericPackageDescription
|
|
-> m GenericPackageDescription
|
|
viewUnchanged _ _ _ = return
|
|
|
|
helper :: Monad m
|
|
=> (Dependency -> m Dependency)
|
|
-> GenericPackageDescription
|
|
-> m GenericPackageDescription
|
|
helper f0 gpd = do
|
|
a <- mapM (go f0) $ condLibrary gpd
|
|
b <- mapM (go2 f0) $ condExecutables gpd
|
|
c <- mapM (go2 f0) $ condTestSuites gpd
|
|
d <- mapM (go2 f0) $ condBenchmarks gpd
|
|
return gpd
|
|
{ condLibrary = a
|
|
, condExecutables = b
|
|
, condTestSuites = c
|
|
, condBenchmarks = d
|
|
}
|
|
where
|
|
go2 f (x, y) = do
|
|
y' <- go f y
|
|
return (x, y')
|
|
|
|
go :: Monad m
|
|
=> (Dependency -> m Dependency)
|
|
-> CondTree ConfVar [Dependency] a
|
|
-> m (CondTree ConfVar [Dependency] a)
|
|
go f (CondNode a constraints comps) = do
|
|
constraints' <- mapM f constraints
|
|
comps' <- mapM (goComp f) comps
|
|
return $ CondNode a constraints' comps'
|
|
|
|
goComp :: Monad m
|
|
=> (Dependency -> m Dependency)
|
|
-> (condition, CondTree ConfVar [Dependency] a, Maybe (CondTree ConfVar [Dependency] a))
|
|
-> m (condition, CondTree ConfVar [Dependency] a, Maybe (CondTree ConfVar [Dependency] a))
|
|
goComp f (condition, tree, mtree) = do
|
|
tree' <- go f tree
|
|
mtree' <- mapM (go f) mtree
|
|
return (condition, tree', mtree')
|
|
|
|
viewNoBounds :: Monad m
|
|
=> packageName -> version -> time
|
|
-> GenericPackageDescription
|
|
-> m GenericPackageDescription
|
|
viewNoBounds _ _ _ =
|
|
helper go
|
|
where
|
|
go (Dependency name _range) = return $ Dependency name anyVersion
|
|
|
|
getAvailable name maxUploaded =
|
|
map fst . filter ((<= maxUploaded) . snd) . mapToList . fromMaybe mempty . lookup name
|
|
|
|
viewPVP :: Monad m
|
|
=> UploadHistory
|
|
-> packageName -> version -> UTCTime
|
|
-> GenericPackageDescription
|
|
-> m GenericPackageDescription
|
|
viewPVP uploadHistory _ _ uploaded =
|
|
helper go
|
|
where
|
|
wiredIn = asSet $ setFromList $ words "base ghc template-haskell"
|
|
|
|
toStr (Distribution.Package.PackageName name) = name
|
|
|
|
go (Dependency name _) | toStr name `member` wiredIn = return $ Dependency name anyVersion
|
|
go orig@(Dependency _ range) | hasUpperBound range = return orig
|
|
go orig@(Dependency nameO@(toStr -> name) range) = do
|
|
let available = getAvailable (fromString name) uploaded uploadHistory
|
|
case fromNullable $ mapMaybe (simpleParse . unpack . toPathPiece) available of
|
|
Nothing -> return orig
|
|
Just vs ->
|
|
case pvpBump $ maximum vs of
|
|
Nothing -> return orig
|
|
Just v -> return
|
|
$ Dependency nameO
|
|
$ simplifyVersionRange
|
|
$ intersectVersionRanges range
|
|
$ earlierVersion v
|
|
|
|
pvpBump (Version (x:y:_) _) = Just $ Version [x, y + 1] []
|
|
pvpBump _ = Nothing
|
|
|
|
hasUpperBound AnyVersion = False
|
|
hasUpperBound ThisVersion{} = True
|
|
hasUpperBound LaterVersion{} = False
|
|
hasUpperBound EarlierVersion{} = True
|
|
hasUpperBound WildcardVersion{} = True
|
|
hasUpperBound (UnionVersionRanges x y) = hasUpperBound x && hasUpperBound y
|
|
hasUpperBound (IntersectVersionRanges x y) = hasUpperBound x || hasUpperBound y
|
|
hasUpperBound (VersionRangeParens x) = hasUpperBound x
|