# `registry-options` [![Hackage](https://img.shields.io/hackage/v/registry-options.svg)](https://hackage.haskell.org/package/registry-options) [![Build Status](https://github.com/etorreborre/registry-options/workflows/ci/badge.svg)](https://github.com/etorreborre/registry-options/actions) ##### *It's functions all the way down* # Presentation This library is an addition to the [`registry`](https://github.com/etorreborre/registry) library, supporting the parsing of options from the command line, environment variables or configuration files. # A `copy` command-line parser Here is a quick example showing how to create a parser for a simple command-line program. We want to be able to parse the following command-line arguments ``` copy -f secrets.txt .hidden ``` T `copy` is the name of the command, `-f` is a flag, and `secrets.txt`, `.hidden` are arguments. The purpose of command line parsing is to transform a list of input strings into a meaningful Haskell value: ```haskell data Copy = Copy { copyForce :: Bool, copySource :: File, copyTarget :: File } newtype File = File { _file :: Text } ``` We can then use this Haskell value to drive the execution of a `copy` function. # Define and use a Parser In order to make a parser for the `Copy` data type we create a [registry](https://github.com/etorreborre/registry) containing several declarations ```haskell import Data.Registry import Data.Registry.Options let parsers = $(makeCommand ''Copy [shortDescription "copy a file from SOURCE to TARGET"]) <: argument @"source" @File [metavar "SOURCE", help "Source path"] <: argument @"target" @File [metavar "TARGET", help "Target path"] <: switch @"force" [help "Overwrite when a file with the same name already exists"] <: decoderOf File <: defaults ``` That registry allows us to make a parser capable of creating a `Copy` value from command-line arguments ```haskell let copyParser = make @(Parser Command Copy) parsers parse copyParser "copy -f secrets.txt .hidden" === Right (Copy True "secrets.txt" ".hidden") ``` # Display the help We can also use the library to display the help of any Parser ```haskell let copyParser = make @(Parser Command Copy) parsers putStrLn $ displayHelp (parserHelp copyParser) ``` and the output is ```haskell copy - copy a file from SOURCE to TARGET USAGE copy [-f|--force] [SOURCE] [TARGET] OPTIONS -f,--force BOOL Force the action even if a file already exists with the same name SOURCE Source path TARGET Target path ``` _Note_: via the use of another registry it is possible to customize any part of the help. See the documentation and functions in `Data.Registry.Options.DisplayHelpBox` on how to override various sections of the help text. # Read option values When we want to effectively run a parser and retrieve values we call the `run` function ```haskell run @Command @Copy parsers :: IO (Either Text Copy) ``` The `run` function takes the `Copy` parser registry and uses some default sources to access option values. By default the option values come from 3 different sources with the following priorities: 1. (highest priority) environment variables 2. "command line arguments 3. a YAML configuration file (off by default) If you want to use a YAML configuration file, you can user the `runWith` function ```haskell runWith @Command @Copy (setConfigFilePath ".configuration.yaml") parsers ``` # You want to know more? - fully developed [example][example]: we explain in detail all the declarations above and their role - [motivations][motivations]: why was this library created? How does it differ from similar libraries? - [sources][sources]: how to configure and extend sources [example]: http://github.com/etorreborre/registry-options/blob/main/doc/example.md [motivations]: http://github.com/etorreborre/registry-options/blob/main/doc/motivations.md [sources]: http://github.com/etorreborre/registry-options/blob/main/doc/sources.md