11{-# LANGUAGE RankNTypes #-}
2+ {-# LANGUAGE OverloadedRecordDot #-}
23{-# LANGUAGE RecordWildCards #-}
34{-# LANGUAGE ScopedTypeVariables #-}
5+ {-# LANGUAGE NamedFieldPuns #-}
46
57module Distribution.Server.Features.PackageInfoJSON (
68 PackageInfoJSONFeature (.. )
@@ -39,6 +41,7 @@ import Distribution.Server.Packages.Types (CabalFileText(.
3941import Distribution.Server.Framework.BackupRestore (RestoreBackup (.. ))
4042
4143import Distribution.Server.Features.PackageInfoJSON.State (PackageBasicDescription (.. ),
44+ PackageBasicDescriptionDTO (.. ),
4245 PackageVersions (.. ),
4346 PackageInfoState (.. ),
4447 GetPackageInfo (.. ),
@@ -54,8 +57,10 @@ import Data.Foldable (toList)
5457import Data.Traversable (for )
5558import qualified Data.List as List
5659import Data.Time (UTCTime )
57- import Distribution.Server.Users.Types (UserName , UserInfo (.. ))
60+ import Distribution.Server.Users.Types (UserName ( .. ) , UserInfo (.. ))
5861import Distribution.Server.Features.Users (UserFeature (lookupUserInfo ))
62+ import Data.Map (Map )
63+ import qualified Data.Map as Map
5964
6065
6166data PackageInfoJSONFeature = PackageInfoJSONFeature {
@@ -92,17 +97,18 @@ initPackageInfoJSONFeature env = do
9297 \and the values are whether the version is preferred or not"
9398 vInfo = " Get basic package information at a specific metadata revision"
9499
100+ uploaderCache = undefined
95101 jsonResources = [
96102 (Framework. extendResource (corePackagePage coreR)) {
97103 Framework. resourceDesc = [(Framework. GET , info)]
98104 , Framework. resourceGet =
99- [(" json" , servePackageBasicDescription coreR userFeature
105+ [(" json" , servePackageBasicDescription coreR uploaderCache userFeature
100106 preferred packageInfoState)]
101107 }
102108 , (Framework. extendResource (coreCabalFileRev coreR)) {
103109 Framework. resourceDesc = [(Framework. GET , vInfo)]
104110 , Framework. resourceGet =
105- [(" json" , servePackageBasicDescription coreR userFeature
111+ [(" json" , servePackageBasicDescription coreR uploaderCache userFeature
106112 preferred packageInfoState)]
107113 }
108114 ]
@@ -135,15 +141,14 @@ initPackageInfoJSONFeature env = do
135141
136142-- | Pure function for extracting basic package info from a Cabal file
137143getBasicDescription
138- :: UserName
139- -> UTCTime
144+ :: UTCTime
140145 -- ^ Time of upload
141146 -> CabalFileText
142147 -> Int
143148 -- ^ Metadata revision. This will be added to the resulting
144149 -- @PackageBasicDescription@
145150 -> Either String PackageBasicDescription
146- getBasicDescription uploader uploadedAt (CabalFileText cf) metadataRev =
151+ getBasicDescription uploadedAt (CabalFileText cf) metadataRev =
147152 let parseResult = PkgDescr. parseGenericPackageDescription (BS. toStrict cf)
148153 in case PkgDescr. runParseResult parseResult of
149154 (_, Right pkg) -> let
@@ -157,28 +162,54 @@ getBasicDescription uploader uploadedAt (CabalFileText cf) metadataRev =
157162 pbd_homepage = T. pack . fromShortText $ PkgDescr. homepage pkgd
158163 pbd_metadata_revision = metadataRev
159164 pbd_uploaded_at = uploadedAt
160- pbd_uploader = uploader
161165 in
162166 return $ PackageBasicDescription {.. }
163167 (_, Left (_, perrs)) ->
164168 let errs = List. intersperse ' \n ' $ mconcat $ for (toList perrs) $ \ err -> Parsec. showPError " " err
165169 in Left $ " Could not parse cabal file: "
166170 <> errs
167171
172+ basicDescriptionToDTO :: UserName -> PackageBasicDescription -> PackageBasicDescriptionDTO
173+ basicDescriptionToDTO uploader d =
174+ PackageBasicDescriptionDTO
175+ { license = d. pbd_license
176+ , copyright = d. pbd_copyright
177+ , synopsis = d. pbd_synopsis
178+ , description = d. pbd_description
179+ , author = d. pbd_author
180+ , homepage = d. pbd_homepage
181+ , metadata_revision = d. pbd_metadata_revision
182+ , uploaded_at = d. pbd_uploaded_at
183+ , uploader
184+ }
185+
186+ dtoToBasicDescription :: PackageBasicDescriptionDTO -> PackageBasicDescription
187+ dtoToBasicDescription dto =
188+ PackageBasicDescription
189+ { pbd_license = dto. license
190+ , pbd_copyright = dto. copyright
191+ , pbd_synopsis = dto. synopsis
192+ , pbd_description = dto. description
193+ , pbd_author = dto. author
194+ , pbd_homepage = dto. homepage
195+ , pbd_metadata_revision = dto. metadata_revision
196+ , pbd_uploaded_at = dto. uploaded_at
197+ }
168198
169199-- | Get a JSON @PackageBasicDescription@ for a particular
170200-- package/version/metadata-revision
171201-- OR
172202-- A listing of versions and their deprecation states
173203servePackageBasicDescription
174204 :: CoreResource
205+ -> Map PackageIdentifier UserName
175206 -> UserFeature
176207 -> Preferred. VersionsFeature
177208 -> Framework. StateComponent Framework. AcidState PackageInfoState
178209 -> Framework. DynamicPath
179210 -- ^ URI specifying a package and version `e.g. lens or lens-4.11`
180211 -> Framework. ServerPartE Framework. Response
181- servePackageBasicDescription resource userFeature preferred packageInfoState dpath = do
212+ servePackageBasicDescription resource uploaderCache userFeature preferred packageInfoState dpath = do
182213
183214 let metadataRev :: Maybe Int = lookup " revision" dpath >>= Framework. fromReqURI
184215
@@ -196,15 +227,17 @@ servePackageBasicDescription resource userFeature preferred packageInfoState dpa
196227 -> Maybe Int
197228 -> Framework. ServerPartE Framework. Response
198229 lookupOrInsertDescr pkgid metadataRev = do
199- cachedDescr <- Framework. queryState packageInfoState $
200- GetDescriptionFor (pkgid, metadataRev)
201- descr :: PackageBasicDescription <- case cachedDescr of
202- Just d -> return d
230+ cachedDescr <- Framework. queryState packageInfoState $ GetDescriptionFor (pkgid, metadataRev)
231+ descr :: PackageBasicDescriptionDTO <- case cachedDescr of
232+ Just d -> do
233+ uploader <- getPackageUploader pkgid uploaderCache
234+ return $ basicDescriptionToDTO uploader d
203235 Nothing -> do
204- d <- getPackageDescr pkgid metadataRev
236+ dto <- getPackageDescr pkgid metadataRev
237+ let description = dtoToBasicDescription dto
205238 Framework. updateState packageInfoState $
206- SetDescriptionFor (pkgid, metadataRev) (Just d )
207- return d
239+ SetDescriptionFor (pkgid, metadataRev) (Just description )
240+ return dto
208241 return $ Framework. toResponse $ Aeson. toJSON descr
209242
210243 getPackageDescr pkgid metadataRev = do
@@ -227,10 +260,12 @@ servePackageBasicDescription resource userFeature preferred packageInfoState dpa
227260 uploadedAt = fst $ uploadInfos Vector. ! metadataInd
228261 uploaderId = snd $ uploadInfos Vector. ! metadataInd
229262 uploader <- userName <$> lookupUserInfo userFeature uploaderId
230- let pkgDescr = getBasicDescription uploader uploadedAt cabalFile metadataInd
263+ let pkgDescr = getBasicDescription uploadedAt cabalFile metadataInd
231264 case pkgDescr of
232265 Left e -> Framework. errInternalError [Framework. MText e]
233- Right d -> return d
266+ Right d -> do
267+ let packageInfoDTO = basicDescriptionToDTO uploader d
268+ return packageInfoDTO
234269
235270 lookupOrInsertVersions
236271 :: PackageName
@@ -255,6 +290,14 @@ servePackageBasicDescription resource userFeature preferred packageInfoState dpa
255290 . Preferred. classifyVersions prefInfo
256291 $ fmap packageVersion pkgs
257292
293+ getPackageUploader
294+ :: PackageIdentifier
295+ -> Map PackageIdentifier UserName
296+ -> Framework. ServerPartE UserName
297+ getPackageUploader pkgId cache =
298+ case Map. lookup pkgId cache of
299+ Just u -> pure u
300+ Nothing -> Framework. errNotFound " Could not find uploader" []
258301
259302-- | Our backup doesn't produce any entries, and backup restore
260303-- returns an empty state. Our responses are cheap enough to
0 commit comments