Skip to content
Merged
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
8 changes: 3 additions & 5 deletions src/Distribution/Server/Features/Core.hs
Original file line number Diff line number Diff line change
Expand Up @@ -726,10 +726,9 @@ coreFeature ServerEnv{serverBlobStore = store} UserFeature{..}

serveCabalFileRevisionsList :: DynamicPath -> ServerPartE Response
serveCabalFileRevisionsList dpath = do
pkginfo <- packageInPath dpath >>= lookupPackageId
revisions <- fmap pkgMetadataRevisions $ packageInPath dpath >>= lookupPackageId
users <- queryGetUserDb
let revisions = pkgMetadataRevisions pkginfo
revisionToObj rev (cabalFileText, (utime, uid)) =
let revisionToObj rev (cabalFileText, (utime, uid)) =
let uname = userIdToName users uid
hash = sha256 (fromStrict $ cabalFileByteString cabalFileText)
in
Expand All @@ -746,8 +745,7 @@ coreFeature ServerEnv{serverBlobStore = store} UserFeature{..}
serveCabalFileRevision dpath = do
pkginfo <- packageInPath dpath >>= lookupPackageId
let mrev = lookup "revision" dpath >>= fromReqURI
revisions = pkgMetadataRevisions pkginfo
case mrev >>= \rev -> revisions Vec.!? rev of
case mrev >>= pkgSpecificRevision pkginfo of
Just (fileRev, (utime, _uid)) -> return $ toResponse cabalfile
where
cabalfile = Resource.CabalFile (fromStrict $ cabalFileByteString fileRev) utime
Expand Down
16 changes: 8 additions & 8 deletions src/Distribution/Server/Features/Html.hs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ import Data.List (intercalate, intersperse, insert)
import Data.Function (on)
import qualified Data.Map as Map
import qualified Data.Set as Set
import qualified Data.Vector as Vec
import qualified Data.Text as T
import qualified Data.ByteString.Lazy as BS (LazyByteString, fromStrict)
import qualified Network.URI as URI
Expand Down Expand Up @@ -805,32 +804,33 @@ mkHtmlCore ServerEnv{serverBaseURI, serverBlobStore}
users <- queryGetUserDb
let pkgid = packageId pkginfo
pkgname = packageName pkginfo
revisions = reverse $ Vec.toList (pkgMetadataRevisions pkginfo)
cabalFiles = reverse $ pkgAllRevisionsCabalFiles pkginfo
uploadInfos = reverse $ pkgAllRevisionsUploadInfos pkginfo
numRevisions = pkgNumRevisions pkginfo

revchanges :: [(SHA256Digest, [Change])]
revchanges = start revisions where
revchanges = start cabalFiles where
start [] = []
start (curr:rest) = go curr rest

go curr [] = [(sha256 (BS.fromStrict (cabalFileByteString (fst curr))), [])]
go curr [] = [(sha256 (BS.fromStrict (cabalFileByteString curr)), [])]
go curr (prev:rest) =
( sha256 (BS.fromStrict (cabalFileByteString (fst curr)))
( sha256 (BS.fromStrict (cabalFileByteString curr))
, changes curr prev )
: go prev rest

changes curr prev = either (const []) id $
diffCabalRevisionsByteString
(cabalFileByteString (fst prev))
(cabalFileByteString (fst curr))
(cabalFileByteString prev)
(cabalFileByteString curr)

cacheControl [NoCache] (etagFromHash numRevisions)
template <- getTemplate templates "revisions.html"
return $ toResponse $ template
[ "pkgname" $= pkgname
, "pkgid" $= pkgid
, "revisions" $= zipWith3 (revisionToTemplate users)
(map snd revisions)
uploadInfos
[numRevisions-1, numRevisions-2..]
revchanges
]
Expand Down
13 changes: 7 additions & 6 deletions src/Distribution/Server/Features/PackageCandidates.hs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import Distribution.Text
import Distribution.Package
import Distribution.Version

import Data.Maybe (maybeToList)
import qualified Data.ByteString.Lazy as BS (toStrict, fromStrict)
import qualified Data.Text as T
import qualified Text.XHtml.Strict as XHtml
Expand Down Expand Up @@ -283,12 +284,12 @@ candidatesFeature ServerEnv{serverBlobStore = store}
let lupUserName uid = (uid, fmap Users.userName (Users.lookupUserId uid users))

let pvs = [ object [ Key.fromString "version" .= (T.pack . display . packageVersion . candInfoId) p
, Key.fromString "sha256" .= (blobInfoHashSHA256 . pkgTarballGz . fst) tarball
, Key.fromString "time" .= (fst . snd) tarball
, Key.fromString "uploader" .= (lupUserName . snd . snd) tarball
, Key.fromString "sha256" .= (blobInfoHashSHA256 . pkgTarballGz) tarball
, Key.fromString "time" .= time
, Key.fromString "uploader" .= lupUserName uploader
]
| p <- pkgs
, let tarball = Vec.last . pkgTarballRevisions . candPkgInfo $ p
, (tarball, (time, uploader), _) <- maybeToList $ pkgLatestTarball $ candPkgInfo p
]

return . toResponse . toJSON $ pvs
Expand All @@ -312,10 +313,10 @@ candidatesFeature ServerEnv{serverBlobStore = store}
where
pn = T.pack . display . pkgName . candInfoId . head $ pkgs
pvs = [ object [ Key.fromString "version" .= (T.pack . display . packageVersion . candInfoId) p
, Key.fromString "sha256" .= (blobInfoHashSHA256 . pkgTarballGz . fst) tarball
, Key.fromString "sha256" .= (blobInfoHashSHA256 . pkgTarballGz) tarball
]
| p <- pkgs
, let tarball = Vec.last . pkgTarballRevisions . candPkgInfo $ p
, (tarball, _, _) <- maybeToList $ pkgLatestTarball $ candPkgInfo p
]

postCandidate :: ServerPartE Response
Expand Down
34 changes: 16 additions & 18 deletions src/Distribution/Server/Features/PackageInfoJSON.hs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import Data.Aeson ((.=))
import qualified Data.Aeson.Key as Key
import qualified Data.Map.Strict as Map
import qualified Data.Text as T
import qualified Data.Vector as Vector

import Distribution.License (licenseToSPDX)
import Distribution.Package (PackageIdentifier(..),
Expand All @@ -39,7 +38,7 @@ import qualified Distribution.Server.Framework as Framework
import Distribution.Server.Features.Core (CoreFeature(..),
CoreResource(..))
import qualified Distribution.Server.Features.PreferredVersions as Preferred
import Distribution.Server.Packages.Types (CabalFileText(..), pkgMetadataRevisions)
import Distribution.Server.Packages.Types (CabalFileText(..), pkgSpecificRevision, pkgLatestRevision, pkgMaxRevision, pkgNumRevisions)

import Distribution.Utils.ShortText (fromShortText)
import Data.Foldable (toList)
Expand Down Expand Up @@ -246,24 +245,23 @@ servePackageBasicDescription resource userFeature preferred dpath = do
guardValidPackageId resource pkgid
pkg <- lookupPackageId resource pkgid

let metadataRevs = fst <$> pkgMetadataRevisions pkg
uploadInfos = snd <$> pkgMetadataRevisions pkg
nMetadata = Vector.length metadataRevs
metadataInd = fromMaybe (nMetadata - 1) metadataRev
descr <- getPackageDescr metadataInd nMetadata metadataRevs uploadInfos
(metadataInd, (cabalFile, uploadInfo)) <- do
case metadataRev of
Nothing ->
pure (pkgMaxRevision pkg, pkgLatestRevision pkg)
Just ix ->
case pkgSpecificRevision pkg ix of
Nothing ->
Framework.errNotFound "Revision not found"
[Framework.MText
$ "There are " <> show (pkgNumRevisions pkg) <> " metadata revisions. Index "
<> show ix <> " is out of bounds."]
Just rev -> pure (ix, rev)

descr <- getPackageDescr cabalFile uploadInfo metadataInd
return $ Framework.toResponse $ Aeson.toJSON descr

getPackageDescr metadataInd nMetadata metadataRevs uploadInfos = do
when (metadataInd < 0 || metadataInd >= nMetadata)
(Framework.errNotFound "Revision not found"
[Framework.MText
$ "There are " <> show nMetadata <> " metadata revisions. Index "
<> show metadataInd <> " is out of bounds."]
)

let cabalFile = metadataRevs Vector.! metadataInd
uploadedAt = fst $ uploadInfos Vector.! metadataInd
uploaderId = snd $ uploadInfos Vector.! metadataInd
getPackageDescr cabalFile (uploadedAt, uploaderId) metadataInd = do
uploader <- userName <$> lookupUserInfo userFeature uploaderId
let pkgDescr = getBasicDescription uploadedAt cabalFile metadataInd
case pkgDescr of
Expand Down
2 changes: 1 addition & 1 deletion src/Distribution/Server/Features/Security/Migration.hs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ migratePkgs ServerEnv{ serverBlobStore = store } updatePackage precomputed =
updatePackage (pkgInfoId pkg) pkg'
return stats
where
tarballs = Vec.toList (pkgTarballRevisions pkg)
tarballs = pkgAllTarballs pkg

migrateTarball :: PkgTarball -> IO (Migrated PkgTarball)
migrateTarball pkgTarball@PkgTarball{} =
Expand Down
5 changes: 2 additions & 3 deletions src/Distribution/Server/Features/Sitemap.hs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import Distribution.Text (display)
import Distribution.Server.Packages.Types

import qualified Distribution.Server.Packages.PackageIndex as PackageIndex
import qualified Data.Vector as Vec
import qualified Data.Map as Map
import qualified Data.Text as T
import Data.ByteString.Lazy (ByteString)
Expand Down Expand Up @@ -233,7 +232,7 @@ generateSitemap serverBaseURI pageBuildDate alltags pkgIndex docIndex cachedTarI
[ ( prefixPkgURI ++ display (packageName pkg)
, uploadtime)
| pkg <- map head pkgss
, let (_, (uploadtime, _user)) = Vec.head (pkgMetadataRevisions pkg)
, let (uploadtime, _user) = pkgLatestUploadInfo pkg
Copy link
Copy Markdown
Contributor Author

@isovector isovector Apr 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that Vec.head was the first revision; this is now the latest revision. The use of head here seemed like a bug to me, but I can keep the old behavior if desired.

]
Daily 1.0

Expand Down Expand Up @@ -293,4 +292,4 @@ generateSitemap serverBaseURI pageBuildDate alltags pkgIndex docIndex cachedTarI
entryToPaths _ (Tar.TarFileEntry _) = []
entryToPaths base (Tar.TarDir content) = map ((base </>) . fst) content ++
[ file | (folder, entry) <- content, file <- entryToPaths (base </> folder) entry ]
-}
-}
5 changes: 1 addition & 4 deletions src/Distribution/Server/Features/UserNotify.hs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ import qualified Data.ByteString.Lazy.Char8 as BS
import qualified Data.Text as T
import qualified Data.Text.Lazy as TL
import qualified Data.Text.Lazy.Encoding as TL
import qualified Data.Vector as Vec


-- A feature to manage notifications to users when package metadata, etc is updated.
Expand Down Expand Up @@ -582,9 +581,7 @@ userNotifyFeature UserFeature{..}
{ notifyPackageId = pkgInfoId pkg
, notifyRevisions =
filter (\(t, _) -> earlier < t && t <= now)
. map snd
. Vec.toList
$ pkgMetadataRevisions pkg
$ pkgAllRevisionsUploadInfos pkg
}
else do
guard notifyUpload
Expand Down
3 changes: 2 additions & 1 deletion src/Distribution/Server/Packages/Index.hs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import Distribution.Server.Framework.MemSize

import Distribution.Server.Packages.Types
( CabalFileText(..), PkgInfo(..)
, pkgSpecificRevision
, pkgLatestCabalFileText, pkgLatestUploadInfo
)
import Distribution.Server.Packages.Metadata
Expand Down Expand Up @@ -100,7 +101,7 @@ writeIncremental pkgs =
mkTarEntry (CabalFileEntry pkgid revno timestamp userid username) = do
pkginfo <- PackageIndex.lookupPackageId pkgs pkgid
cabalfile <- fmap (cabalFileByteString . fst) $
pkgMetadataRevisions pkginfo Vec.!? revno
pkgSpecificRevision pkginfo revno
tarPath <- either (const Nothing) Just $
Tar.toTarPath False fileName
let !tarEntry = addTimestampAndOwner timestamp userid username $
Expand Down
3 changes: 1 addition & 2 deletions src/Distribution/Server/Packages/Metadata.hs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ computePkgMetadata :: PkgInfo -- ^ Package
-> (FilePath, BS.Lazy.ByteString)
computePkgMetadata pkg revNo = (inIndexPkgMetadata pkgId, raw)
where
tarballs = pkgTarballRevisions pkg
(tarball, _) = tarballs Vec.! revNo
Just (tarball, _) = pkgSpecificTarball pkg revNo
pkgId = pkgInfoId pkg
targets = pkgTarballTargets revNo pkgId tarball
signed = Sec.withSignatures' [] targets
Expand Down
4 changes: 2 additions & 2 deletions src/Distribution/Server/Packages/Render.hs
Original file line number Diff line number Diff line change
Expand Up @@ -119,12 +119,12 @@ doPackageRender users info = PackageRender
str -> categorySplit str
, rendRepoHeads = catMaybes (map rendRepo $ sourceRepos desc)
, rendModules = renderModules
, rendHasTarball = not . Vec.null $ pkgTarballRevisions info
, rendHasTarball = not . null $ pkgAllTarballs info
, rendChangeLog = Nothing -- populated later
, rendReadme = Nothing -- populated later
, rendUploadInfo = let (utime, uid) = pkgOriginalUploadInfo info
in (utime, Users.lookupUserId uid users)
, rendUpdateInfo = let maxrevision = Vec.length (pkgMetadataRevisions info) - 1
, rendUpdateInfo = let maxrevision = pkgMaxRevision info
(utime, uid) = pkgLatestUploadInfo info
uinfo = Users.lookupUserId uid users
in if maxrevision > 0
Expand Down
18 changes: 18 additions & 0 deletions src/Distribution/Server/Packages/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,21 @@ pkgOriginalUploadUser = snd . pkgOriginalUploadInfo
pkgLatestRevision :: PkgInfo -> (CabalFileText, UploadInfo)
pkgLatestRevision = Vec.last . pkgMetadataRevisions

pkgSpecificRevision :: PkgInfo -> Int -> Maybe (CabalFileText, UploadInfo)
pkgSpecificRevision pkg revno = pkgMetadataRevisions pkg Vec.!? revno

pkgAllRevisionsCabalFiles :: PkgInfo -> [CabalFileText]
pkgAllRevisionsCabalFiles = fmap fst . Vec.toList . pkgMetadataRevisions

pkgSpecificTarball :: PkgInfo -> Int -> Maybe (PkgTarball, UploadInfo)
pkgSpecificTarball pkg revno = pkgTarballRevisions pkg Vec.!? revno

pkgAllTarballs :: PkgInfo -> [(PkgTarball, UploadInfo)]
pkgAllTarballs = Vec.toList . pkgTarballRevisions

pkgAllRevisionsUploadInfos :: PkgInfo -> [UploadInfo]
pkgAllRevisionsUploadInfos = fmap snd . Vec.toList . pkgMetadataRevisions

pkgLatestCabalFileText :: PkgInfo -> CabalFileText
pkgLatestCabalFileText = fst . pkgLatestRevision

Expand All @@ -191,6 +206,9 @@ pkgLatestUploadUser = snd . pkgLatestUploadInfo
pkgNumRevisions :: PkgInfo -> Int
pkgNumRevisions = Vec.length . pkgMetadataRevisions

pkgMaxRevision :: PkgInfo -> Int
pkgMaxRevision = subtract 1 . pkgNumRevisions

-- | The latest tarball for a package (if any)
--
-- For packages with a @.cabal@ file but no tarball we return 'Nothing'.
Expand Down