mirror of
https://github.com/commercialhaskell/stackage-server.git
synced 2026-01-22 08:51:55 +01:00
Add deprecation info to stackage (#42)
This commit is contained in:
parent
b4578da0ba
commit
b06424463e
@ -67,6 +67,7 @@ import Handler.PackageList
|
|||||||
import Handler.CompressorStatus
|
import Handler.CompressorStatus
|
||||||
import Handler.Tag
|
import Handler.Tag
|
||||||
import Handler.BannedTags
|
import Handler.BannedTags
|
||||||
|
import Handler.RefreshDeprecated
|
||||||
|
|
||||||
-- This line actually creates our YesodDispatch instance. It is the second half
|
-- This line actually creates our YesodDispatch instance. It is the second half
|
||||||
-- of the call to mkYesodData which occurs in Foundation.hs. Please see the
|
-- of the call to mkYesodData which occurs in Foundation.hs. Please see the
|
||||||
|
|||||||
49
Data/Hackage/DeprecationInfo.hs
Normal file
49
Data/Hackage/DeprecationInfo.hs
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
-- | Transforms http://hackage.haskell.org/packages/deprecated.json
|
||||||
|
-- into model data to be stored in the database.
|
||||||
|
module Data.Hackage.DeprecationInfo
|
||||||
|
( HackageDeprecationInfo(..)
|
||||||
|
) where
|
||||||
|
|
||||||
|
import Prelude
|
||||||
|
import Data.Aeson
|
||||||
|
import Model
|
||||||
|
import Types
|
||||||
|
|
||||||
|
data HackageDeprecationInfo = HackageDeprecationInfo {
|
||||||
|
deprecations :: [Deprecated],
|
||||||
|
suggestions :: [Suggested]
|
||||||
|
}
|
||||||
|
|
||||||
|
instance FromJSON HackageDeprecationInfo where
|
||||||
|
parseJSON j = do
|
||||||
|
deprecationRecords <- parseJSON j
|
||||||
|
return $ HackageDeprecationInfo {
|
||||||
|
deprecations = map toDeprecated deprecationRecords,
|
||||||
|
suggestions = concatMap toSuggestions deprecationRecords
|
||||||
|
}
|
||||||
|
|
||||||
|
data DeprecationRecord = DeprecationRecord {
|
||||||
|
deprecatedPackage :: PackageName,
|
||||||
|
deprecatedInFavourOf :: [PackageName]
|
||||||
|
}
|
||||||
|
|
||||||
|
instance FromJSON DeprecationRecord where
|
||||||
|
parseJSON j = do
|
||||||
|
obj <- parseJSON j
|
||||||
|
package <- (obj .: "deprecated-package") >>= parsePackageName
|
||||||
|
inFavourOf <- (obj .: "in-favour-of") >>= mapM parsePackageName
|
||||||
|
return $ DeprecationRecord package inFavourOf
|
||||||
|
where
|
||||||
|
parsePackageName name = return (PackageName name)
|
||||||
|
|
||||||
|
toDeprecated :: DeprecationRecord -> Deprecated
|
||||||
|
toDeprecated (DeprecationRecord deprecated _) = Deprecated deprecated
|
||||||
|
|
||||||
|
toSuggestions :: DeprecationRecord -> [Suggested]
|
||||||
|
toSuggestions (DeprecationRecord deprecated inFavourOf) =
|
||||||
|
map toSuggestion inFavourOf
|
||||||
|
where
|
||||||
|
toSuggestion favoured = Suggested {
|
||||||
|
suggestedPackage = favoured,
|
||||||
|
suggestedInsteadOf = deprecated
|
||||||
|
}
|
||||||
@ -26,7 +26,7 @@ getPackageR pn = do
|
|||||||
HaddockR ident [concat [toPathPiece pn, "-", toPathPiece version]]
|
HaddockR ident [concat [toPathPiece pn, "-", toPathPiece version]]
|
||||||
muid <- maybeAuthId
|
muid <- maybeAuthId
|
||||||
(mnightly, mlts, nLikes, liked,
|
(mnightly, mlts, nLikes, liked,
|
||||||
Entity _ metadata, revdeps', mdocs) <- runDB $ do
|
Entity _ metadata, revdeps', mdocs, deprecated, inFavourOf) <- runDB $ do
|
||||||
mnightly <- getNightly pn
|
mnightly <- getNightly pn
|
||||||
mlts <- getLts pn
|
mlts <- getLts pn
|
||||||
nLikes <- count [LikePackage ==. pn]
|
nLikes <- count [LikePackage ==. pn]
|
||||||
@ -42,6 +42,8 @@ getPackageR pn = do
|
|||||||
<$> pure version
|
<$> pure version
|
||||||
<*> (map entityVal <$>
|
<*> (map entityVal <$>
|
||||||
selectList [ModuleDocs ==. docsid] [Asc ModuleName])
|
selectList [ModuleDocs ==. docsid] [Asc ModuleName])
|
||||||
|
deprecated <- getDeprecated pn
|
||||||
|
inFavourOf <- getInFavourOf pn
|
||||||
return ( mnightly
|
return ( mnightly
|
||||||
, mlts
|
, mlts
|
||||||
, nLikes
|
, nLikes
|
||||||
@ -49,8 +51,12 @@ getPackageR pn = do
|
|||||||
, metadata
|
, metadata
|
||||||
, revdeps'
|
, revdeps'
|
||||||
, mdocs
|
, mdocs
|
||||||
|
, deprecated
|
||||||
|
, inFavourOf
|
||||||
)
|
)
|
||||||
|
|
||||||
|
let ixInFavourOf = zip [0::Int ..] inFavourOf
|
||||||
|
|
||||||
myTags <- maybe (return []) (runDB . user'sTagsOf pn) muid
|
myTags <- maybe (return []) (runDB . user'sTagsOf pn) muid
|
||||||
tags <- fmap (map (\(v,count') -> (v,count',any (==v) myTags)))
|
tags <- fmap (map (\(v,count') -> (v,count',any (==v) myTags)))
|
||||||
(runDB (packageTags pn))
|
(runDB (packageTags pn))
|
||||||
@ -146,6 +152,18 @@ getLts pn =
|
|||||||
,p ^. PackageVersion
|
,p ^. PackageVersion
|
||||||
,s ^. StackageSlug)
|
,s ^. StackageSlug)
|
||||||
|
|
||||||
|
getDeprecated :: PackageName -> YesodDB App Bool
|
||||||
|
getDeprecated pn = fmap ((>0) . length) $ E.select $ E.from $ \d -> do
|
||||||
|
E.where_ $ d ^. DeprecatedPackage E.==. E.val pn
|
||||||
|
return ()
|
||||||
|
|
||||||
|
getInFavourOf :: PackageName -> YesodDB App [PackageName]
|
||||||
|
getInFavourOf pn = fmap unBoilerplate $ E.select $ E.from $ \s -> do
|
||||||
|
E.where_ $ s ^. SuggestedInsteadOf E.==. E.val pn
|
||||||
|
return (s ^. SuggestedPackage)
|
||||||
|
where
|
||||||
|
unBoilerplate = map (\(E.Value p) -> p)
|
||||||
|
|
||||||
-- | An identifier specified in a package. Because this field has
|
-- | An identifier specified in a package. Because this field has
|
||||||
-- quite liberal requirements, we often encounter various forms. A
|
-- quite liberal requirements, we often encounter various forms. A
|
||||||
-- name, a name and email, just an email, or maybe nothing at all.
|
-- name, a name and email, just an email, or maybe nothing at all.
|
||||||
|
|||||||
20
Handler/RefreshDeprecated.hs
Normal file
20
Handler/RefreshDeprecated.hs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
module Handler.RefreshDeprecated where
|
||||||
|
|
||||||
|
import Import
|
||||||
|
import qualified Data.Aeson as Aeson
|
||||||
|
import Network.HTTP.Conduit (simpleHttp)
|
||||||
|
import Data.Hackage.DeprecationInfo
|
||||||
|
|
||||||
|
getRefreshDeprecatedR :: Handler Html
|
||||||
|
getRefreshDeprecatedR = do
|
||||||
|
bs <- simpleHttp "http://hackage.haskell.org/packages/deprecated.json"
|
||||||
|
case Aeson.decode bs of
|
||||||
|
Nothing -> return "Failed to parse"
|
||||||
|
Just info -> do
|
||||||
|
runDB $ do
|
||||||
|
deleteWhere ([] :: [Filter Deprecated])
|
||||||
|
insertMany_ (deprecations info)
|
||||||
|
runDB $ do
|
||||||
|
deleteWhere ([] :: [Filter Suggested])
|
||||||
|
insertMany_ (suggestions info)
|
||||||
|
return "Done"
|
||||||
@ -122,3 +122,12 @@ Lts
|
|||||||
minor Int
|
minor Int
|
||||||
stackage StackageId
|
stackage StackageId
|
||||||
UniqueLts major minor
|
UniqueLts major minor
|
||||||
|
|
||||||
|
Deprecated
|
||||||
|
package PackageName
|
||||||
|
UniqueDeprecated package
|
||||||
|
|
||||||
|
Suggested
|
||||||
|
package PackageName
|
||||||
|
insteadOf PackageName
|
||||||
|
UniqueSuggested package insteadOf
|
||||||
|
|||||||
@ -50,3 +50,5 @@
|
|||||||
/authors AuthorsR GET
|
/authors AuthorsR GET
|
||||||
/install InstallR GET
|
/install InstallR GET
|
||||||
/older-releases OlderReleasesR GET
|
/older-releases OlderReleasesR GET
|
||||||
|
|
||||||
|
/refresh-deprecated RefreshDeprecatedR GET
|
||||||
|
|||||||
@ -25,6 +25,7 @@ library
|
|||||||
Data.Tag
|
Data.Tag
|
||||||
Data.BlobStore
|
Data.BlobStore
|
||||||
Data.Hackage
|
Data.Hackage
|
||||||
|
Data.Hackage.DeprecationInfo
|
||||||
Data.Hackage.Views
|
Data.Hackage.Views
|
||||||
Data.WebsiteContent
|
Data.WebsiteContent
|
||||||
Types
|
Types
|
||||||
@ -49,6 +50,7 @@ library
|
|||||||
Handler.CompressorStatus
|
Handler.CompressorStatus
|
||||||
Handler.Tag
|
Handler.Tag
|
||||||
Handler.BannedTags
|
Handler.BannedTags
|
||||||
|
Handler.RefreshDeprecated
|
||||||
|
|
||||||
if flag(dev) || flag(library-only)
|
if flag(dev) || flag(library-only)
|
||||||
cpp-options: -DDEVELOPMENT
|
cpp-options: -DDEVELOPMENT
|
||||||
|
|||||||
@ -1,7 +1,19 @@
|
|||||||
$newline never
|
$newline never
|
||||||
<div .container #snapshot-home .content>
|
<div .container #snapshot-home .content :deprecated:.deprecated>
|
||||||
<div .row>
|
<div .row>
|
||||||
<div .span12>
|
<div .span12>
|
||||||
|
$if deprecated
|
||||||
|
<h1 .package-deprecation-warning>
|
||||||
|
Deprecated
|
||||||
|
$if (not $ null ixInFavourOf)
|
||||||
|
<div .in-favour-of>
|
||||||
|
In favour of
|
||||||
|
<div .in-favour-of-list>
|
||||||
|
$forall (i, pn) <- ixInFavourOf
|
||||||
|
$if i /= 0
|
||||||
|
, #
|
||||||
|
<a href="@{PackageR pn}">
|
||||||
|
#{pn}
|
||||||
<h1>
|
<h1>
|
||||||
#{pn} #
|
#{pn} #
|
||||||
<span .latest-version>
|
<span .latest-version>
|
||||||
|
|||||||
@ -224,3 +224,26 @@ h2.changes-title {
|
|||||||
div.plain-text {
|
div.plain-text {
|
||||||
white-space: pre-wrap;
|
white-space: pre-wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.deprecated {
|
||||||
|
color: #aaa;
|
||||||
|
|
||||||
|
h1,h2,h3,h4,h5,a {
|
||||||
|
color: #aaa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.package-deprecation-warning{
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
.in-favour-of {
|
||||||
|
color: #333;
|
||||||
|
|
||||||
|
.in-favour-of-list {
|
||||||
|
a {
|
||||||
|
color: #08c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user