Skip to content

Commit e05676a

Browse files
committed
Remove cabal-install-parsers wrt #1092
1 parent ada2331 commit e05676a

File tree

6 files changed

+118
-11
lines changed

6 files changed

+118
-11
lines changed

app/ghcup/Main.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
module Main where
1212

13-
import PlanJson
13+
import GHCup.PlanJson
1414

1515
#if defined(BRICK)
1616
import GHCup.BrickMain (brickMain)

ghcup.cabal

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ common app-common-depends
7070
, async ^>=2.2.3
7171
, base >=4.12 && <5
7272
, bytestring >=0.10 && <0.12
73-
, cabal-install-parsers >=0.4.5
7473
, containers ^>=0.6
7574
, deepseq ^>=1.4
7675
, directory ^>=1.3.6.0
@@ -114,13 +113,15 @@ library
114113
exposed-modules:
115114
GHCup
116115
GHCup.Cabal
116+
GHCup.CabalConfig
117117
GHCup.Download
118118
GHCup.Download.Utils
119119
GHCup.Errors
120120
GHCup.GHC
121121
GHCup.HLS
122122
GHCup.List
123123
GHCup.Platform
124+
GHCup.PlanJson
124125
GHCup.Prelude
125126
GHCup.Prelude.File
126127
GHCup.Prelude.File.Search
@@ -180,6 +181,7 @@ library
180181
, bytestring >=0.10 && <0.12
181182
, bz2 ^>=1.0.1.1
182183
, Cabal ^>=3.0.0.0 || ^>=3.2.0.0 || ^>=3.4.0.0 || ^>=3.6.0.0 || ^>=3.8.0.0 || ^>= 3.10.0.0
184+
, Cabal-syntax ^>=3.6.0.0 || ^>=3.8.0.0 || ^>= 3.10.0.0 || ^>= 3.12.0.0
183185
, case-insensitive ^>=1.2.1.0
184186
, casing ^>=0.1.4.1
185187
, containers ^>=0.6
@@ -197,6 +199,7 @@ library
197199
, megaparsec >=8.0.0 && <9.3
198200
, mtl ^>=2.2
199201
, os-release ^>=1.0.0
202+
, parsec
200203
, pretty ^>=1.1.3.1
201204
, pretty-terminal ^>=0.1.0.0
202205
, regex-posix ^>=0.96
@@ -377,7 +380,6 @@ executable ghcup
377380
main-is: Main.hs
378381

379382
hs-source-dirs: app/ghcup
380-
other-modules: PlanJson
381383
default-language: Haskell2010
382384
default-extensions:
383385
LambdaCase

lib-opt/GHCup/OptParse/Common.hs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ module GHCup.OptParse.Common where
1111

1212

1313
import GHCup
14+
import GHCup.CabalConfig
1415
import GHCup.Download
1516
import GHCup.Platform
1617
import GHCup.Types
@@ -25,7 +26,6 @@ import Control.DeepSeq
2526
import Control.Concurrent
2627
import Control.Concurrent.Async
2728
import Control.Exception.Safe
28-
import Control.Monad.Identity (Identity(..))
2929
#if !MIN_VERSION_base(4,13,0)
3030
import Control.Monad.Fail ( MonadFail )
3131
#endif
@@ -60,7 +60,6 @@ import qualified Data.Text as T
6060
import qualified System.FilePath.Posix as FP
6161
import GHCup.Version
6262
import Control.Exception (evaluate)
63-
import qualified Cabal.Config as CC
6463

6564
--------------
6665
--[ Parser ]--
@@ -500,6 +499,6 @@ checkForUpdates = do
500499
logGHCPostRm :: (MonadReader env m, HasLog env, MonadIO m) => GHCTargetVersion -> m ()
501500
logGHCPostRm ghcVer = do
502501
cabalStore <- liftIO $ handleIO (\_ -> if isWindows then pure "C:\\cabal\\store" else pure "~/.cabal/store or ~/.local/state/cabal/store")
503-
(runIdentity . CC.cfgStoreDir <$> CC.readConfig)
502+
getStoreDir
504503
let storeGhcDir = cabalStore </> ("ghc-" <> T.unpack (prettyVer $ _tvVersion ghcVer))
505504
logInfo $ T.pack $ "After removing GHC you might also want to clean up your cabal store at: " <> storeGhcDir

lib-tui/GHCup/Brick/Actions.hs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
module GHCup.Brick.Actions where
1313

1414
import GHCup
15+
import GHCup.CabalConfig
1516
import GHCup.Download
1617
import GHCup.Errors
1718
import GHCup.Types.Optics ( getDirs, getPlatformReq, HasLog )
@@ -44,7 +45,6 @@ import Control.Monad.Trans.Resource
4445
import Data.Bool
4546
import Data.Functor
4647
import Data.Function ( (&), on)
47-
import Data.Functor.Identity
4848
import Data.List
4949
import Data.Maybe
5050
import Data.IORef (IORef, readIORef, newIORef, modifyIORef)
@@ -81,7 +81,6 @@ import Control.Concurrent (threadDelay)
8181
import qualified GHCup.GHC as GHC
8282
import qualified GHCup.Utils.Parsers as Utils
8383
import qualified GHCup.HLS as HLS
84-
import qualified Cabal.Config as CC
8584

8685

8786

@@ -414,7 +413,7 @@ set' input@(_, ListResult {..}) = do
414413
logGHCPostRm :: (MonadReader env m, HasLog env, MonadIO m) => GHCTargetVersion -> m ()
415414
logGHCPostRm ghcVer = do
416415
cabalStore <- liftIO $ handleIO (\_ -> if isWindows then pure "C:\\cabal\\store" else pure "~/.cabal/store or ~/.local/state/cabal/store")
417-
(runIdentity . CC.cfgStoreDir <$> CC.readConfig)
416+
getStoreDir
418417
let storeGhcDir = cabalStore </> ("ghc-" <> T.unpack (prettyVer $ _tvVersion ghcVer))
419418
logInfo $ T.pack $ "After removing GHC you might also want to clean up your cabal store at: " <> storeGhcDir
420419

@@ -725,4 +724,4 @@ keyHandlers KeyBindings {..} =
725724
ad <- use appData
726725
current_app_state <- use appState
727726
appSettings .= newAppSettings
728-
appState .= constructList ad newAppSettings (Just current_app_state)
727+
appState .= constructList ad newAppSettings (Just current_app_state)

lib/GHCup/CabalConfig.hs

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
{-# LANGUAGE CPP #-}
2+
{-# LANGUAGE OverloadedStrings #-}
3+
{-# LANGUAGE UndecidableInstances #-}
4+
5+
module GHCup.CabalConfig (getStoreDir) where
6+
7+
import Data.ByteString (ByteString)
8+
import Data.List.NonEmpty (NonEmpty)
9+
import Data.Map (Map)
10+
import System.Directory (getAppUserDataDirectory)
11+
import System.Environment (lookupEnv)
12+
import System.FilePath ((</>))
13+
14+
import qualified Data.ByteString as BS
15+
import qualified Data.Map.Strict as M
16+
import qualified Distribution.CabalSpecVersion as C
17+
import qualified Distribution.FieldGrammar as C
18+
import qualified Distribution.FieldGrammar.Parsec as C
19+
import qualified Distribution.Fields as C
20+
import qualified Distribution.Fields.LexerMonad as C
21+
import qualified Distribution.Parsec as C
22+
import qualified Distribution.Utils.Generic as C
23+
import qualified Text.Parsec as P
24+
25+
import Data.Foldable (for_)
26+
import Distribution.Parsec.Error
27+
28+
29+
30+
31+
getStoreDir :: IO FilePath
32+
getStoreDir = do
33+
fp <- findConfig
34+
bs <- BS.readFile fp
35+
either (fail . show . fmap (showPError fp)) resolveConfig (parseConfig bs)
36+
37+
-------------------------------------------------------------------------------
38+
-- Find config
39+
-------------------------------------------------------------------------------
40+
41+
-- | Find the @~\/.cabal\/config@ file.
42+
findConfig :: IO FilePath
43+
findConfig = do
44+
env <- lookupEnv "CABAL_CONFIG"
45+
case env of
46+
Just p -> return p
47+
Nothing -> do
48+
cabalDir <- findCabalDir
49+
return (cabalDir </> "config")
50+
51+
-- | Find the @~\/.cabal@ dir.
52+
findCabalDir :: IO FilePath
53+
findCabalDir = do
54+
cabalDirVar <- lookupEnv "CABAL_DIR"
55+
maybe (getAppUserDataDirectory "cabal") return cabalDirVar
56+
57+
58+
-------------------------------------------------------------------------------
59+
-- Parsing
60+
-------------------------------------------------------------------------------
61+
62+
-- | Parse @~\/.cabal\/config@ file.
63+
parseConfig :: ByteString -> Either (NonEmpty PError) (Maybe FilePath)
64+
parseConfig = parseWith $ \fields0 -> do
65+
let (fields1, _) = C.partitionFields fields0
66+
let fields2 = M.filterWithKey (\k _ -> k `elem` knownFields) fields1
67+
parse fields2
68+
where
69+
knownFields = C.fieldGrammarKnownFieldList grammar
70+
71+
parse :: Map C.FieldName [C.NamelessField C.Position]
72+
-> C.ParseResult (Maybe FilePath)
73+
parse fields = C.parseFieldGrammar C.cabalSpecLatest fields grammar
74+
75+
grammar :: C.ParsecFieldGrammar (Maybe FilePath) (Maybe FilePath)
76+
grammar = mempty
77+
<$> C.optionalFieldAla "store-dir" C.FilePathNT id
78+
79+
parseWith
80+
:: ([C.Field C.Position] -> C.ParseResult a) -- ^ parse
81+
-> ByteString -- ^ contents
82+
-> Either (NonEmpty PError) a
83+
parseWith parser bs = case C.runParseResult result of
84+
(_, Right x) -> Right x
85+
(_, Left (_, es)) -> Left es
86+
where
87+
result = case C.readFields' bs of
88+
Left perr -> C.parseFatalFailure pos (show perr) where
89+
ppos = P.errorPos perr
90+
pos = C.Position (P.sourceLine ppos) (P.sourceColumn ppos)
91+
Right (fields, lexWarnings) -> do
92+
C.parseWarnings (C.toPWarnings lexWarnings)
93+
for_ (C.validateUTF8 bs) $ \pos ->
94+
C.parseWarning C.zeroPos C.PWTUTF $ "UTF8 encoding problem at byte offset " ++ show pos
95+
parser fields
96+
97+
-------------------------------------------------------------------------------
98+
-- Resolving
99+
-------------------------------------------------------------------------------
100+
101+
-- | Fill the default in @~\/.cabal\/config@ file.
102+
resolveConfig :: Maybe FilePath -> IO FilePath
103+
resolveConfig (Just fp) = pure fp
104+
resolveConfig Nothing = do
105+
c <- findCabalDir
106+
return (c </> "store")
107+

app/ghcup/PlanJson.hs renamed to lib/GHCup/PlanJson.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
module PlanJson where
1+
module GHCup.PlanJson where
22

33
import Control.Monad (unless)
44
import System.FilePath

0 commit comments

Comments
 (0)