registry-options: application options parsing

[ data, library, mit ] [ Propose Tags ]
Versions [RSS] 0.1.0.0, 0.2.0.0
Dependencies base (>=4.7 && <5), boxes (>=0.1 && <1), bytestring (>=0.10 && <1), containers (>=0.2 && <1), HsYAML (>=0.2 && <1), multimap (>=1.2 && <2), protolude (>=0.3 && <0.4), registry (>=0.4 && <1), template-haskell (>=2.13 && <3.0), text (>=1 && <2), th-lift (>=0.8 && <1), transformers (>=0.5 && <2), unordered-containers (>=0.2 && <1), vector (>=0.1 && <1) [details]
License MIT
Author
Maintainer etorreborre@yahoo.com
Category Data
Source repo head: git clone https://github.com/etorreborre/registry-options
Uploaded by etorreborre at 2022-11-24T14:19:12Z
Distributions LTSHaskell:0.1.0.0, NixOS:0.1.0.0
Downloads 42 total (15 in the last 30 days)
Rating (no votes yet) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Docs uploaded by user
Build status unknown [no reports yet]

Readme for registry-options-0.2.0.0

[back to package description]

registry-options

Hackage Build Status

It's functions all the way down

Presentation

This library is an addition to the 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:

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 containing several declarations

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

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

let copyParser = make @(Parser Command Copy) parsers
putStrLn $ displayHelp (parserHelp copyParser)

and the output is

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

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

runWith @Command @Copy (setConfigFilePath ".configuration.yaml") parsers

You want to know more?

  • fully developed example: we explain in detail all the declarations above and their role
  • motivations: why was this library created? How does it differ from similar libraries?
  • sources: how to configure and extend sources