ronn-opt-env-conf (empty) → 1.0.0.0
raw patch · 8 files changed
+365/−0 lines, 8 filesdep +basedep +filepathdep +hspec
Dependencies added: base, filepath, hspec, hspec-golden, opt-env-conf, ronn, ronn-opt-env-conf, text
Files
- CHANGELOG.md +5/−0
- README.md +0/−0
- ronn-opt-env-conf.cabal +88/−0
- src/Ronn/OptEnvConf.hs +14/−0
- src/Ronn/OptEnvConf/Env.hs +50/−0
- src/Ronn/OptEnvConf/Opt.hs +111/−0
- tests/Main.hs +9/−0
- tests/Ronn/OptEnvConfSpec.hs +88/−0
+ CHANGELOG.md view
@@ -0,0 +1,5 @@+## [_Unreleased_](https://github.com/pbrisbin/ronn/compare/ronn-opt-env-conf-v1.0.0.0...main)++## [v1.0.0.0](https://github.com/pbrisbin/ronn/tree/ronn-opt-env-conf-v1.0.0.0)++First tagged pre-release.
+ README.md view
+ ronn-opt-env-conf.cabal view
@@ -0,0 +1,88 @@+cabal-version: 1.18+name: ronn-opt-env-conf+version: 1.0.0.0+license: AGPL-3+maintainer: Pat Brisbin+homepage: https://github.com/pbrisbin/ronn#readme+bug-reports: https://github.com/pbrisbin/ronn/issues+synopsis: Produce Ronn from OptEnvConf+description: Please see README.md+category: Documentation+build-type: Simple+extra-doc-files:+ README.md+ CHANGELOG.md++source-repository head+ type: git+ location: https://github.com/pbrisbin/ronn++library+ exposed-modules:+ Ronn.OptEnvConf+ Ronn.OptEnvConf.Env+ Ronn.OptEnvConf.Opt++ hs-source-dirs: src+ other-modules: Paths_ronn_opt_env_conf+ default-language: GHC2021+ default-extensions:+ DataKinds DeriveAnyClass DerivingStrategies DerivingVia+ DuplicateRecordFields GADTs LambdaCase NoFieldSelectors+ NoImplicitPrelude NoMonomorphismRestriction OverloadedRecordDot+ OverloadedStrings RecordWildCards TypeFamilies++ ghc-options:+ -fignore-optim-changes -fwrite-ide-info -Weverything+ -Wno-all-missed-specialisations -Wno-missing-exported-signatures+ -Wno-missing-import-lists -Wno-missing-kind-signatures+ -Wno-missing-local-signatures -Wno-missing-safe-haskell-mode+ -Wno-monomorphism-restriction -Wno-prepositive-qualified-module+ -Wno-safe -Wno-unsafe++ build-depends:+ base >=4.16.4.0 && <5,+ opt-env-conf,+ ronn >=1.1.0.0,+ text >=1.2.5.0++ if impl(ghc >=9.8)+ ghc-options:+ -Wno-missing-role-annotations -Wno-missing-poly-kind-signatures++test-suite spec+ type: exitcode-stdio-1.0+ main-is: Main.hs+ hs-source-dirs: tests+ other-modules:+ Ronn.OptEnvConfSpec+ Paths_ronn_opt_env_conf++ default-language: GHC2021+ default-extensions:+ DataKinds DeriveAnyClass DerivingStrategies DerivingVia+ DuplicateRecordFields GADTs LambdaCase NoFieldSelectors+ NoImplicitPrelude NoMonomorphismRestriction OverloadedRecordDot+ OverloadedStrings RecordWildCards TypeFamilies++ ghc-options:+ -fignore-optim-changes -fwrite-ide-info -Weverything+ -Wno-all-missed-specialisations -Wno-missing-exported-signatures+ -Wno-missing-import-lists -Wno-missing-kind-signatures+ -Wno-missing-local-signatures -Wno-missing-safe-haskell-mode+ -Wno-monomorphism-restriction -Wno-prepositive-qualified-module+ -Wno-safe -Wno-unsafe -threaded -rtsopts -with-rtsopts=-N++ build-depends:+ base >=4.16.4.0 && <5,+ filepath >=1.4.2.2,+ hspec >=2.9.7,+ hspec-golden >=0.2.1.0,+ opt-env-conf,+ ronn >=1.1.0.0,+ ronn-opt-env-conf,+ text >=1.2.5.0++ if impl(ghc >=9.8)+ ghc-options:+ -Wno-missing-role-annotations -Wno-missing-poly-kind-signatures
+ src/Ronn/OptEnvConf.hs view
@@ -0,0 +1,14 @@+-- |+--+-- Module : Ronn.OptEnvConf+-- Copyright : (c) 2024 Patrick Brisbin+-- License : AGPL-3+-- Maintainer : pbrisbin@gmail.com+-- Stability : experimental+-- Portability : POSIX+module Ronn.OptEnvConf+ ( module X+ ) where++import Ronn.OptEnvConf.Env as X+import Ronn.OptEnvConf.Opt as X
+ src/Ronn/OptEnvConf/Env.hs view
@@ -0,0 +1,50 @@+-- |+--+-- Module : Ronn.OptEnvConf.Env+-- Copyright : (c) 2024 Patrick Brisbin+-- License : AGPL-3+-- Maintainer : pbrisbin@gmail.com+-- Stability : experimental+-- Portability : POSIX+module Ronn.OptEnvConf.Env+ ( envDefinitions+ ) where++import Prelude++import Data.Foldable (toList)+import Data.List (intersperse)+import Data.String (IsString (..))+import OptEnvConf (Parser)+import OptEnvConf.Doc (AnyDocs (..), EnvDoc (..), parserEnvDocs)+import Ronn.AST++envDefinitions :: Parser a -> [Definition]+envDefinitions = go . parserEnvDocs+ where+ go :: AnyDocs EnvDoc -> [Definition]+ go = \case+ AnyDocsCommands {} -> [] -- TODO+ AnyDocsAnd ds -> concatMap go ds+ AnyDocsOr ds -> concatMap go ds+ AnyDocsSingle d -> [envDocDefinition d]++envDocDefinition :: EnvDoc -> Definition+envDocDefinition doc =+ Definition+ { name+ , description = Line $ maybe [] (pure . fromString) $ envDocHelp doc+ , content = Nothing+ }+ where+ name =+ Concat $+ addArgument $+ intersperse "|" $+ map (Code . fromString) $+ toList $+ envDocVars doc++ addArgument = case envDocMetavar doc of+ Nothing -> id+ Just arg -> (<> ["=", Variable $ fromString arg])
+ src/Ronn/OptEnvConf/Opt.hs view
@@ -0,0 +1,111 @@+-- |+--+-- Module : Ronn.OptEnvConf.Opt+-- Copyright : (c) 2024 Patrick Brisbin+-- License : AGPL-3+-- Maintainer : pbrisbin@gmail.com+-- Stability : experimental+-- Portability : POSIX+module Ronn.OptEnvConf.Opt+ ( optSynopsis+ , optDefinitions+ ) where++import Prelude++import Data.Foldable (toList)+import Data.List (intersperse)+import Data.String (IsString (..))+import Data.Text (pack)+import Data.Text qualified as T+import OptEnvConf (Parser)+import OptEnvConf.Args (Dashed (..))+import OptEnvConf.Doc (AnyDocs (..), OptDoc (..), parserOptDocs)+import Ronn.AST++optSynopsis :: Parser a -> [Part]+optSynopsis = go False . parserOptDocs+ where+ go :: Bool -> AnyDocs (Maybe OptDoc) -> [Part]+ go nested = \case+ AnyDocsCommands {} -> [] -- TODO+ AnyDocsAnd ds -> concatMap (go True) ds+ AnyDocsOr [AnyDocsSingle (Just d)] -> [Brackets $ optDocPart d] -- optional d+ AnyDocsOr ds ->+ [ (if nested then Parens else id) $+ Concat $+ intersperse " \\| " $+ concatMap (go True) ds+ ]+ AnyDocsSingle Nothing -> []+ AnyDocsSingle (Just d) -> [optDocPart d]++optDocPart :: OptDoc -> Part+optDocPart doc = bracketize go+ where+ go+ | null (optDocDasheds doc)+ , Just mv <- optDocMetavar doc =+ case optDocDefault doc of+ Nothing -> Variable $ fromString mv+ Just {} -> Brackets $ fromString mv+ | otherwise =+ Concat $+ intersperse "\\|" $+ optDashedParts doc++ bracketize = case optDocDefault doc of+ Nothing -> id+ Just {} -> Brackets++optDefinitions :: Parser a -> [Definition]+optDefinitions = go . parserOptDocs+ where+ go :: AnyDocs (Maybe OptDoc) -> [Definition]+ go = \case+ AnyDocsCommands {} -> [] -- TODO+ AnyDocsAnd ds -> concatMap go ds+ AnyDocsOr ds -> concatMap go ds+ AnyDocsSingle Nothing -> []+ AnyDocsSingle (Just d) -> [optDocDefinition d]++optDocDefinition :: OptDoc -> Definition+optDocDefinition doc =+ Definition+ { name+ , description =+ Line $+ concat+ [ maybe [] (pure . fromString) $ optDocHelp doc+ , maybe [] (\d -> pure $ Parens $ "default " <> fromString d) $ optDocDefault doc+ ]+ , content = Nothing+ }+ where+ name+ | null (optDocDasheds doc)+ , Just mv <- optDocMetavar doc =+ Code $ fromString mv+ | otherwise = Concat $ intersperse ", " $ optDashedParts doc++optDashedParts :: OptDoc -> [Part]+optDashedParts doc =+ map (\c -> Concat [Code $ "-" <> Raw (T.singleton c)]) shorts+ <> map+ (\n -> Concat $ addArgument (optDocMetavar doc) [Code $ "--" <> Raw (pack n)])+ longs+ where+ (shorts, longs) = partitionDasheds $ optDocDasheds doc++addArgument :: Maybe String -> [Part] -> [Part]+addArgument = \case+ Nothing -> id+ Just arg -> (<> ["=", Variable $ fromString arg])++partitionDasheds :: [Dashed] -> ([Char], [String])+partitionDasheds = go ([], [])+ where+ go acc@(shorts, longs) = \case+ [] -> acc+ (DashedShort c : ds) -> go (shorts <> [c], longs) ds+ (DashedLong cs : ds) -> go (shorts, longs <> [toList cs]) ds
+ tests/Main.hs view
@@ -0,0 +1,9 @@+-- |+--+-- Module : Main+-- Copyright : (c) 2024 Patrick Brisbin+-- License : AGPL-3+-- Maintainer : pbrisbin@gmail.com+-- Stability : experimental+-- Portability : POSIX+{-# OPTIONS_GHC -F -pgmF hspec-discover -Wno-missing-export-lists #-}
+ tests/Ronn/OptEnvConfSpec.hs view
@@ -0,0 +1,88 @@+-- |+--+-- Module : Ronn.OptEnvConfSpec+-- Copyright : (c) 2024 Patrick Brisbin+-- License : AGPL-3+-- Maintainer : pbrisbin@gmail.com+-- Stability : experimental+-- Portability : POSIX+module Ronn.OptEnvConfSpec+ ( spec+ ) where++import Prelude++import Data.Text (Text, unpack)+import Data.Text.IO qualified as T+import OptEnvConf+import Ronn+import Ronn.OptEnvConf+import System.FilePath ((</>))+import Test.Hspec+import Test.Hspec.Golden++spec :: Spec+spec = do+ specify "complete example" $+ let+ p :: Parser (Maybe Bool, FilePath, FilePath)+ p =+ (,,)+ <$> optional+ ( setting+ [ help "Enable debug"+ , long "debug"+ , switch True+ , env "DEBUG"+ , env "VERBOSE"+ ]+ )+ <*> setting+ [ help "Output file"+ , short 'o'+ , long "output"+ , reader str+ , metavar "FILE"+ , option+ , env "OUTPUT"+ , value "-"+ ]+ <*> setting+ [ help "Input file"+ , reader str+ , metavar "FILE"+ , argument+ , env "INPUT"+ ]+ in+ ronnGolden $+ Ronn+ { name = ManRef "ronn-opt-env-conf" ManSection1+ , description = ["example Ronn from opt-env-conf"]+ , sections =+ [ Section+ { name = "SYNOPSIS"+ , content = [Groups [Lines [Line $ Code "ronn-opt-env-conf" : optSynopsis p]]]+ }+ , Section+ { name = "OPTIONS"+ , content = [Definitions $ optDefinitions p]+ }+ , Section+ { name = "ENVIRONMENT"+ , content = [Definitions $ envDefinitions p]+ }+ ]+ }++ronnGolden :: Ronn -> Golden Text+ronnGolden ronn =+ Golden+ { output = ronnToText ronn+ , encodePretty = unpack+ , writeToFile = T.writeFile+ , readFromFile = T.readFile+ , goldenFile = "../doc" </> ronnFilePath ronn+ , actualFile = Nothing+ , failFirstTime = False+ }