Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/etorreborre/registry-options

options parsing using registry
https://github.com/etorreborre/registry-options

Last synced: 7 days ago
JSON representation

options parsing using registry

Awesome Lists containing this project

README

        

# `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