From c335dd6865a7ad448bfbff28262556ced163be29 Mon Sep 17 00:00:00 2001 From: Tommy Bidne Date: Sun, 10 Mar 2024 22:36:26 +1300 Subject: [PATCH] Add 'Nothing' to WithDisabled; make usage more principled --- shrun.cabal | 4 +- src/Shrun/Configuration.hs | 45 ++++---- src/Shrun/Configuration/Args.hs | 3 +- src/Shrun/Configuration/Args/Parsing.hs | 22 ++-- .../Configuration/Args/Parsing/CmdLogging.hs | 10 +- src/Shrun/Configuration/Args/Parsing/Core.hs | 30 +++--- .../Configuration/Args/Parsing/FileLogging.hs | 18 ++-- .../Configuration/Args/Parsing/Notify.hs | 14 +-- src/Shrun/Configuration/Args/Parsing/Utils.hs | 30 ++++-- src/Shrun/Configuration/Data/CmdLogging.hs | 90 +++++++++------- src/Shrun/Configuration/Data/ConfigPhase.hs | 6 +- src/Shrun/Configuration/Data/FileLogging.hs | 75 +++++++++---- src/Shrun/Configuration/Data/Notify.hs | 59 ++++++---- src/Shrun/Configuration/Data/WithDisable.hs | 98 ----------------- src/Shrun/Configuration/Data/WithDisabled.hs | 93 ++++++++++++++++ src/Shrun/Env.hs | 43 ++++---- test/unit/Main.hs | 4 +- test/unit/Unit/Shrun/Configuration/Args.hs | 57 +++++----- .../Data/{WithDisable.hs => WithDisabled.hs} | 101 +++++++----------- 19 files changed, 428 insertions(+), 374 deletions(-) delete mode 100644 src/Shrun/Configuration/Data/WithDisable.hs create mode 100644 src/Shrun/Configuration/Data/WithDisabled.hs rename test/unit/Unit/Shrun/Configuration/Data/{WithDisable.hs => WithDisabled.hs} (53%) diff --git a/shrun.cabal b/shrun.cabal index 793057ec..27386130 100644 --- a/shrun.cabal +++ b/shrun.cabal @@ -65,7 +65,7 @@ library Shrun.Configuration.Data.FileLogging Shrun.Configuration.Data.MergedConfig Shrun.Configuration.Data.Notify - Shrun.Configuration.Data.WithDisable + Shrun.Configuration.Data.WithDisabled Shrun.Configuration.Legend Shrun.Configuration.Toml Shrun.Data.Command @@ -167,7 +167,7 @@ test-suite unit Unit.Generators Unit.Prelude Unit.Shrun.Configuration.Args - Unit.Shrun.Configuration.Data.WithDisable + Unit.Shrun.Configuration.Data.WithDisabled Unit.Shrun.Configuration.Legend Unit.Shrun.Logging.Formatting Unit.Shrun.Logging.Generators diff --git a/src/Shrun/Configuration.hs b/src/Shrun/Configuration.hs index 2ce3cc76..1439e5fe 100644 --- a/src/Shrun/Configuration.hs +++ b/src/Shrun/Configuration.hs @@ -30,13 +30,8 @@ import Shrun.Configuration.Data.MergedConfig ), ) import Shrun.Configuration.Data.Notify (mergeNotifyLogging) -import Shrun.Configuration.Data.WithDisable - ( WithDisable, - alternativeDefault, - alternativeEmpty, - defaultIfDisabled, - emptyIfDisabled, - ) +import Shrun.Configuration.Data.WithDisabled (WithDisabled, (<>?)) +import Shrun.Configuration.Data.WithDisabled qualified as WD import Shrun.Configuration.Legend qualified as Legend import Shrun.Configuration.Toml (Toml) import Shrun.Data.Command (Command (MkCommand)) @@ -78,24 +73,24 @@ mergeConfig args mToml = do $ MkMergedConfig { coreConfig = MkCoreConfigP - { timeout = emptyIfDisabled (args ^. (#coreConfig % #timeout)), - init = emptyIfDisabled (args ^. (#coreConfig % #init)), + { timeout = WD.toMaybe (args ^. (#coreConfig % #timeout)), + init = WD.toMaybe (args ^. (#coreConfig % #init)), keyHide = - defaultIfDisabled KeyHideOff (args ^. (#coreConfig % #keyHide)), + WD.fromWithDisabled KeyHideOff (args ^. (#coreConfig % #keyHide)), pollInterval = - defaultIfDisabled + WD.fromWithDisabled defaultPollInterval (args ^. (#coreConfig % #pollInterval)), cmdLogSize = - defaultIfDisabled + WD.fromWithDisabled defaultCmdLogSize (args ^. (#coreConfig % #cmdLogSize)), timerFormat = - defaultIfDisabled + WD.fromWithDisabled defaultTimerFormat (args ^. (#coreConfig % #timerFormat)), cmdNameTrunc = - emptyIfDisabled (args ^. (#coreConfig % #cmdNameTrunc)), + WD.toMaybe (args ^. (#coreConfig % #cmdNameTrunc)), cmdLogging, fileLogging = mergeFileLogging @@ -128,31 +123,31 @@ mergeConfig args mToml = do { coreConfig = MkCoreConfigP { timeout = - altNothing #timeout (toml ^. (#coreConfig % #timeout)), + plusNothing #timeout (toml ^. (#coreConfig % #timeout)), init = - altNothing #init (toml ^. (#coreConfig % #init)), + plusNothing #init (toml ^. (#coreConfig % #init)), keyHide = - altDefault + plusDefault KeyHideOff #keyHide (toml ^. (#coreConfig % #keyHide)), pollInterval = - altDefault + plusDefault defaultPollInterval #pollInterval (toml ^. (#coreConfig % #pollInterval)), cmdLogSize = - altDefault + plusDefault defaultCmdLogSize #cmdLogSize (toml ^. (#coreConfig % #cmdLogSize)), timerFormat = - altDefault + plusDefault defaultTimerFormat #timerFormat (toml ^. (#coreConfig % #timerFormat)), cmdNameTrunc = - altNothing + plusNothing #cmdNameTrunc (toml ^. (#coreConfig % #cmdNameTrunc)), cmdLogging, @@ -170,8 +165,8 @@ mergeConfig args mToml = do where cmdsText = args ^. #commands - altDefault :: a -> Lens' CoreConfigArgs (WithDisable (Maybe a)) -> Maybe a -> a - altDefault defA l = alternativeDefault defA (args ^. (#coreConfig % l)) + plusDefault :: a -> Lens' CoreConfigArgs (WithDisabled a) -> Maybe a -> a + plusDefault defA l r = WD.fromWithDisabled defA $ (args ^. (#coreConfig % l)) <>? r - altNothing :: Lens' CoreConfigArgs (WithDisable (Maybe a)) -> Maybe a -> Maybe a - altNothing l = alternativeEmpty (args ^. (#coreConfig % l)) + plusNothing :: Lens' CoreConfigArgs (WithDisabled a) -> Maybe a -> Maybe a + plusNothing l r = WD.toMaybe $ (args ^. (#coreConfig % l)) <>? r diff --git a/src/Shrun/Configuration/Args.hs b/src/Shrun/Configuration/Args.hs index 510aad9a..906c1b8f 100644 --- a/src/Shrun/Configuration/Args.hs +++ b/src/Shrun/Configuration/Args.hs @@ -43,14 +43,13 @@ import Shrun.Configuration.Data.FileLogging import Shrun.Configuration.Data.Notify ( NotifyP (MkNotifyP, action, system, timeout), ) -import Shrun.Configuration.Data.WithDisable (WithDisable (With)) import Shrun.Prelude defaultArgs :: NESeq Text -> Args defaultArgs commands = MkArgs { configPath = mempty, - cmdLog = With False, + cmdLog = mempty, coreConfig = MkCoreConfigP { timeout = mempty, diff --git a/src/Shrun/Configuration/Args/Parsing.hs b/src/Shrun/Configuration/Args/Parsing.hs index f1434405..6cc77a5a 100644 --- a/src/Shrun/Configuration/Args/Parsing.hs +++ b/src/Shrun/Configuration/Args/Parsing.hs @@ -38,16 +38,16 @@ import Shrun.Configuration.Args.Parsing.Core qualified as Core import Shrun.Configuration.Args.Parsing.Utils qualified as Utils import Shrun.Configuration.Args.TH (getDefaultConfigTH) import Shrun.Configuration.Data.Core (CoreConfigArgs) -import Shrun.Configuration.Data.WithDisable (WithDisable) +import Shrun.Configuration.Data.WithDisabled (WithDisabled) import Shrun.Prelude import Shrun.Utils qualified as U -- | CLI args. data Args = MkArgs { -- | Optional config file. - configPath :: WithDisable (Maybe OsPath), + configPath :: WithDisabled OsPath, -- | Whether to log commands. - cmdLog :: WithDisable Bool, + cmdLog :: WithDisabled (), -- | Core config. coreConfig :: CoreConfigArgs, -- | List of commands. @@ -115,8 +115,8 @@ defaultConfig = OA.infoOption (unpack txt) (OA.long "default-config" <> Utils.mk txt = T.unlines $$getDefaultConfigTH help = "Writes a default config.toml file to stdout." -configParser :: Parser (WithDisable (Maybe OsPath)) -configParser = Utils.withDisableParser mainParser "config" +configParser :: Parser (WithDisabled OsPath) +configParser = Utils.withDisabledParser mainParser "config" where mainParser = OA.optional @@ -137,10 +137,10 @@ configParser = Utils.withDisableParser mainParser "config" "--config and the automatic XDG lookup." ] -cmdLogParser :: Parser (WithDisable Bool) -cmdLogParser = Utils.withDisableParser mainParser "cmd-log" +cmdLogParser :: Parser (WithDisabled ()) +cmdLogParser = Utils.withDisabledParser mainParser "cmd-log" where - mainParser = + switchParser = OA.switch ( mconcat [ OA.short 'l', @@ -148,6 +148,12 @@ cmdLogParser = Utils.withDisableParser mainParser "cmd-log" Utils.mkHelp helpTxt ] ) + mainParser = do + b <- switchParser + pure + $ if b + then Just () + else Nothing helpTxt = mconcat [ "The default behavior is to swallow logs for the commands ", diff --git a/src/Shrun/Configuration/Args/Parsing/CmdLogging.hs b/src/Shrun/Configuration/Args/Parsing/CmdLogging.hs index 580836a2..bad0e396 100644 --- a/src/Shrun/Configuration/Args/Parsing/CmdLogging.hs +++ b/src/Shrun/Configuration/Args/Parsing/CmdLogging.hs @@ -15,7 +15,7 @@ import Shrun.Configuration.Data.CmdLogging stripControl ), ) -import Shrun.Configuration.Data.WithDisable (WithDisable) +import Shrun.Configuration.Data.WithDisabled (WithDisabled) import Shrun.Data.StripControl (StripControl) import Shrun.Data.StripControl qualified as StripControl import Shrun.Data.Truncation (LineTruncation) @@ -33,9 +33,9 @@ cmdLoggingParser = do lineTrunc } -cmdLogStripControlParser :: Parser (WithDisable (Maybe StripControl)) +cmdLogStripControlParser :: Parser (WithDisabled StripControl) cmdLogStripControlParser = - Utils.withDisableParser mainParser "cmd-log-strip-control" + Utils.withDisabledParser mainParser "cmd-log-strip-control" where mainParser = OA.optional @@ -60,8 +60,8 @@ cmdLogStripControlParser = " This option is experimental and subject to change." ] -cmdLogLineTruncParser :: Parser (WithDisable (Maybe LineTruncation)) -cmdLogLineTruncParser = Utils.withDisableParser mainParser "cmd-log-line-trunc" +cmdLogLineTruncParser :: Parser (WithDisabled LineTruncation) +cmdLogLineTruncParser = Utils.withDisabledParser mainParser "cmd-log-line-trunc" where mainParser = OA.optional diff --git a/src/Shrun/Configuration/Args/Parsing/Core.hs b/src/Shrun/Configuration/Args/Parsing/Core.hs index ee5e2361..fb07bf48 100644 --- a/src/Shrun/Configuration/Args/Parsing/Core.hs +++ b/src/Shrun/Configuration/Args/Parsing/Core.hs @@ -27,7 +27,7 @@ import Shrun.Configuration.Data.Core timerFormat ), ) -import Shrun.Configuration.Data.WithDisable (WithDisable) +import Shrun.Configuration.Data.WithDisabled (WithDisabled) import Shrun.Data.KeyHide (KeyHide (KeyHideOn)) import Shrun.Data.PollInterval ( PollInterval, @@ -69,8 +69,8 @@ coreParser = do notify } -timeoutParser :: Parser (WithDisable (Maybe Timeout)) -timeoutParser = Utils.withDisableParser mainParser "timeout" +timeoutParser :: Parser (WithDisabled Timeout) +timeoutParser = Utils.withDisabledParser mainParser "timeout" where mainParser = OA.optional @@ -90,8 +90,8 @@ timeoutParser = Utils.withDisableParser mainParser "timeout" "2h3s. Defaults to no timeout." ] -initParser :: Parser (WithDisable (Maybe Text)) -initParser = Utils.withDisableParser mainParser "init" +initParser :: Parser (WithDisabled Text) +initParser = Utils.withDisabledParser mainParser "init" where mainParser = OA.optional @@ -109,8 +109,8 @@ initParser = Utils.withDisableParser mainParser "init" "to 'shrun \". ~/.bashrc && foo\" \". ~/.bashrc && bar\"'." ] -keyHideParser :: Parser (WithDisable (Maybe KeyHide)) -keyHideParser = Utils.withDisableParser mainParser "key-hide" +keyHideParser :: Parser (WithDisabled KeyHide) +keyHideParser = Utils.withDisabledParser mainParser "key-hide" where mainParser = OA.optional @@ -130,8 +130,8 @@ keyHideParser = Utils.withDisableParser mainParser "key-hide" "unaffected." ] -pollIntervalParser :: Parser (WithDisable (Maybe PollInterval)) -pollIntervalParser = Utils.withDisableParser mainParser "poll-interval" +pollIntervalParser :: Parser (WithDisabled PollInterval) +pollIntervalParser = Utils.withDisabledParser mainParser "poll-interval" where mainParser = OA.optional @@ -164,8 +164,8 @@ pollIntervalParser = Utils.withDisableParser mainParser "poll-interval" . showt . view #unPollInterval -cmdLogSizeParser :: Parser (WithDisable (Maybe (Bytes B Natural))) -cmdLogSizeParser = Utils.withDisableParser mainParser "cmd-log-size" +cmdLogSizeParser :: Parser (WithDisabled (Bytes B Natural)) +cmdLogSizeParser = Utils.withDisabledParser mainParser "cmd-log-size" where mainParser = OA.optional @@ -186,8 +186,8 @@ cmdLogSizeParser = Utils.withDisableParser mainParser "cmd-log-size" "across lines. The default is 1024." ] -timerFormatParser :: Parser (WithDisable (Maybe TimerFormat)) -timerFormatParser = Utils.withDisableParser mainParser "timer-format" +timerFormatParser :: Parser (WithDisabled TimerFormat) +timerFormatParser = Utils.withDisabledParser mainParser "timer-format" where mainParser = OA.optional @@ -203,8 +203,8 @@ timerFormatParser = Utils.withDisableParser mainParser "timer-format" "'2 hours, 3 seconds'." ] -cmdNameTruncParser :: Parser (WithDisable (Maybe (Truncation TCmdName))) -cmdNameTruncParser = Utils.withDisableParser mainParser "cmd-name-trunc" +cmdNameTruncParser :: Parser (WithDisabled (Truncation TCmdName)) +cmdNameTruncParser = Utils.withDisabledParser mainParser "cmd-name-trunc" where mainParser = OA.optional diff --git a/src/Shrun/Configuration/Args/Parsing/FileLogging.hs b/src/Shrun/Configuration/Args/Parsing/FileLogging.hs index 32d676c7..586633c0 100644 --- a/src/Shrun/Configuration/Args/Parsing/FileLogging.hs +++ b/src/Shrun/Configuration/Args/Parsing/FileLogging.hs @@ -11,7 +11,7 @@ import Shrun.Configuration.Data.FileLogging ( FileLoggingArgs, FileLoggingP (MkFileLoggingP, mode, path, sizeMode, stripControl), ) -import Shrun.Configuration.Data.WithDisable (WithDisable) +import Shrun.Configuration.Data.WithDisabled (WithDisabled) import Shrun.Data.FileMode (FileMode) import Shrun.Data.FileMode qualified as FileMode import Shrun.Data.FilePathDefault (FilePathDefault) @@ -37,8 +37,8 @@ fileLoggingParser = do sizeMode } -fileLogParser :: Parser (WithDisable (Maybe FilePathDefault)) -fileLogParser = Utils.withDisableParser mainParser "file-log" +fileLogParser :: Parser (WithDisabled FilePathDefault) +fileLogParser = Utils.withDisabledParser mainParser "file-log" where mainParser = OA.optional @@ -61,9 +61,9 @@ fileLogParser = Utils.withDisableParser mainParser "file-log" "directory e.g. ~/.config/shrun/shrun.log." ] -fileLogStripControlParser :: Parser (WithDisable (Maybe StripControl)) +fileLogStripControlParser :: Parser (WithDisabled StripControl) fileLogStripControlParser = - Utils.withDisableParser mainParser "file-log-strip-control" + Utils.withDisabledParser mainParser "file-log-strip-control" where mainParser = OA.optional @@ -81,8 +81,8 @@ fileLogStripControlParser = "Defaults to all." ] -fileLogModeParser :: Parser (WithDisable (Maybe FileMode)) -fileLogModeParser = Utils.withDisableParser mainParser "file-log-mode" +fileLogModeParser :: Parser (WithDisabled FileMode) +fileLogModeParser = Utils.withDisabledParser mainParser "file-log-mode" where mainParser = OA.optional @@ -96,8 +96,8 @@ fileLogModeParser = Utils.withDisableParser mainParser "file-log-mode" ) helpTxt = "Mode in which to open the log file. Defaults to write." -fileLogSizeModeParser :: Parser (WithDisable (Maybe FileSizeMode)) -fileLogSizeModeParser = Utils.withDisableParser mainParser "file-log-size-mode" +fileLogSizeModeParser :: Parser (WithDisabled FileSizeMode) +fileLogSizeModeParser = Utils.withDisabledParser mainParser "file-log-size-mode" where mainParser = OA.optional diff --git a/src/Shrun/Configuration/Args/Parsing/Notify.hs b/src/Shrun/Configuration/Args/Parsing/Notify.hs index 65ff5278..bd1239b6 100644 --- a/src/Shrun/Configuration/Args/Parsing/Notify.hs +++ b/src/Shrun/Configuration/Args/Parsing/Notify.hs @@ -11,7 +11,7 @@ import Shrun.Configuration.Data.Notify ( NotifyArgs, NotifyP (MkNotifyP, action, system, timeout), ) -import Shrun.Configuration.Data.WithDisable (WithDisable) +import Shrun.Configuration.Data.WithDisabled (WithDisabled) import Shrun.Notify.Types (NotifyAction, NotifySystemP1, NotifyTimeout) import Shrun.Notify.Types qualified as Notify import Shrun.Prelude @@ -29,8 +29,8 @@ notifyParser = do timeout } -notifyActionParser :: Parser (WithDisable (Maybe NotifyAction)) -notifyActionParser = Utils.withDisableParser mainParser "notify-action" +notifyActionParser :: Parser (WithDisabled NotifyAction) +notifyActionParser = Utils.withDisabledParser mainParser "notify-action" where mainParser = OA.optional @@ -48,8 +48,8 @@ notifyActionParser = Utils.withDisableParser mainParser "notify-action" "'command'." ] -notifySystemParser :: Parser (WithDisable (Maybe NotifySystemP1)) -notifySystemParser = Utils.withDisableParser mainParser "notify-system" +notifySystemParser :: Parser (WithDisabled NotifySystemP1) +notifySystemParser = Utils.withDisabledParser mainParser "notify-system" where mainParser = OA.optional @@ -65,8 +65,8 @@ notifySystemParser = Utils.withDisableParser mainParser "notify-system" "available on linux, whereas 'apple-script' is available for osx." ] -notifyTimeoutParser :: Parser (WithDisable (Maybe NotifyTimeout)) -notifyTimeoutParser = Utils.withDisableParser mainParser "notify-timeout" +notifyTimeoutParser :: Parser (WithDisabled NotifyTimeout) +notifyTimeoutParser = Utils.withDisabledParser mainParser "notify-timeout" where mainParser = OA.optional diff --git a/src/Shrun/Configuration/Args/Parsing/Utils.hs b/src/Shrun/Configuration/Args/Parsing/Utils.hs index ff070dfa..6ee4d05c 100644 --- a/src/Shrun/Configuration/Args/Parsing/Utils.hs +++ b/src/Shrun/Configuration/Args/Parsing/Utils.hs @@ -1,6 +1,6 @@ module Shrun.Configuration.Args.Parsing.Utils - ( withDisableParser, - withDisableParserHelp, + ( withDisabledParser, + withDisabledParserHelp, mkHelp, ) where @@ -9,21 +9,31 @@ import Options.Applicative (Parser) import Options.Applicative qualified as OA import Options.Applicative.Help.Chunk qualified as Chunk import Options.Applicative.Help.Pretty qualified as Pretty -import Shrun.Configuration.Data.WithDisable (WithDisable (Disabled, With)) +import Shrun.Configuration.Data.WithDisabled + ( WithDisabled + ( Disabled, + With, + Without + ), + ) import Shrun.Prelude -withDisableParser :: Parser a -> String -> Parser (WithDisable a) -withDisableParser mainParser name = - withDisableParserHelp mainParser name ("Disables --" ++ name) +withDisabledParser :: Parser (Maybe a) -> String -> Parser (WithDisabled a) +withDisabledParser mainParser name = + withDisabledParserHelp mainParser name ("Disables --" ++ name) -withDisableParserHelp :: Parser a -> String -> String -> Parser (WithDisable a) -withDisableParserHelp mainParser name helpTxt = do - x <- mainParser +withDisabledParserHelp :: + Parser (Maybe a) -> + String -> + String -> + Parser (WithDisabled a) +withDisabledParserHelp mainParser name helpTxt = do + mx <- mainParser y <- noParser pure $ if y then Disabled - else With x + else maybe Without With mx where noParser = OA.flag diff --git a/src/Shrun/Configuration/Data/CmdLogging.hs b/src/Shrun/Configuration/Data/CmdLogging.hs index aec5a03d..0cbbda74 100644 --- a/src/Shrun/Configuration/Data/CmdLogging.hs +++ b/src/Shrun/Configuration/Data/CmdLogging.hs @@ -15,13 +15,11 @@ import Shrun.Configuration.Data.ConfigPhase ( ConfigPhase (ConfigPhaseArgs, ConfigPhaseMerged, ConfigPhaseToml), ConfigPhaseF, ) -import Shrun.Configuration.Data.WithDisable - ( WithDisable (Disabled, With), - alternativeDefault, - alternativeEmpty, - defaultIfDisabled, - emptyIfDisabled, +import Shrun.Configuration.Data.WithDisabled + ( WithDisabled (Disabled, With, Without), + (<>?), ) +import Shrun.Configuration.Data.WithDisabled qualified as WD import Shrun.Data.StripControl (StripControl (StripControlSmart)) import Shrun.Data.Truncation ( LineTruncation (Detected, Undetected), @@ -33,7 +31,7 @@ import Shrun.Prelude -- | Cmd log line truncation is truly optional, the default being none. type CmdLogLineTruncF :: ConfigPhase -> Type type family CmdLogLineTruncF p where - CmdLogLineTruncF ConfigPhaseArgs = WithDisable (Maybe LineTruncation) + CmdLogLineTruncF ConfigPhaseArgs = WithDisabled LineTruncation CmdLogLineTruncF ConfigPhaseToml = Maybe LineTruncation CmdLogLineTruncF ConfigPhaseMerged = Maybe (Truncation TCmdLine) @@ -66,58 +64,67 @@ deriving stock instance Show (CmdLoggingP ConfigPhaseMerged) -- | Merges args and toml configs. mergeCmdLogging :: - ( MonadTerminal m + ( HasCallStack, + MonadTerminal m ) => - WithDisable Bool -> + WithDisabled () -> CmdLoggingArgs -> Maybe CmdLoggingToml -> m (Maybe CmdLoggingMerged) -mergeCmdLogging withDisable args mToml = - case withDisable of +mergeCmdLogging withDisabled args mToml = + case withDisabled of -- 1. Logging globally disabled Disabled -> pure Nothing - With enabled -> case (enabled, mToml) of - -- 2. Neither Args nor Toml specifies logging -> disable - (False, Nothing) -> pure Nothing - -- 3. Args but no Toml -> Use Args - (True, Nothing) -> do - cmdLogLineTrunc <- case emptyIfDisabled (args ^. #lineTrunc) of - Just Detected -> Just . MkTruncation <$> getTerminalWidth - Just (Undetected x) -> pure $ Just x - Nothing -> pure Nothing + Without -> case mToml of + -- 2. No Args and no Toml + Nothing -> pure Nothing + -- 3. No Args but yes Toml + Just toml -> do + cmdLogLineTrunc <- + toLineTrunc $ view #lineTrunc args <>? view #lineTrunc toml pure $ Just $ MkCmdLoggingP - { stripControl = defaultIfDisabled StripControlSmart (args ^. #stripControl), + { stripControl = + plusDefault + StripControlSmart + #stripControl + (toml ^. #stripControl), lineTrunc = cmdLogLineTrunc } - -- 4. Maybe Args and Toml -> Merge (doesn't matter if Args specifies logging - -- since we only need at least one of Args + Toml, and Toml does). - -- - -- We combine toml w/ Args' config in altNothing/Default below. - (_, Just toml) -> do - cmdLogLineTrunc <- case altNothing #lineTrunc (toml ^. #lineTrunc) of - Just Detected -> Just . MkTruncation <$> getTerminalWidth - Just (Undetected x) -> pure $ Just x - Nothing -> pure Nothing + With _ -> case mToml of + -- 4. Args but no Toml -> Use Args + Nothing -> do + cmdLogLineTrunc <- toLineTrunc (view #lineTrunc args) pure $ Just $ MkCmdLoggingP { stripControl = - altDefault + WD.fromWithDisabled + StripControlSmart + (view #stripControl args), + lineTrunc = cmdLogLineTrunc + } + -- 5. Args and Toml -> Same as 3 + Just toml -> do + cmdLogLineTrunc <- + toLineTrunc $ view #lineTrunc args <>? view #lineTrunc toml + + pure + $ Just + $ MkCmdLoggingP + { stripControl = + plusDefault StripControlSmart #stripControl (toml ^. #stripControl), lineTrunc = cmdLogLineTrunc } where - altDefault :: a -> Lens' CmdLoggingArgs (WithDisable (Maybe a)) -> Maybe a -> a - altDefault defA l = alternativeDefault defA (args ^. l) - - altNothing :: Lens' CmdLoggingArgs (WithDisable (Maybe a)) -> Maybe a -> Maybe a - altNothing l = alternativeEmpty (args ^. l) + plusDefault :: a -> Lens' CmdLoggingArgs (WithDisabled a) -> Maybe a -> a + plusDefault defA l r = WD.fromWithDisabled defA $ (args ^. l) <>? r instance DecodeTOML CmdLoggingToml where tomlDecoder = @@ -130,3 +137,14 @@ decodeStripControl = getFieldOptWith tomlDecoder "strip-control" decodeCmdLineTrunc :: Decoder (Maybe LineTruncation) decodeCmdLineTrunc = getFieldOptWith tomlDecoder "line-trunc" + +toLineTrunc :: + ( HasCallStack, + MonadTerminal m + ) => + WithDisabled LineTruncation -> + m (Maybe (Truncation TCmdLine)) +toLineTrunc Disabled = pure Nothing +toLineTrunc Without = pure Nothing +toLineTrunc (With Detected) = Just . MkTruncation <$> getTerminalWidth +toLineTrunc (With (Undetected x)) = pure $ Just x diff --git a/src/Shrun/Configuration/Data/ConfigPhase.hs b/src/Shrun/Configuration/Data/ConfigPhase.hs index f120b251..21abb30f 100644 --- a/src/Shrun/Configuration/Data/ConfigPhase.hs +++ b/src/Shrun/Configuration/Data/ConfigPhase.hs @@ -7,7 +7,7 @@ module Shrun.Configuration.Data.ConfigPhase ) where -import Shrun.Configuration.Data.WithDisable (WithDisable) +import Shrun.Configuration.Data.WithDisabled (WithDisabled) import Shrun.Prelude -- | Data "phases" related to configuration. @@ -26,7 +26,7 @@ data ConfigPhase -- - Merged: Definite type ConfigPhaseF :: ConfigPhase -> Type -> Type type family ConfigPhaseF p a where - ConfigPhaseF ConfigPhaseArgs a = WithDisable (Maybe a) + ConfigPhaseF ConfigPhaseArgs a = WithDisabled a ConfigPhaseF ConfigPhaseToml a = Maybe a ConfigPhaseF ConfigPhaseMerged a = a @@ -37,6 +37,6 @@ type family ConfigPhaseF p a where -- - Merged: Maybe type ConfigPhaseMaybeF :: ConfigPhase -> Type -> Type type family ConfigPhaseMaybeF p a where - ConfigPhaseMaybeF ConfigPhaseArgs a = WithDisable (Maybe a) + ConfigPhaseMaybeF ConfigPhaseArgs a = WithDisabled a ConfigPhaseMaybeF ConfigPhaseToml a = Maybe a ConfigPhaseMaybeF ConfigPhaseMerged a = Maybe a diff --git a/src/Shrun/Configuration/Data/FileLogging.hs b/src/Shrun/Configuration/Data/FileLogging.hs index 925e4ea3..8fcc633f 100644 --- a/src/Shrun/Configuration/Data/FileLogging.hs +++ b/src/Shrun/Configuration/Data/FileLogging.hs @@ -14,11 +14,11 @@ import Shrun.Configuration.Data.ConfigPhase ( ConfigPhase (ConfigPhaseArgs, ConfigPhaseMerged, ConfigPhaseToml), ConfigPhaseF, ) -import Shrun.Configuration.Data.WithDisable - ( WithDisable (Disabled, With), - alternativeDefault, - defaultIfDisabled, +import Shrun.Configuration.Data.WithDisabled + ( WithDisabled (Disabled, With, Without), + (<>?), ) +import Shrun.Configuration.Data.WithDisabled qualified as WD import Shrun.Data.FileMode (FileMode (FileModeWrite)) import Shrun.Data.FilePathDefault (FilePathDefault) import Shrun.Data.FileSizeMode (FileSizeMode, defaultFileSizeMode) @@ -46,7 +46,7 @@ import Shrun.Prelude -- it must be present if file logging is active. type FileLogPathF :: ConfigPhase -> Type type family FileLogPathF p where - FileLogPathF ConfigPhaseArgs = WithDisable (Maybe FilePathDefault) + FileLogPathF ConfigPhaseArgs = WithDisabled FilePathDefault FileLogPathF ConfigPhaseToml = FilePathDefault FileLogPathF ConfigPhaseMerged = FilePathDefault @@ -93,36 +93,67 @@ mergeFileLogging args mToml = case args ^. #path of -- 1. Logging globally disabled Disabled -> Nothing - With mPath -> case (mPath, mToml) of - -- 2. Neither Args nor Toml specifies logging - (Nothing, Nothing) -> Nothing - -- 3. Args and no Toml - (Just p, Nothing) -> + Without -> case mToml of + -- 2. No Args and no Toml + Nothing -> Nothing + -- 3. No Args and yes Toml + Just toml -> Just $ MkFileLoggingP - { path = p, + { path = toml ^. #path, stripControl = - defaultIfDisabled StripControlAll (args ^. #stripControl), + plusDefault + StripControlAll + #stripControl + (toml ^. #stripControl), mode = - defaultIfDisabled FileModeWrite (args ^. #mode), + plusDefault + FileModeWrite + #mode + (toml ^. #mode), sizeMode = - defaultIfDisabled defaultFileSizeMode (args ^. #sizeMode) + plusDefault + defaultFileSizeMode + #sizeMode + (toml ^. #sizeMode) } - -- 4. Maybe Args and Toml - (mArgsPath, Just toml) -> + With path -> case mToml of + -- 3. Yes Args and no Toml + Nothing -> Just $ MkFileLoggingP - { path = fromMaybe (toml ^. #path) mArgsPath, + { path, stripControl = - altDefault StripControlAll #stripControl (toml ^. #stripControl), + WD.fromWithDisabled StripControlAll (args ^. #stripControl), mode = - altDefault FileModeWrite #mode (toml ^. #mode), + WD.fromWithDisabled FileModeWrite (args ^. #mode), sizeMode = - altDefault defaultFileSizeMode #sizeMode (toml ^. #sizeMode) + WD.fromWithDisabled defaultFileSizeMode (args ^. #sizeMode) + } + -- 4. Yes Args and yes Toml + Just toml -> + Just + $ MkFileLoggingP + { path, + stripControl = + plusDefault + StripControlAll + #stripControl + (view #stripControl toml), + mode = + plusDefault + FileModeWrite + #mode + (view #mode toml), + sizeMode = + plusDefault + defaultFileSizeMode + #sizeMode + (view #sizeMode toml) } where - altDefault :: a -> Lens' FileLoggingArgs (WithDisable (Maybe a)) -> Maybe a -> a - altDefault defA l = alternativeDefault defA (args ^. l) + plusDefault :: a -> Lens' FileLoggingArgs (WithDisabled a) -> Maybe a -> a + plusDefault defA l r = WD.fromWithDisabled defA $ (args ^. l) <>? r instance DecodeTOML FileLoggingToml where tomlDecoder = diff --git a/src/Shrun/Configuration/Data/Notify.hs b/src/Shrun/Configuration/Data/Notify.hs index 49b779c4..51aa5192 100644 --- a/src/Shrun/Configuration/Data/Notify.hs +++ b/src/Shrun/Configuration/Data/Notify.hs @@ -14,11 +14,11 @@ import Shrun.Configuration.Data.ConfigPhase ( ConfigPhase (ConfigPhaseArgs, ConfigPhaseMerged, ConfigPhaseToml), ConfigPhaseF, ) -import Shrun.Configuration.Data.WithDisable - ( WithDisable (Disabled, With), - alternativeDefault, - defaultIfDisabled, +import Shrun.Configuration.Data.WithDisabled + ( WithDisabled (Disabled, With, Without), + (<>?), ) +import Shrun.Configuration.Data.WithDisabled qualified as WD import Shrun.Notify.Types ( NotifyAction, NotifySystemP1, @@ -32,7 +32,7 @@ import Shrun.Prelude -- | Notify action is mandatory if we are running notifications. type NotifyActionF :: ConfigPhase -> Type type family NotifyActionF p where - NotifyActionF ConfigPhaseArgs = WithDisable (Maybe NotifyAction) + NotifyActionF ConfigPhaseArgs = WithDisabled NotifyAction NotifyActionF ConfigPhaseToml = NotifyAction NotifyActionF ConfigPhaseMerged = NotifyAction @@ -76,27 +76,50 @@ mergeNotifyLogging args mToml = case args ^. #action of -- 1. Notifications globally disabled Disabled -> Nothing - With mAction -> case (mAction, mToml) of - -- 2. Neither Args nor Toml specifies notifications - (Nothing, Nothing) -> Nothing + Without -> case mToml of + Nothing -> Nothing + Just toml -> + Just + $ MkNotifyP + { action = toml ^. #action, + system = + plusDefault + defaultNotifySystem + #system + (toml ^. #system), + timeout = + plusDefault + (afromInteger 10) + #timeout + (toml ^. #timeout) + } + With action -> case mToml of -- 3. Args but no Toml - (Just argsAction, Nothing) -> + Nothing -> Just $ MkNotifyP - { action = argsAction, - system = defaultIfDisabled defaultNotifySystem (args ^. #system), - timeout = defaultIfDisabled (afromInteger 10) (args ^. #timeout) + { action, + system = WD.fromWithDisabled defaultNotifySystem (args ^. #system), + timeout = WD.fromWithDisabled (afromInteger 10) (args ^. #timeout) } - (mArgsAction, Just toml) -> + Just toml -> Just $ MkNotifyP - { action = fromMaybe (toml ^. #action) mArgsAction, - system = altDefault defaultNotifySystem #system (toml ^. #system), - timeout = altDefault (afromInteger 10) #timeout (toml ^. #timeout) + { action, + system = + plusDefault + defaultNotifySystem + #system + (toml ^. #system), + timeout = + plusDefault + (afromInteger 10) + #timeout + (toml ^. #timeout) } where - altDefault :: a -> Lens' NotifyArgs (WithDisable (Maybe a)) -> Maybe a -> a - altDefault defA l = alternativeDefault defA (args ^. l) + plusDefault :: a -> Lens' NotifyArgs (WithDisabled a) -> Maybe a -> a + plusDefault defA l r = WD.fromWithDisabled defA $ (args ^. l) <>? r instance DecodeTOML NotifyToml where tomlDecoder = diff --git a/src/Shrun/Configuration/Data/WithDisable.hs b/src/Shrun/Configuration/Data/WithDisable.hs deleted file mode 100644 index 6a9a0443..00000000 --- a/src/Shrun/Configuration/Data/WithDisable.hs +++ /dev/null @@ -1,98 +0,0 @@ -{-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE UndecidableInstances #-} - -module Shrun.Configuration.Data.WithDisable - ( WithDisable (..), - - -- * Elimination - defaultIfDisabled, - emptyIfDisabled, - - -- * Functions - alternativeDefault, - alternativeEmpty, - - -- * Optics - _With, - _Disabled, - ) -where - -import Shrun.Prelude - --- | Adds a "disable" flag to some data. Though this is isomorphic to --- Maybe, we create a new type to be clearer about provenance. For instance, --- WithDisable (Maybe a) has much clearer meaning than Maybe (Maybe a) --- ("which level means what?"). --- --- The semigroup instance is based on an inner alternative i.e. With uses --- the inner alternative (With empty is the identity) and (Disabled, mempty) is --- a normal submonoid (i.e. Disabled <> x === Disabled === x <> Disabled). -data WithDisable a - = -- | The field. - With a - | -- | Disabled. - Disabled - deriving stock (Eq, Functor, Show) - -makePrisms ''WithDisable - -instance Foldable WithDisable where - foldr f e (With x) = f x e - foldr _ e Disabled = e - -instance Applicative WithDisable where - pure = With - - Disabled <*> _ = Disabled - _ <*> Disabled = Disabled - With f <*> With x = With (f x) - -instance (Alternative f) => Semigroup (WithDisable (f a)) where - Disabled <> _ = Disabled - _ <> Disabled = Disabled - With l <> With r = With (l <|> r) - -instance (Alternative f) => Monoid (WithDisable (f a)) where - mempty = With empty - --- | Returns the data if it exists and is not disabled, otherwise returns --- the default. -defaultIfDisabled :: (Foldable f) => a -> WithDisable (f a) -> a -defaultIfDisabled x Disabled = x -defaultIfDisabled x (With y) = fromFoldable x y - --- | Returns empty if the data is disabled or it does not exist. -emptyIfDisabled :: (Alternative f) => WithDisable (f a) -> f a -emptyIfDisabled Disabled = empty -emptyIfDisabled (With x) = x - --- | Morally returns @l <|> r@ or the default, taking Disabled into account. --- --- @ --- alternativeDefault x Disabled _ === x --- alternativeDefault x (With l) r === fromFoldable x (l <|> r) --- @ -alternativeDefault :: - (Alternative f, Foldable f) => - a -> - WithDisable (f a) -> - f a -> - a -alternativeDefault defA args = fromFoldable defA . alternativeEmpty args - --- | Morally returns @l <|> r@, taking Disabled into account. --- --- @ --- alternativeEmpty Disabled _ === empty --- alternativeEmpty (With l) r === l <|> r --- @ -alternativeEmpty :: - (Alternative f) => - -- | l - WithDisable (f a) -> - -- | r - f a -> - -- | l <|> r - f a -alternativeEmpty l r = emptyIfDisabled $ l <> pure r diff --git a/src/Shrun/Configuration/Data/WithDisabled.hs b/src/Shrun/Configuration/Data/WithDisabled.hs new file mode 100644 index 00000000..da416825 --- /dev/null +++ b/src/Shrun/Configuration/Data/WithDisabled.hs @@ -0,0 +1,93 @@ +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE UndecidableInstances #-} + +module Shrun.Configuration.Data.WithDisabled + ( WithDisabled (..), + + -- * Construction + Shrun.Configuration.Data.WithDisabled.fromMaybe, + + -- * Elimination + toMaybe, + fromWithDisabled, + + -- * Misc + (<>?), + + -- * Optics + _With, + _Without, + _Disabled, + ) +where + +import Shrun.Prelude + +-- | Like Maybe but adds an extra constructor representing a "disabled" state. +-- The idea is that both CLI Args and Toml and have optional fields, but +-- the CLI can also be "disabled", which overrides everything. +-- +-- The semigroup is similar to Maybe's: +-- +-- - Identity: 'Without' +-- - 'With' is left-biased. +-- - ('Without', 'Without') forms a normal submonoid, in particular: +-- +-- @ +-- 'Without' <> _ === 'Without' === _ <> 'Without' +-- @ +data WithDisabled a + = -- | The field. + With a + | -- | Missing. + Without + | -- | Disabled. + Disabled + deriving stock (Eq, Functor, Show) + +makePrisms ''WithDisabled + +instance Foldable WithDisabled where + foldr f e (With x) = f x e + foldr _ e Without = e + foldr _ e Disabled = e + +instance Applicative WithDisabled where + pure = With + + Disabled <*> _ = Disabled + _ <*> Disabled = Disabled + Without <*> _ = Without + _ <*> Without = Without + With f <*> With x = With (f x) + +instance Semigroup (WithDisabled a) where + Disabled <> _ = Disabled + _ <> Disabled = Disabled + Without <> r = r + l <> _ = l + +instance Monoid (WithDisabled a) where + mempty = Without + +-- | 'With' -> 'Just', o/w -> 'Nothing'. +toMaybe :: WithDisabled a -> Maybe a +toMaybe (With x) = Just x +toMaybe _ = Nothing + +-- | 'Nothing' -> 'Without', 'Just' -> 'With'. +fromMaybe :: Maybe a -> WithDisabled a +fromMaybe (Just x) = With x +fromMaybe Nothing = Without + +-- | Eliminates 'WithDisabled'. +fromWithDisabled :: a -> WithDisabled a -> a +fromWithDisabled _ (With y) = y +fromWithDisabled x _ = x + +-- | @l <>? r@ lifts 'Maybe' @r@ into a 'WithDisabled' per +-- 'Shrun.Configuration.Data.WithDisabled.fromMaybe' then runs the 'Semigroup'. +(<>?) :: WithDisabled a -> Maybe a -> WithDisabled a +wd <>? m = wd <> Shrun.Configuration.Data.WithDisabled.fromMaybe m + +infixr 6 <>? diff --git a/src/Shrun/Env.hs b/src/Shrun/Env.hs index 7bb4f6a5..ad41b3d5 100644 --- a/src/Shrun/Env.hs +++ b/src/Shrun/Env.hs @@ -33,8 +33,8 @@ import Shrun.Configuration.Args.Parsing ( parserInfoArgs, ) import Shrun.Configuration.Data.MergedConfig (MergedConfig) -import Shrun.Configuration.Data.WithDisable - ( WithDisable (Disabled, With), +import Shrun.Configuration.Data.WithDisabled + ( WithDisabled (Disabled, With, Without), ) import Shrun.Data.FileMode (FileMode (FileModeAppend, FileModeWrite)) import Shrun.Data.FilePathDefault (FilePathDefault (FPDefault, FPManual)) @@ -142,26 +142,25 @@ getMergedConfig = do case args ^. #configPath of -- 1. If noConfig is true then we ignore all toml config Disabled -> pure Nothing - With mConfigPath -> case mConfigPath of - -- 2. noConfig is false and toml config explicitly set: try reading - -- (all errors rethrown) - Just f -> readConfig f - -- 3. noConfig is false and toml config not set: try reading from - -- default location. If it does not exist that's fine, just print - -- a message. If it does, try to read it and throw any errors - -- (e.g. file errors, toml errors). - Nothing -> do - configDir <- getShrunXdgConfig - let path = configDir [osp|config.toml|] - b <- doesFileExist path - if b - then Just <$> readConfig path - else do - putTextLn - ( "No default config found at: " - <> T.pack (FsUtils.decodeOsToFpShow path) - ) - pure Nothing + -- 2. noConfig is false and toml config not set: try reading from + -- default location. If it does not exist that's fine, just print + -- a message. If it does, try to read it and throw any errors + -- (e.g. file errors, toml errors). + Without -> do + configDir <- getShrunXdgConfig + let path = configDir [osp|config.toml|] + b <- doesFileExist path + if b + then Just <$> readConfig path + else do + putTextLn + ( "No default config found at: " + <> T.pack (FsUtils.decodeOsToFpShow path) + ) + pure Nothing + -- 3. noConfig is false and toml config explicitly set: try reading + -- (all errors rethrown) + With f -> readConfig f mergeConfig args mTomlConfig where diff --git a/test/unit/Main.hs b/test/unit/Main.hs index 1f17f1be..080dbb14 100644 --- a/test/unit/Main.hs +++ b/test/unit/Main.hs @@ -3,7 +3,7 @@ module Main (main) where import Unit.Prelude import Unit.Shrun.Configuration.Args qualified -import Unit.Shrun.Configuration.Data.WithDisable qualified +import Unit.Shrun.Configuration.Data.WithDisabled qualified import Unit.Shrun.Configuration.Legend qualified import Unit.Shrun.Logging.Formatting qualified import Unit.Shrun.Utils qualified @@ -15,7 +15,7 @@ main = $ testGroup "Unit tests" [ Unit.Shrun.Configuration.Args.tests, - Unit.Shrun.Configuration.Data.WithDisable.tests, + Unit.Shrun.Configuration.Data.WithDisabled.tests, Unit.Shrun.Configuration.Legend.tests, Unit.Shrun.Logging.Formatting.tests, Unit.Shrun.Utils.tests diff --git a/test/unit/Unit/Shrun/Configuration/Args.hs b/test/unit/Unit/Shrun/Configuration/Args.hs index c6f54d40..7c050105 100644 --- a/test/unit/Unit/Shrun/Configuration/Args.hs +++ b/test/unit/Unit/Shrun/Configuration/Args.hs @@ -13,10 +13,7 @@ import Shrun.Configuration.Data.CmdLogging (CmdLoggingArgs) import Shrun.Configuration.Data.Core (CoreConfigArgs) import Shrun.Configuration.Data.FileLogging (FileLoggingArgs) import Shrun.Configuration.Data.Notify (NotifyArgs) -import Shrun.Configuration.Data.WithDisable - ( WithDisable (Disabled, With), - _With, - ) +import Shrun.Configuration.Data.WithDisabled (WithDisabled (Disabled, With)) import Shrun.Data.FileMode (FileMode (FileModeAppend, FileModeWrite)) import Shrun.Data.FilePathDefault (FilePathDefault (FPDefault, FPManual)) import Shrun.Data.FileSizeMode @@ -476,7 +473,7 @@ parseShortCommandLogging = testPropertyNamed "Should parse -l as CmdLogging" "pa verifyResult argList expected where argList = ["-l", "command"] - expected = set' (_Just % #cmdLog) (With True) defArgs + expected = set' (_Just % #cmdLog) (With ()) defArgs parseLongCommandLogging :: TestTree parseLongCommandLogging = @@ -485,7 +482,7 @@ parseLongCommandLogging = where desc = "Should parse --cmd-log as CmdLogging" argList = ["--cmd-log", "command"] - expected = set' (_Just % #cmdLog) (With True) defArgs + expected = set' (_Just % #cmdLog) (With ()) defArgs parseNoCmdLog :: TestTree parseNoCmdLog = @@ -933,68 +930,68 @@ defArgs = Just $ Args.defaultArgs defCommand updateDefArgs :: forall a. - Lens' Args (WithDisable (Maybe a)) -> + Lens' Args (WithDisabled a) -> a -> Maybe Args -updateDefArgs l x = (l' ?~ x) defArgs +updateDefArgs l x = (l' .~ With x) defArgs where - l' :: AffineTraversal' (Maybe Args) (Maybe a) - l' = _Just % l % _With + l' :: AffineTraversal' (Maybe Args) (WithDisabled a) + l' = _Just % l disableDefArgs :: forall a. - Lens' Args (WithDisable a) -> + Lens' Args (WithDisabled a) -> Maybe Args disableDefArgs l = (l' .~ Disabled) defArgs where - l' :: AffineTraversal' (Maybe Args) (WithDisable a) + l' :: AffineTraversal' (Maybe Args) (WithDisabled a) l' = _Just % l updateDefCoreArgs :: forall a. - Lens' CoreConfigArgs (WithDisable (Maybe a)) -> + Lens' CoreConfigArgs (WithDisabled a) -> a -> Maybe Args -updateDefCoreArgs l x = (l' ?~ x) defArgs +updateDefCoreArgs l x = (l' .~ With x) defArgs where - l' :: AffineTraversal' (Maybe Args) (Maybe a) - l' = _Just % #coreConfig % l % _With + l' :: AffineTraversal' (Maybe Args) (WithDisabled a) + l' = _Just % #coreConfig % l disableDefCoreArgs :: forall a. - Lens' CoreConfigArgs (WithDisable a) -> + Lens' CoreConfigArgs (WithDisabled a) -> Maybe Args disableDefCoreArgs l = (l' .~ Disabled) defArgs where - l' :: AffineTraversal' (Maybe Args) (WithDisable a) + l' :: AffineTraversal' (Maybe Args) (WithDisabled a) l' = _Just % #coreConfig % l updateDefCmdLogArgs :: forall a. - Lens' CmdLoggingArgs (WithDisable (Maybe a)) -> + Lens' CmdLoggingArgs (WithDisabled a) -> a -> Maybe Args -updateDefCmdLogArgs l x = (l' ?~ x) defArgs +updateDefCmdLogArgs l x = (l' .~ With x) defArgs where - l' :: AffineTraversal' (Maybe Args) (Maybe a) - l' = _Just % #coreConfig % #cmdLogging % l % _With + l' :: AffineTraversal' (Maybe Args) (WithDisabled a) + l' = _Just % #coreConfig % #cmdLogging % l updateDefFileLogArgs :: forall a. - Lens' FileLoggingArgs (WithDisable (Maybe a)) -> + Lens' FileLoggingArgs (WithDisabled a) -> a -> Maybe Args -updateDefFileLogArgs l x = (l' ?~ x) defArgs +updateDefFileLogArgs l x = (l' .~ With x) defArgs where - l' :: AffineTraversal' (Maybe Args) (Maybe a) - l' = _Just % #coreConfig % #fileLogging % l % _With + l' :: AffineTraversal' (Maybe Args) (WithDisabled a) + l' = _Just % #coreConfig % #fileLogging % l updateDefNotifyArgs :: forall a. - Lens' NotifyArgs (WithDisable (Maybe a)) -> + Lens' NotifyArgs (WithDisabled a) -> a -> Maybe Args -updateDefNotifyArgs l x = (l' ?~ x) defArgs +updateDefNotifyArgs l x = (l' .~ With x) defArgs where - l' :: AffineTraversal' (Maybe Args) (Maybe a) - l' = _Just % #coreConfig % #notify % l % _With + l' :: AffineTraversal' (Maybe Args) (WithDisabled a) + l' = _Just % #coreConfig % #notify % l diff --git a/test/unit/Unit/Shrun/Configuration/Data/WithDisable.hs b/test/unit/Unit/Shrun/Configuration/Data/WithDisabled.hs similarity index 53% rename from test/unit/Unit/Shrun/Configuration/Data/WithDisable.hs rename to test/unit/Unit/Shrun/Configuration/Data/WithDisabled.hs index 66e71f1a..397808c0 100644 --- a/test/unit/Unit/Shrun/Configuration/Data/WithDisable.hs +++ b/test/unit/Unit/Shrun/Configuration/Data/WithDisabled.hs @@ -1,7 +1,7 @@ {- HLINT ignore "Monoid law, left identity" -} {- HLINT ignore "Monoid law, right identity" -} -module Unit.Shrun.Configuration.Data.WithDisable +module Unit.Shrun.Configuration.Data.WithDisabled ( tests, ) where @@ -10,14 +10,20 @@ import Data.Foldable (Foldable (foldMap)) import Data.Monoid (Endo (Endo, appEndo)) import Hedgehog.Gen qualified as G import Hedgehog.Range qualified as R -import Shrun.Configuration.Data.WithDisable (WithDisable (Disabled, With)) -import Shrun.Configuration.Data.WithDisable qualified as WD +import Shrun.Configuration.Data.WithDisabled + ( WithDisabled + ( Disabled, + With, + Without + ), + ) +import Shrun.Configuration.Data.WithDisabled qualified as WD import Unit.Prelude tests :: TestTree tests = testGroup - "Shrun.Configuration.Data.WithDisable" + "Shrun.Configuration.Data.WithDisabled" [ testLaws, testsFunctions ] @@ -87,89 +93,64 @@ testFoldable = testPropertyNamed "Foldable" "testFoldable" $ do start :: String start = "acc" - accFn :: Maybe Int -> String -> String + accFn :: Int -> String -> String accFn i acc = show i ++ acc testsFunctions :: TestTree testsFunctions = testGroup "Functions" - [ testsDefaultIfDisabled, - testsEmptyIfDisabled, - testsAlternativeDefault, - testAlternativeEmpty + [ testsFromMaybe, + testsToMaybe, + testsFromWithDisabled ] -testsEmptyIfDisabled :: TestTree -testsEmptyIfDisabled = testPropertyNamed desc name $ do +testsFromMaybe :: TestTree +testsFromMaybe = testPropertyNamed desc name $ do property $ do - x <- forAll genMaybeInt - - x === WD.emptyIfDisabled (With x) + x <- forAll genInt - Nothing === WD.emptyIfDisabled (Disabled @(Maybe Int)) + With x === WD.fromMaybe (Just x) + Without === WD.fromMaybe (Nothing @Int) where - desc = "testsEmptyIfDisabled" - name = "emptyIfDisabled" + desc = "testsFromMaybe" + name = "fromMaybe" -testsDefaultIfDisabled :: TestTree -testsDefaultIfDisabled = testPropertyNamed desc name $ do +testsToMaybe :: TestTree +testsToMaybe = testPropertyNamed desc name $ do property $ do - d <- forAll genInt - e <- forAll genInt + x <- forAll genInt - d === WD.defaultIfDisabled d (Disabled @(Maybe Int)) - d === WD.defaultIfDisabled d (With Nothing) - e === WD.defaultIfDisabled d (With $ Just e) + Just x === WD.toMaybe (With x) + Nothing === WD.toMaybe (Without @Int) + Nothing === WD.toMaybe (Disabled @Int) where - desc = "defaultIfDisabled" - name = "testsDefaultIfDisabled" + desc = "testsToMaybe" + name = "toMaybe" -testsAlternativeDefault :: TestTree -testsAlternativeDefault = testPropertyNamed desc name $ do +testsFromWithDisabled :: TestTree +testsFromWithDisabled = testPropertyNamed desc name $ do property $ do d <- forAll genInt - x <- forAll genMaybeInt - - d === WD.alternativeDefault d Disabled x - - d === WD.alternativeDefault d (With Nothing) Nothing - where - desc = "alternativeDefault" - name = "testsAlternativeDefault" - -testAlternativeEmpty :: TestTree -testAlternativeEmpty = testPropertyNamed desc name $ do - property $ do - y <- forAll genMaybeInt - Nothing === WD.alternativeEmpty Disabled y + e <- forAll genInt - wd@(With x) <- forAll genWith - (x <|> y) === WD.alternativeEmpty wd y + d === WD.fromWithDisabled d Disabled + d === WD.fromWithDisabled d Without + e === WD.fromWithDisabled d (With e) where - desc = "alternativeEmpty" - name = "testAlternativeEmpty" + desc = "fromWithDisabled" + name = "testsFromWithDisabled" -genWD :: Gen (WithDisable (Maybe Int)) +genWD :: Gen (WithDisabled Int) genWD = G.choice [ genWith, - pure $ With Nothing, + pure Without, pure Disabled ] -genWith :: Gen (WithDisable (Maybe Int)) -genWith = With <$> genJustInt - -genMaybeInt :: Gen (Maybe Int) -genMaybeInt = - G.choice - [ genJustInt, - pure Nothing - ] - -genJustInt :: Gen (Maybe Int) -genJustInt = Just <$> genInt +genWith :: Gen (WithDisabled Int) +genWith = With <$> genInt genInt :: Gen Int genInt = G.integral $ R.linearFrom 0 0 100