optparse-applicative-dex (empty) → 1.0.0
raw patch · 7 files changed
+247/−0 lines, 7 filesdep +basedep +optparse-applicativedep +prettyprinter
Dependencies added: base, optparse-applicative, prettyprinter, text
Files
- .gitignore +5/−0
- CHANGELOG.md +3/−0
- LICENSE +15/−0
- README.md +58/−0
- optparse-applicative-dex.cabal +54/−0
- src/lib/Options/Applicative/Dex.hs +108/−0
- stack.yaml +4/−0
+ .gitignore view
@@ -0,0 +1,5 @@+# stack uses this directory for build artifacts+/.stack-work/++# Made by 'hasktags --ctags .'+tags
+ CHANGELOG.md view
@@ -0,0 +1,3 @@+1.0.0 (2025-09-05)++ * Initial release
+ LICENSE view
@@ -0,0 +1,15 @@+Copyright (c) 2025, Dino Morelli <dino@ui3.info>++Permission to use, copy, modify, and/or distribute this software+for any purpose with or without fee is hereby granted, provided+that the above copyright notice and this permission notice appear+in all copies.++THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL+WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED+WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE+AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA+OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR+PERFORMANCE OF THIS SOFTWARE.
+ README.md view
@@ -0,0 +1,58 @@+# optparse-applicative-dex+++## Synopsis++Extra functions for working with optparse-applicative+++## Description++optparse-applicative is a fantastic library++My usage of it has often used the same features wrapped in a `parseOpts`+function along with a version helper.++This package abstracts that code into a re-usable library, minimizing pasting+between projects.++In most CLI projects I almost always want:++- A header consisting of the program name and a short description+- A helper parser to provide -h, --help+- A version helper to respond to a --version option with shorter output than -h, --help+- Some additional usage info below the generated switch usage++The parseOpts' and parseOptsWithWidth functions in this library take a parser+and arguments for header, footer and the app version as generated by cabal and+do all these things automatically.++A simple example:++ {- # LANGUAGE OverloadedStrings #-}++ import Options.Applicative.Dex+ import Paths_your_app (version)++ data Options = Options { optA :: String , optB :: Bool }+ deriving Show++ parser :: Parser Options+ parser = Options+ <$> option str ( short 'a' <> metavar "STR" <> help "The a option, a string" )+ <*> switch ( short 'b' <> help "The b option, a switch")++ main :: IO ()+ main = do+ opts <- parseOpts' parser "header-info" "footer-info" version+ print opts+++## Getting source++Source code is available from codeberg at the [optparse-applicative-dex](https://codeberg.org/dinofp/optparse-applicative-dex) project page.+++## Contact++Dino Morelli <dino@ui3.info>
+ optparse-applicative-dex.cabal view
@@ -0,0 +1,54 @@+cabal-version: 2.2++name: optparse-applicative-dex+version: 1.0.0+synopsis: Extra functions for working with optparse-applicative+description:+ optparse-applicative is a fantastic library+ .+ My usage of it has often used the same features wrapped in a `parseOpts`+ function along with a version helper.+ .+ This package abstracts that code into a re-usable library, minimizing pasting+ between projects.+author: Dino Morelli+maintainer: dino@ui3.info+copyright: 2025 Dino Morelli+category: CLI, Console, Options, Parsing+license: ISC+license-file: LICENSE+build-type: Simple+extra-source-files:+ .gitignore+ README.md+ stack.yaml+extra-doc-files:+ CHANGELOG.md++source-repository head+ type: git+ location: https://codeberg.org/dinofp/optparse-applicative-dex++common lang+ default-language: Haskell2010+ ghc-options:+ -fwarn-tabs+ -Wall+ -Wcompat+ -Wderiving-typeable+ -Wincomplete-record-updates+ -Wincomplete-uni-patterns+ -Wpartial-fields+ -Wredundant-constraints++library+ import: lang+ exposed-modules:+ Options.Applicative.Dex+ hs-source-dirs:+ src/lib+ build-depends:+ base >=3 && <5+ , optparse-applicative >=0.17.1 && <0.19+ , prettyprinter >=1.7.1 && <2+ , text >=1.11.1 && <3
+ src/lib/Options/Applicative/Dex.hs view
@@ -0,0 +1,108 @@+{-|+optparse-applicative is a fantastic library++My usage of it has often used the same features wrapped in a `parseOpts`+function along with a version helper.++This package abstracts that code into a re-usable library, minimizing pasting+between projects.++In most projects I almost always want:++- A header consisting of the program name and a short description+- A helper parser to provide -h, --help+- A version helper to respond to a --version option with shorter output than -h, --help+- Some additional usage info below the generated switch usage++The parseOpts' and parseOptsWithWidth functions in this library take a parser+and arguments for header, footer and the app version as generated by cabal and+do all these things automatically.++A simple example:++@+{- # LANGUAGE OverloadedStrings #-}++import Options.Applicative.Dex+import Paths_your_app (version)++data Options = Options { optA :: String , optB :: Bool }+ deriving Show++parser :: Parser Options+parser = Options+ <$> option str ( short 'a' <> metavar "STR" <> help "The a option, a string" )+ <*> switch ( short 'b' <> help "The b option, a switch")++main :: IO ()+main = do+ opts <- parseOpts' parser "header-info" "footer-info" version+ print opts+@+-}++module Options.Applicative.Dex+ (+ -- * Option parser functions+ parseOpts'+ , parseOptsWithWidth++ -- * Re-exporting everything from optparse-applicative+ , module Options.Applicative+ )+ where++import Data.Text.Lazy (Text, unpack)+import Data.Version (Version, showVersion)+import Options.Applicative+import Prettyprinter (pretty)+import System.Environment (getProgName)+++versionHelper :: String -> Version -> Parser (a -> a)+versionHelper progName version =+ infoOption (progName <> " " <> showVersion version) $ mconcat+ [ long "version"+ , help "Show version information"+ , hidden+ ]+++{-|+ Main opts parsing entry point++ This is named with a ' so the `parseOpts` identifier can be re-used by your+ code. For example in an Opts module where you define your parser and other+ usage content.+-}+parseOpts'+ :: Parser a -- ^ CLI arguments parser made with optparse-applicative API+ -> Text -- ^ One-line app description for the usage header+ -> Text -- ^ Content for usage footer (after switches)+ -> Version -- ^ Application version+ -> IO a+parseOpts' = parseOptsWithWidth 100+++{-|+ Opts parsing with column limit as an argument++ This library defaults to setting the columns to 100 instead of the+ optparse-applicative default of 80 columns. I found 80 to be kind of+ restrictive, 100 seems like a better default. Use this function to set a+ custom width.+-}+parseOptsWithWidth+ :: Int -- ^ Wrap column+ -> Parser a -- ^ CLI arguments parser made with optparse-applicative API+ -> Text -- ^ One-line app description for the usage header+ -> Text -- ^ Content for usage footer (after switches)+ -> Version -- ^ Application version+ -> IO a+parseOptsWithWidth cols parser headerContent footerContent version = do+ pn <- getProgName+ customExecParser (prefs $ columns cols)+ $ info (parser <**> helper <**> versionHelper pn version)+ ( header (pn <> " - " <> unpack headerContent)+ <> (footerDoc . Just . pretty $ footerContent)+ )
+ stack.yaml view
@@ -0,0 +1,4 @@+snapshot: lts-22.6++packages:+- .