packages feed

opt-env-conf 0.1.0.0 → 0.2.0.0

raw patch · 4 files changed

+154/−93 lines, 4 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ OptEnvConf.Lint: LintErrorManyInfinite :: LintErrorMessage
+ OptEnvConf.Lint: LintErrorNoOptionOrSwitchForDashed :: LintErrorMessage

Files

CHANGELOG.md view
@@ -1,5 +1,13 @@ # Changelog +## [0.2.0.0] -- 2024-07-18++### Changed++* Fixed that the settings check could not be run with arguments.+* Added a lint to check that `long` isn't used without `option` or `switch`.+* Added a lint to check that `many` cannot be used with a parser that can succeed without consuming anything.+ ## [0.1.0.0] - 2024-07-16  ### Changed
opt-env-conf.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack  name:           opt-env-conf-version:        0.1.0.0+version:        0.2.0.0 synopsis:       Settings parsing for Haskell: command-line arguments, environment variables, and configuration values. homepage:       https://github.com/NorfairKing/opt-env-conf#readme bug-reports:    https://github.com/NorfairKing/opt-env-conf/issues
src/OptEnvConf/Lint.hs view
@@ -46,11 +46,13 @@   | LintErrorNoDashedForOption   | LintErrorNoMetavarForOption   | LintErrorNoDashedForSwitch+  | LintErrorNoOptionOrSwitchForDashed   | LintErrorNoReaderForEnvVar   | LintErrorNoMetavarForEnvVar   | LintErrorNoCommands   | LintErrorUnreadableExample !String   | LintErrorConfigWithoutLoad+  | LintErrorManyInfinite  renderLintErrors :: NonEmpty LintError -> [Chunk] renderLintErrors =@@ -156,6 +158,17 @@               "."             ]           ]+        LintErrorNoOptionOrSwitchForDashed ->+          [ [ functionChunk "long",+              " or ",+              functionChunk "short",+              " has no ",+              functionChunk "option",+              " or ",+              functionChunk "switch",+              "."+            ]+          ]         LintErrorNoReaderForEnvVar ->           [ [ functionChunk "env",               " has no ",@@ -183,6 +196,12 @@           [ [ functionChunk "conf",               " was called with no way to load configuration."             ]+          ]+        LintErrorManyInfinite ->+          [ [ functionChunk "many",+              " was called with a parser that may succeed without consuming anything."+            ],+            ["This is not allowed because the parser would run infinitely."]           ],       maybe [] (pure . ("Defined at: " :) . pure . fore cyan . chunk . T.pack . prettySrcLoc) lintErrorSrcLoc     ]@@ -198,22 +217,41 @@     . runValidationT     . go   where-    go :: Parser a -> ValidationT LintError (Reader Bool) ()+    -- Returns whether 'many' is allowed.+    -- 'many' is allowed only when every parse below consumes something.+    go :: Parser a -> ValidationT LintError (Reader Bool) Bool     go = \case-      ParserPure _ -> pure ()-      ParserAp p1 p2 -> go p1 *> go p2-      ParserSelect p1 p2 -> go p1 *> go p2-      ParserEmpty _ -> pure ()-      ParserAlt p1 p2 -> go p1 *> go p2-      -- TODO lint if we don't try to parse anything consuming under many.-      ParserMany p -> go p+      ParserPure _ -> pure False+      ParserAp p1 p2 -> do+        c1 <- go p1+        c2 <- go p2+        pure (c1 || c2)+      ParserSelect p1 p2 -> do+        c1 <- go p1+        c2 <- go p2+        pure (c1 || c2) -- TODO: is this right?+      ParserEmpty _ -> pure True+      ParserAlt p1 p2 -> do+        c1 <- go p1+        c2 <- go p2+        pure (c1 && c2) -- TODO: is this right?+        -- TODO lint if we don't try to parse anything consuming under many.+      ParserMany p -> do+        c <- go p+        when (not c) $+          mapValidationTFailure (LintError Nothing) $+            validationTFailure LintErrorManyInfinite+        pure c       ParserAllOrNothing _ p -> go p       ParserCheck _ _ _ p -> go p       ParserCommands mLoc ls -> do         if null ls           then validationTFailure $ LintError mLoc LintErrorNoCommands-          else traverse_ (go . commandParser) ls-      ParserWithConfig p1 p2 -> go p1 *> local (const True) (go p2)+          else and <$> traverse (go . commandParser) ls -- TODO is this right?+      ParserWithConfig p1 p2 -> do+        c1 <- go p1+        c2 <- local (const True) (go p2)+        pure $ c1 || c2       ParserSetting mLoc Setting {..} -> mapValidationTFailure (LintError mLoc) $ do         case settingHelp of           Nothing ->@@ -246,6 +284,8 @@           validationTFailure LintErrorNoMetavarForOption         when (isJust settingSwitchValue && null settingDasheds) $           validationTFailure LintErrorNoDashedForSwitch+        when (not settingTryOption && isNothing settingSwitchValue && not (null settingDasheds)) $+          validationTFailure LintErrorNoOptionOrSwitchForDashed         when (isJust settingEnvVars && null settingReaders) $           validationTFailure LintErrorNoReaderForEnvVar         when (isJust settingEnvVars && not settingHidden && isNothing settingMetavar) $@@ -257,3 +297,11 @@         hasConfig <- ask         when (isJust settingConfigVals && not hasConfig) $           validationTFailure LintErrorConfigWithoutLoad+        pure $+          -- 'many' is only allowed if something is being consumed and it's+          -- impossible for nothing to be consumed.+          and+            [ settingTryArgument || settingTryOption || isJust settingSwitchValue,+              null settingEnvVars,+              null settingConfigVals+            ]
src/OptEnvConf/Run.hs view
@@ -188,95 +188,100 @@  internalParser :: Version -> Parser a -> Parser (Internal a) internalParser version p =-  choice-    [ setting-        [ switch ShowHelp,-          short 'h',-          long "help",-          help "Show this help text"-        ],-      setting-        [ switch ShowVersion,-          long "version",-          help $ "Output version information: " <> showVersion version-        ],-      setting-        [ switch RenderMan,-          long "render-man-page",-          hidden,-          help "Show this help text"-        ],-      setting-        [ switch CheckSettings,-          long $ NE.toList settingsCheckSwitch,-          hidden,-          help "Run the parser and exit if parsing succeeded."-        ],-      BashCompletionScript-        <$> mapIO-          parseAbsFile-          ( setting-              [ option,-                reader str,-                long "bash-completion-script",+  let allowLeftovers :: Parser a -> Parser a+      allowLeftovers p' = fst <$> ((,) <$> p' <*> many (setting [reader str, argument, hidden] :: Parser String))+   in choice+        [ allowLeftovers $+            setting+              [ switch ShowHelp,+                short 'h',+                long "help",+                help "Show this help text"+              ],+          allowLeftovers $+            setting+              [ switch ShowVersion,+                long "version",+                help $ "Output version information: " <> showVersion version+              ],+          setting+            [ switch RenderMan,+              long "render-man-page",+              hidden,+              help "Show this help text"+            ],+          allowLeftovers $+            setting+              [ switch CheckSettings,+                long $ NE.toList settingsCheckSwitch,                 hidden,-                help "Render the bash completion script"-              ]-          ),-      ZshCompletionScript-        <$> mapIO-          parseAbsFile-          ( setting-              [ option,-                reader str,-                long "zsh-completion-script",+                help "Run the parser and exit if parsing succeeded."+              ],+          BashCompletionScript+            <$> mapIO+              parseAbsFile+              ( setting+                  [ option,+                    reader str,+                    long "bash-completion-script",+                    hidden,+                    help "Render the bash completion script"+                  ]+              ),+          ZshCompletionScript+            <$> mapIO+              parseAbsFile+              ( setting+                  [ option,+                    reader str,+                    long "zsh-completion-script",+                    hidden,+                    help "Render the zsh completion script"+                  ]+              ),+          ZshCompletionScript+            <$> mapIO+              parseAbsFile+              ( setting+                  [ option,+                    reader str,+                    long "fish-completion-script",+                    hidden,+                    help "Render the fish completion script"+                  ]+              ),+          setting+            [ help "Query completion",+              switch CompletionQuery,+              -- Long string that no normal user would ever use.+              long "query-opt-env-conf-completion",+              hidden+            ]+            <*> setting+              [ switch True,+                long "completion-enriched",+                value False,                 hidden,-                help "Render the zsh completion script"+                help "Whether to enable enriched completion"               ]-          ),-      ZshCompletionScript-        <$> mapIO-          parseAbsFile-          ( setting+            <*> setting               [ option,-                reader str,-                long "fish-completion-script",+                reader auto,+                long "completion-index",                 hidden,-                help "Render the fish completion script"+                help "The index between the arguments where completion was invoked."               ]-          ),-      setting-        [ help "Query completion",-          switch CompletionQuery,-          -- Long string that no normal user would ever use.-          long "query-opt-env-conf-completion",-          hidden+            <*> many+              ( setting+                  [ option,+                    reader str,+                    long "completion-word",+                    hidden,+                    help "The words (arguments) that have already been typed"+                  ]+              ),+          ParsedNormally <$> p         ]-        <*> setting-          [ switch True,-            long "completion-enriched",-            value False,-            hidden,-            help "Whether to enable enriched completion"-          ]-        <*> setting-          [ option,-            reader auto,-            long "completion-index",-            hidden,-            help "The index between the arguments where completion was invoked."-          ]-        <*> many-          ( setting-              [ option,-                reader str,-                long "completion-word",-                hidden,-                help "The words (arguments) that have already been typed"-              ]-          ),-      ParsedNormally <$> p-    ]  -- | Run a parser on given arguments and environment instead of getting them -- from the current process.