From fa3c42d2c3d8b03a834a1740ba5ee250e6d8a488 Mon Sep 17 00:00:00 2001 From: Troels Henriksen Date: Fri, 10 Mar 2023 15:23:33 +0100 Subject: [PATCH 1/4] hackage-db: support cabal-install 3.10.1.0 XDG paths. From 3.10.1.0 onwards, cabal-install uses XDG directories to store its state and cache components. cabal2nix expects to find the Hackage tarball in ~/.cabal, where it may no longer be located. This commit changes cabal2nix to look in ~/.cabal if that directory exists (which matches the behaviour of cabal-install itself), but otherwise looks in the appropriate XDG directory. --- hackage-db/src/Distribution/Hackage/DB/Path.hs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/hackage-db/src/Distribution/Hackage/DB/Path.hs b/hackage-db/src/Distribution/Hackage/DB/Path.hs index 462497550..1aa393888 100644 --- a/hackage-db/src/Distribution/Hackage/DB/Path.hs +++ b/hackage-db/src/Distribution/Hackage/DB/Path.hs @@ -17,8 +17,18 @@ import Control.Exception import System.Directory import System.FilePath +-- Some logic to handle both old ~/.cabal and XDG cache directory used +-- by default from cabal-install 3.10.1.0. +-- +-- This is a simplified form of the logic found in cabal-install +-- itself: +-- https://github.com/haskell/cabal/blob/0ed12188525335ac9759dc957d49979ab09382a1/cabal-install/src/Distribution/Client/Config.hs#L594-L610 cabalStateDir :: IO FilePath -cabalStateDir = getAppUserDataDirectory "cabal" +cabalStateDir = do + dotCabal <- getAppUserDataDirectory "cabal" + dotCabalExists <- doesDirectoryExist dotCabal + if dotCabalExists then pure dotCabal else + getXdgDirectory XdgCache "cabal" cabalTarballDir :: String -> IO FilePath cabalTarballDir repo = do From cf924304e170369c528ce396cd10c626c99f8da8 Mon Sep 17 00:00:00 2001 From: sternenseemann Date: Mon, 10 Apr 2023 14:53:14 +0200 Subject: [PATCH 2/4] hackage-db: Distribution.Hackage.DB.Path: document cabalStateDir --- .../src/Distribution/Hackage/DB/Path.hs | 29 ++++++++++++++----- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/hackage-db/src/Distribution/Hackage/DB/Path.hs b/hackage-db/src/Distribution/Hackage/DB/Path.hs index 1aa393888..05d8effa0 100644 --- a/hackage-db/src/Distribution/Hackage/DB/Path.hs +++ b/hackage-db/src/Distribution/Hackage/DB/Path.hs @@ -17,12 +17,23 @@ import Control.Exception import System.Directory import System.FilePath --- Some logic to handle both old ~/.cabal and XDG cache directory used --- by default from cabal-install 3.10.1.0. +-- | +-- Determines the /state/ directory (which e.g. holds the hackage tarball) +-- cabal-install uses via the following logic: -- --- This is a simplified form of the logic found in cabal-install --- itself: --- https://github.com/haskell/cabal/blob/0ed12188525335ac9759dc957d49979ab09382a1/cabal-install/src/Distribution/Client/Config.hs#L594-L610 +-- 1. If @~/.cabal@ (see 'getAppUserDataDirectory') exists, use that. +-- 2. Otherwise, use @${XDG_CACHE_HOME}/cabal@ (see @'getXdgDirectory' 'XdgCache'@) +-- which is the new directory cabal-install can use starting with +-- version @3.10.*@. +-- +-- This logic is mostly equivalent to what upstream cabal-install is +-- [doing](https://github.com/haskell/cabal/blob/0ed12188525335ac9759dc957d49979ab09382a1/cabal-install/src/Distribution/Client/Config.hs#L594-L610) +-- with the following exceptions: +-- +-- * The @CABAL_DIR@ environment variable is not supported at the moment. +-- * The state directory can freely be configured to use a different location +-- in the cabal-install configuration file. hackage-db doesn't parse this +-- configuration file, so differing state directories are ignored. cabalStateDir :: IO FilePath cabalStateDir = do dotCabal <- getAppUserDataDirectory "cabal" @@ -39,9 +50,11 @@ hackageTarballDir :: IO FilePath hackageTarballDir = cabalTarballDir "hackage.haskell.org" -- | Determine the default path of the Hackage database, which typically --- resides at @"$HOME\/.cabal\/packages\/hackage.haskell.org\/00-index.tar"@. --- Running the command @"cabal update"@ will keep that file up-to-date. - +-- resides in @$HOME\/.cabal\/packages\/hackage.haskell.org\/@. +-- Running the command @cabal update@ or @cabal v2-update@ will keep the index +-- up-to-date. +-- +-- See 'cabalStateDir' on how @hackage-db@ searches for the cabal state directory. hackageTarball :: IO FilePath hackageTarball = do htd <- hackageTarballDir From bbc9f1fe3a9fcc2eaa7748134516100294422ee5 Mon Sep 17 00:00:00 2001 From: sternenseemann Date: Mon, 10 Apr 2023 15:06:02 +0200 Subject: [PATCH 3/4] hackage-db: Distribution.Hackage.DB.Path: support CABAL_DIR env var Just like cabal-install, if CABAL_DIR is set, use that for all operations. The environment variable does of course not support any split between $XDG_CONFIG_HOME/cabal and $XDG_CACHE_HOME/cabal which seems like an oversight on upstream's part, but we don't need to care: we only ever care about the state dir, so users can just need to set that. --- .../src/Distribution/Hackage/DB/Path.hs | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/hackage-db/src/Distribution/Hackage/DB/Path.hs b/hackage-db/src/Distribution/Hackage/DB/Path.hs index 05d8effa0..7bf806c94 100644 --- a/hackage-db/src/Distribution/Hackage/DB/Path.hs +++ b/hackage-db/src/Distribution/Hackage/DB/Path.hs @@ -15,31 +15,37 @@ import Distribution.Hackage.DB.Errors import Control.Exception import System.Directory +import System.Environment (lookupEnv) import System.FilePath -- | -- Determines the /state/ directory (which e.g. holds the hackage tarball) -- cabal-install uses via the following logic: -- --- 1. If @~/.cabal@ (see 'getAppUserDataDirectory') exists, use that. --- 2. Otherwise, use @${XDG_CACHE_HOME}/cabal@ (see @'getXdgDirectory' 'XdgCache'@) +-- 1. If the @CABAL_DIR@ environment variable is set, its content is used as the +-- cabal state directory +-- 2. If @~/.cabal@ (see 'getAppUserDataDirectory') exists, use that. +-- 3. Otherwise, use @${XDG_CACHE_HOME}/cabal@ (see @'getXdgDirectory' 'XdgCache'@) -- which is the new directory cabal-install can use starting with -- version @3.10.*@. -- -- This logic is mostly equivalent to what upstream cabal-install is -- [doing](https://github.com/haskell/cabal/blob/0ed12188525335ac9759dc957d49979ab09382a1/cabal-install/src/Distribution/Client/Config.hs#L594-L610) --- with the following exceptions: --- --- * The @CABAL_DIR@ environment variable is not supported at the moment. --- * The state directory can freely be configured to use a different location --- in the cabal-install configuration file. hackage-db doesn't parse this --- configuration file, so differing state directories are ignored. +-- with the following exception: +-- The state directory can freely be configured to use a different location +-- in the cabal-install configuration file. hackage-db doesn't parse this +-- configuration file, so differing state directories are ignored. cabalStateDir :: IO FilePath cabalStateDir = do + envCabal <- lookupEnv "CABAL_DIR" dotCabal <- getAppUserDataDirectory "cabal" dotCabalExists <- doesDirectoryExist dotCabal - if dotCabalExists then pure dotCabal else - getXdgDirectory XdgCache "cabal" + case envCabal of + Just dir -> pure dir + Nothing -> + if dotCabalExists + then pure dotCabal + else getXdgDirectory XdgCache "cabal" cabalTarballDir :: String -> IO FilePath cabalTarballDir repo = do From 56bcf7984532b44678a6dbea05f78ecd41547e8c Mon Sep 17 00:00:00 2001 From: sternenseemann Date: Mon, 10 Apr 2023 15:18:32 +0200 Subject: [PATCH 4/4] hackage-db: bump version to 2.1.3 and prepare changelog Since nixpkgs unstable now ships cabal-install 3.10.1.0 (23.05 will as well), we should get this feature released soon. --- hackage-db/CHANGELOG.md | 21 +++++++++++++++++++++ hackage-db/hackage-db.cabal | 2 +- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/hackage-db/CHANGELOG.md b/hackage-db/CHANGELOG.md index 0d8c0c30a..fa76e46a9 100644 --- a/hackage-db/CHANGELOG.md +++ b/hackage-db/CHANGELOG.md @@ -1,5 +1,26 @@ # Revision history for hackage-db +## 2.1.3 + +* `hackageTarball` / `cabalStateDir` now support overriding the cabal directory + location by setting the `CABAL_DIR` environment variable. This is useful if + `hackage-db` doesn't detect the correct location on its own: + + - A matching cabal state directory may exist, but should not be used for some + reason. + + - A non-standard cabal state directory may be used, but `hackage-db` can't + find it (as it doesn't check the `cabal-install` configuration file). + +* `hackageTarball` now supports all state dir location(s) (newly) supported by + `cabal-install`. If `CABAL_DIR` is not set, it will look in the following + locations in that order: + + 1. `$HOME/.cabal`, the classic location, will be preferred if it exists. + 2. `$XDG_CACHE_HOME/cabal` (usually `$HOME/.cache/cabal`) is used otherwise. + `cabal-install` 3.10.1.0 and newer will default to this location for + fresh installations. + ## 2.1.2 Fix a bug which lead to `parsePackageData` always failing if the package had diff --git a/hackage-db/hackage-db.cabal b/hackage-db/hackage-db.cabal index 81e69a80f..d6f580a70 100644 --- a/hackage-db/hackage-db.cabal +++ b/hackage-db/hackage-db.cabal @@ -1,5 +1,5 @@ name: hackage-db -version: 2.1.2 +version: 2.1.3 synopsis: Access cabal-install's Hackage database via Data.Map description: This library provides convenient access to the local copy of the Hackage database that \"cabal update\" creates. Check out