Skip to content

Commit

Permalink
Separate true HackageSecurityConfig from (renamed) `PackageIndexCon…
Browse files Browse the repository at this point in the history
…fig`

This pull request proposes a relatively minor, but breaking, change to Pantry's API. There is a corresponding pull request for Stack that adopts this version of the Pantry API.

The motivation for this proposal is the request at Stack issue [#5870](commercialhaskell/stack#5870).

What is currently referred to as `HackageSecurityConfig` is better named `PackageIndexConfig`, comprising a true `HackageSecuityConfig` value and a download prefix (`picDownloadPrefix :: !Text`).

What is currently referred to as `defaultHackageSecurityConfig` is renamed `defaultPackageIndexConfig`.

True `HackageSecurityConfig` (strictly, `WithJSONWarnings HackageSecurityConfig`) has its own instance of `FromJSON` and its own default: `defaultHackageSecurityConfig`.

Meeting the ask in the Stack issue, the instance of `FromJSON` for `PackageIndexConfig` now assigns a default value of `defaultHackageSecurityConfig` if the `hackage-security` key is absent from the JSON object.

The field of `PackageConfig` named `pcHackageSecuity :: !HackageSecurityConfig` is renamed `pcPackageIndex :: !PackageIndexConfig`.

For completeness, `defaultDownloadPrefix` is also exposed.
  • Loading branch information
mpilgrem committed Oct 11, 2022
1 parent f429530 commit fc8baeb
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 36 deletions.
14 changes: 14 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
# Changelog for pantry

## v0.6.0

* Rename `HackageSecurityConfig` as `PackageIndexConfig`,
`defaultHackageSecurityConfig` as `defaultPackageIndexConfig`, and
`pcHackageSecurity` field of `PantryConfig` as `pcPackageIndex`.
* Expose new `HackageSecurityConfig` and `defaultHackageSecurityConfig`. The
former represents Hackage Security configurations (only - no download prefix).
* Change the data constructor of `PackageIndexConfig` to have fields for a
download prefix (type `Text`) and of type `HackageSecurityIndex`.
* The `WithJSONWarnings PackageIndexConfig` instance of `FromJSON` now assigns
default value `defaultHackageSecurityConfig` if the `hackage-security` key is
absent from the JSON object.
* Expose `defaultDownloadPrefix`, for the official Hackage server.

## v0.5.7

* Expose `loadAndCompleteSnapshotRaw'` and `loadAndCompleteSnapshot'`, which
Expand Down
2 changes: 1 addition & 1 deletion package.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: pantry
version: 0.5.7
version: 0.6.0
synopsis: Content addressable Haskell package management
description: Please see the README on GitHub at <https://github.com/commercialhaskell/pantry#readme>
category: Development
Expand Down
2 changes: 1 addition & 1 deletion pantry.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ cabal-version: 1.12
-- see: https://github.com/sol/hpack

name: pantry
version: 0.5.7
version: 0.6.0
synopsis: Content addressable Haskell package management
description: Please see the README on GitHub at <https://github.com/commercialhaskell/pantry#readme>
category: Development
Expand Down
44 changes: 23 additions & 21 deletions src/Pantry.hs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@
module Pantry
( -- * Running
PantryConfig
, PackageIndexConfig (..)
, HackageSecurityConfig (..)
, defaultPackageIndexConfig
, defaultDownloadPrefix
, defaultHackageSecurityConfig
, defaultCasaRepoPrefix
, defaultCasaMaxPerRequest
Expand Down Expand Up @@ -177,6 +180,7 @@ module Pantry
, getHackageTypoCorrections
, loadGlobalHints
, partitionReplacedDependencies

-- * Snapshot cache
, SnapshotCacheHash (..)
, withSnapshotCache
Expand Down Expand Up @@ -232,9 +236,9 @@ withPantryConfig
=> Path Abs Dir
-- ^ pantry root directory, where the SQLite database and Hackage
-- downloads are kept.
-> HackageSecurityConfig
-- ^ Hackage configuration. You probably want
-- 'defaultHackageSecurityConfig'.
-> PackageIndexConfig
-- ^ Package index configuration. You probably want
-- 'defaultPackageIndexConfig'.
-> HpackExecutable
-- ^ When converting an hpack @package.yaml@ file to a cabal file,
-- what version of hpack should we use?
Expand All @@ -249,7 +253,7 @@ withPantryConfig
-> (PantryConfig -> RIO env a)
-- ^ What to do with the config
-> RIO env a
withPantryConfig root hsc he count pullURL maxPerRequest snapLoc inner = do
withPantryConfig root pic he count pullURL maxPerRequest snapLoc inner = do
env <- ask
pantryRelFile <- parseRelFile "pantry.sqlite3"
-- Silence persistent's logging output, which is really noisy
Expand All @@ -258,7 +262,7 @@ withPantryConfig root hsc he count pullURL maxPerRequest snapLoc inner = do
ref1 <- newIORef mempty
ref2 <- newIORef mempty
inner PantryConfig
{ pcHackageSecurity = hsc
{ pcPackageIndex = pic
, pcHpackExecutable = he
, pcRootDir = root
, pcStorage = storage
Expand All @@ -283,23 +287,21 @@ defaultCasaRepoPrefix = $(thParserCasaRepo "https://casa.fpcomplete.com")
defaultCasaMaxPerRequest :: Int
defaultCasaMaxPerRequest = 1280

-- | Default 'HackageSecurityConfig' value using the official Hackage server.
-- | Default 'PackageIndexConfig' value using the official Hackage server.
--
-- @since 0.1.0.0
defaultHackageSecurityConfig :: HackageSecurityConfig
defaultHackageSecurityConfig = HackageSecurityConfig
{ hscKeyIds =
[ "0a5c7ea47cd1b15f01f5f51a33adda7e655bc0f0b0615baa8e271f4c3351e21d"
, "1ea9ba32c526d1cc91ab5e5bd364ec5e9e8cb67179a471872f6e26f0ae773d42"
, "2c6c3627bd6c982990239487f1abd02e08a02e6cf16edb105a8012d444d870c3"
, "51f0161b906011b52c6613376b1ae937670da69322113a246a09f807c62f6921"
, "fe331502606802feac15e514d9b9ea83fee8b6ffef71335479a2e68d84adc6b0"
]
, hscKeyThreshold = 3
, hscDownloadPrefix = "https://hackage.haskell.org/"
, hscIgnoreExpiry = False
-- @since 0.6.0
defaultPackageIndexConfig :: PackageIndexConfig
defaultPackageIndexConfig = PackageIndexConfig
{ picDownloadPrefix = defaultDownloadPrefix
, picHackageSecurityConfig = defaultHackageSecurityConfig
}

-- | The download prefix for the official Hackage server.
--
-- @since 0.6.0
defaultDownloadPrefix :: Text
defaultDownloadPrefix = "https://hackage.haskell.org/"

-- | Returns the latest version of the given package available from
-- Hackage.
--
Expand Down Expand Up @@ -1709,7 +1711,7 @@ runPantryAppWith maxConnCount casaRepoPrefix casaMaxPerRequest f = runSimpleApp
root <- parseAbsDir $ stack FilePath.</> "pantry"
withPantryConfig
root
defaultHackageSecurityConfig
defaultPackageIndexConfig
HpackBundled
maxConnCount
casaRepoPrefix
Expand All @@ -1736,7 +1738,7 @@ runPantryAppClean f = liftIO $ withSystemTempDirectory "pantry-clean" $ \dir ->
root <- resolveDir' dir
withPantryConfig
root
defaultHackageSecurityConfig
defaultPackageIndexConfig
HpackBundled
8
defaultCasaRepoPrefix
Expand Down
4 changes: 2 additions & 2 deletions src/Pantry/Hackage.hs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ updateHackageIndexInternal forceUpdate mreason = do
gateUpdate $ withWriteLock_ storage $ do
for_ mreason logInfo
pc <- view pantryConfigL
let HackageSecurityConfig keyIds threshold url ignoreExpiry = pcHackageSecurity pc
let PackageIndexConfig url (HackageSecurityConfig keyIds threshold ignoreExpiry) = pcPackageIndex pc
root <- view hackageDirL
tarball <- view hackageIndexTarballL
baseURI <-
Expand Down Expand Up @@ -606,7 +606,7 @@ getHackageTarball pir mtreeKey = do
Nothing -> throwIO exc
Just pair2 -> pure pair2
pc <- view pantryConfigL
let urlPrefix = hscDownloadPrefix $ pcHackageSecurity pc
let urlPrefix = picDownloadPrefix $ pcPackageIndex pc
url =
mconcat
[ urlPrefix
Expand Down
62 changes: 51 additions & 11 deletions src/Pantry/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
{-# LANGUAGE NamedFieldPuns #-}
module Pantry.Types
( PantryConfig (..)
, PackageIndexConfig (..)
, HackageSecurityConfig (..)
, defaultHackageSecurityConfig
, Storage (..)
, HasPantryConfig (..)
, BlobKey (..)
Expand Down Expand Up @@ -248,7 +250,7 @@ data Storage = Storage
--
-- @since 0.1.0.0
data PantryConfig = PantryConfig
{ pcHackageSecurity :: !HackageSecurityConfig
{ pcPackageIndex :: !PackageIndexConfig
, pcHpackExecutable :: !HpackExecutable
, pcRootDir :: !(Path Abs Dir)
, pcStorage :: !Storage
Expand Down Expand Up @@ -607,33 +609,71 @@ instance FromJSON GitHubRepo where
[x, y] | not (T.null x || T.null y) -> return (GitHubRepo s)
_ -> fail "expecting \"user/repo\""

-- | Configuration for Hackage Security to securely download package
-- metadata and contents from Hackage. For most purposes, you'll want
-- to use the default Hackage settings via
-- @defaultHackageSecurityConfig@.
-- | Configuration to securely download package metadata and contents. For most
-- purposes, you'll want to use the default Hackage settings via
-- @defaultPackageIndexConfig@.
--
-- /NOTE/ It's highly recommended to only use the official Hackage
-- server or a mirror. See
-- <https://github.com/commercialhaskell/stack/issues/4137>.
--
-- @since 0.1.0.0
-- @since 0.6.0
data PackageIndexConfig = PackageIndexConfig
{ picDownloadPrefix :: !Text
, picHackageSecurityConfig :: !HackageSecurityConfig
}
deriving Show

-- | If the @hackage-security@ key is absent from the JSON object, assigns
-- default value 'defaultHackageSecurityConfig'.
--
-- @since 0.6.0
instance FromJSON (WithJSONWarnings PackageIndexConfig) where
parseJSON = withObjectWarnings "PackageIndexConfig" $ \o -> do
picDownloadPrefix <- o ..: "download-prefix"
picHackageSecurityConfig <- jsonSubWarnings $
o ..:? "hackage-security" ..!= noJSONWarnings defaultHackageSecurityConfig
pure PackageIndexConfig {..}

-- | Default 'HackageSecurityConfig' value using the official Hackage server.
--
-- @since 0.6.0
defaultHackageSecurityConfig :: HackageSecurityConfig
defaultHackageSecurityConfig = HackageSecurityConfig
{ hscKeyIds =
[ "0a5c7ea47cd1b15f01f5f51a33adda7e655bc0f0b0615baa8e271f4c3351e21d"
, "1ea9ba32c526d1cc91ab5e5bd364ec5e9e8cb67179a471872f6e26f0ae773d42"
, "2c6c3627bd6c982990239487f1abd02e08a02e6cf16edb105a8012d444d870c3"
, "51f0161b906011b52c6613376b1ae937670da69322113a246a09f807c62f6921"
, "fe331502606802feac15e514d9b9ea83fee8b6ffef71335479a2e68d84adc6b0"
]
, hscKeyThreshold = 3
, hscIgnoreExpiry = False
}

-- | Configuration for Hackage Security to securely download package metadata
-- and contents. For most purposes, you'll want to use the default Hackage
-- settings via @defaultHackageSecurityConfig@.
--
-- /NOTE/ It's highly recommended to only use the official Hackage
-- server or a mirror. See
-- <https://github.com/commercialhaskell/stack/issues/4137>.
--
-- @since 0.6.0
data HackageSecurityConfig = HackageSecurityConfig
{ hscKeyIds :: ![Text]
, hscKeyThreshold :: !Int
, hscDownloadPrefix :: !Text
, hscIgnoreExpiry :: !Bool
}
deriving Show

instance FromJSON (WithJSONWarnings HackageSecurityConfig) where
parseJSON = withObjectWarnings "HackageSecurityConfig" $ \o' -> do
hscDownloadPrefix <- o' ..: "download-prefix"
Object o <- o' ..: "hackage-security"
parseJSON = withObjectWarnings "HackageSecurityConfig" $ \o -> do
hscKeyIds <- o ..: "keyids"
hscKeyThreshold <- o ..: "key-threshold"
hscIgnoreExpiry <- o ..:? "ignore-expiry" ..!= True
pure HackageSecurityConfig {..}


-- | An environment which contains a 'PantryConfig'.
--
-- @since 0.1.0.0
Expand Down

0 comments on commit fc8baeb

Please sign in to comment.