8
8
{-# LANGUAGE LambdaCase #-}
9
9
{-# LANGUAGE TupleSections #-}
10
10
{-# LANGUAGE RecordWildCards #-}
11
+ {-# LANGUAGE ViewPatterns #-}
11
12
12
13
-- | Make changes to project or global configuration.
13
14
module Stack.ConfigCmd
@@ -49,6 +50,7 @@ import Pantry.Internal.AesonExtended
49
50
(ToJSON (.. ), FromJSON , (.=) , WithJSONWarnings (WithJSONWarnings ), object )
50
51
import qualified Data.Aeson as Aeson
51
52
import qualified Data.Aeson.Key as Key
53
+ import Data.Aeson.KeyMap (KeyMap )
52
54
import qualified Data.Aeson.KeyMap as KeyMap
53
55
import Data.ByteString.Builder (byteString )
54
56
import qualified Data.Map.Merge.Strict as Map
@@ -125,9 +127,11 @@ configCmdSetScope (ConfigCmdSetResolver _) = CommandScopeProject
125
127
configCmdSetScope (ConfigCmdSetSystemGhc scope _) = scope
126
128
configCmdSetScope (ConfigCmdSetInstallGhc scope _) = scope
127
129
128
- encodeDumpProject :: ConfigDumpFormat -> (Project -> ByteString )
129
- encodeDumpProject ConfigDumpYaml = Yaml. encode
130
- encodeDumpProject ConfigDumpJson = toStrictBytes . Aeson. encode
130
+ encodeDumpProject :: RawYaml -> ConfigDumpFormat -> Project -> ByteString
131
+ encodeDumpProject _ ConfigDumpJson = toStrictBytes . Aeson. encode
132
+ encodeDumpProject rawConfig ConfigDumpYaml = \ p -> let e = Yaml. encode p in
133
+ Yaml. decodeEither' e & either (const e) (\ (d :: KeyMap Yaml. Value ) ->
134
+ either (const e) encodeUtf8 (cfgRedress rawConfig d " " ))
131
135
132
136
encodeDumpStackBy :: ToJSON a => (Config -> a ) -> ConfigCmdDumpStack -> (Config -> ByteString )
133
137
encodeDumpStackBy f (ConfigCmdDumpStack _ ConfigDumpYaml ) = Yaml. encode . f
@@ -151,9 +155,11 @@ cfgReadProject scope = do
151
155
152
156
cfgCmdDumpProject :: (HasConfig env , HasLogFunc env ) => ConfigCmdDumpProject -> RIO env ()
153
157
cfgCmdDumpProject (ConfigCmdDumpProject dumpFormat) = do
158
+ configFilePath <- cfgLocation CommandScopeProject
159
+ rawConfig <- mkRaw <$> liftIO (readFileUtf8 (toFilePath configFilePath))
154
160
project <- cfgReadProject CommandScopeProject
155
161
project & maybe (logError " Couldn't find project" ) (\ p ->
156
- encodeDumpProject dumpFormat p
162
+ encodeDumpProject rawConfig dumpFormat p
157
163
& decodeUtf8'
158
164
& either throwM (logInfo . display))
159
165
@@ -250,32 +256,34 @@ cfgRead scope = do
250
256
liftIO (Yaml. decodeFileEither (toFilePath configFilePath)) >>=
251
257
either throwM (return . (configFilePath,))
252
258
259
+ cfgRedress :: RawYaml -> KeyMap Yaml. Value -> Text -> Either UnicodeException Text
260
+ cfgRedress (yamlLines -> configLines) config@ (fmap Key. toText . KeyMap. keys -> keys) cmdKey =
261
+ unmkRaw . redress configLines <$>
262
+ encodeInOrder configLines (coerce keys) (coerce cmdKey) config
263
+
264
+ cfgRedressWrite :: RawYaml -> KeyMap Yaml. Value -> Text -> (Text -> RIO env () ) -> RIO env ()
265
+ cfgRedressWrite rawConfig config cmdKey write =
266
+ either throwM write (cfgRedress rawConfig config cmdKey)
267
+
253
268
cfgCmdSet :: (HasConfig env , HasGHCVariant env ) => ConfigCmdSet -> RIO env ()
254
269
cfgCmdSet cmd = do
255
- configFilePath <- cfgLocation $ configCmdSetScope cmd
256
270
-- We don't need to worry about checking for a valid yaml here
271
+ configFilePath <- cfgLocation $ configCmdSetScope cmd
257
272
rawConfig <- mkRaw <$> liftIO (readFileUtf8 (toFilePath configFilePath))
258
273
(config :: Yaml. Object ) <- either throwM return (Yaml. decodeEither' . encodeUtf8 $ coerce rawConfig)
259
274
newValue <- cfgCmdSetValue (parent configFilePath) cmd
260
275
let cmdKey = cfgCmdSetOptionName cmd
261
276
config' = KeyMap. insert (Key. fromText cmdKey) newValue config
262
- yamlKeys = Key. toText <$> KeyMap. keys config
263
277
if config' == config
264
278
then logInfo
265
279
(fromString (toFilePath configFilePath) <>
266
280
" already contained the intended configuration and remains \
267
281
\unchanged." )
268
- else do
269
- let configLines = yamlLines rawConfig
270
- either
271
- throwM
272
- (\ updated -> do
273
- let redressed = unmkRaw $ redress configLines updated
274
- writeBinaryFileAtomic configFilePath . byteString $ encodeUtf8 redressed
275
-
276
- let file = fromString $ toFilePath configFilePath
277
- logInfo (file <> " has been updated." ))
278
- (encodeInOrder configLines (coerce yamlKeys) (coerce cmdKey) config')
282
+ else cfgRedressWrite rawConfig config' cmdKey (\ redressed -> do
283
+ writeBinaryFileAtomic configFilePath . byteString $ encodeUtf8 redressed
284
+
285
+ let file = fromString $ toFilePath configFilePath
286
+ logInfo (file <> " has been updated." ))
279
287
280
288
cfgCmdSetValue
281
289
:: (HasConfig env , HasGHCVariant env )
0 commit comments