Skip to content

Commit eb1355b

Browse files
committed
Redress the dump project YAML.
1 parent 6b93bd0 commit eb1355b

File tree

1 file changed

+25
-17
lines changed

1 file changed

+25
-17
lines changed

src/Stack/ConfigCmd.hs

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
{-# LANGUAGE LambdaCase #-}
99
{-# LANGUAGE TupleSections #-}
1010
{-# LANGUAGE RecordWildCards #-}
11+
{-# LANGUAGE ViewPatterns #-}
1112

1213
-- | Make changes to project or global configuration.
1314
module Stack.ConfigCmd
@@ -49,6 +50,7 @@ import Pantry.Internal.AesonExtended
4950
(ToJSON(..), FromJSON, (.=), WithJSONWarnings (WithJSONWarnings), object)
5051
import qualified Data.Aeson as Aeson
5152
import qualified Data.Aeson.Key as Key
53+
import Data.Aeson.KeyMap (KeyMap)
5254
import qualified Data.Aeson.KeyMap as KeyMap
5355
import Data.ByteString.Builder (byteString)
5456
import qualified Data.Map.Merge.Strict as Map
@@ -125,9 +127,11 @@ configCmdSetScope (ConfigCmdSetResolver _) = CommandScopeProject
125127
configCmdSetScope (ConfigCmdSetSystemGhc scope _) = scope
126128
configCmdSetScope (ConfigCmdSetInstallGhc scope _) = scope
127129

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 ""))
131135

132136
encodeDumpStackBy :: ToJSON a => (Config -> a) -> ConfigCmdDumpStack -> (Config -> ByteString)
133137
encodeDumpStackBy f (ConfigCmdDumpStack _ ConfigDumpYaml) = Yaml.encode . f
@@ -151,9 +155,11 @@ cfgReadProject scope = do
151155

152156
cfgCmdDumpProject :: (HasConfig env, HasLogFunc env) => ConfigCmdDumpProject -> RIO env ()
153157
cfgCmdDumpProject (ConfigCmdDumpProject dumpFormat) = do
158+
configFilePath <- cfgLocation CommandScopeProject
159+
rawConfig <- mkRaw <$> liftIO (readFileUtf8 (toFilePath configFilePath))
154160
project <- cfgReadProject CommandScopeProject
155161
project & maybe (logError "Couldn't find project") (\p ->
156-
encodeDumpProject dumpFormat p
162+
encodeDumpProject rawConfig dumpFormat p
157163
& decodeUtf8'
158164
& either throwM (logInfo . display))
159165

@@ -250,32 +256,34 @@ cfgRead scope = do
250256
liftIO (Yaml.decodeFileEither (toFilePath configFilePath)) >>=
251257
either throwM (return . (configFilePath,))
252258

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+
253268
cfgCmdSet :: (HasConfig env, HasGHCVariant env) => ConfigCmdSet -> RIO env ()
254269
cfgCmdSet cmd = do
255-
configFilePath <- cfgLocation $ configCmdSetScope cmd
256270
-- We don't need to worry about checking for a valid yaml here
271+
configFilePath <- cfgLocation $ configCmdSetScope cmd
257272
rawConfig <- mkRaw <$> liftIO (readFileUtf8 (toFilePath configFilePath))
258273
(config :: Yaml.Object) <- either throwM return (Yaml.decodeEither' . encodeUtf8 $ coerce rawConfig)
259274
newValue <- cfgCmdSetValue (parent configFilePath) cmd
260275
let cmdKey = cfgCmdSetOptionName cmd
261276
config' = KeyMap.insert (Key.fromText cmdKey) newValue config
262-
yamlKeys = Key.toText <$> KeyMap.keys config
263277
if config' == config
264278
then logInfo
265279
(fromString (toFilePath configFilePath) <>
266280
" already contained the intended configuration and remains \
267281
\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."))
279287

280288
cfgCmdSetValue
281289
:: (HasConfig env, HasGHCVariant env)

0 commit comments

Comments
 (0)