Skip to content

Commit

Permalink
Migrate dhall-{bash,json,text} into this repository (#661)
Browse files Browse the repository at this point in the history
The motivation for this change is:

* To catch build failures in downstream packages whenever we make a breaking
  change to the `dhall` API
* To reduce the amount of work I need in order to cut a release for all of
  these packages
* To better share Nix/CI-related logic between the projects

Note that I have not yet migrated `dhall-nix` in.  I'm waiting for
dhall-lang/dhall-nix#17 to be fixed since
`dhall-nix` is incompatible with later versions of `megaparsec` due to
`hnix`.
  • Loading branch information
Gabriella439 committed Oct 29, 2018
1 parent 6fd4c83 commit aecfbc9
Show file tree
Hide file tree
Showing 539 changed files with 2,601 additions and 162 deletions.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright (c) 2017 Gabriel Gonzalez
Copyright (c) 2018 Gabriel Gonzalez
All rights reserved.

Redistribution and use in source and binary forms, with or without
Expand Down
141 changes: 12 additions & 129 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,142 +1,25 @@
# `dhall 1.18.0`
# `dhall-haskell`

Dhall is a programmable configuration language that is not Turing-complete
This repository is a shared repository for all of the `dhall-*` Haskell
packages, including:

You can think of Dhall as: JSON + functions + types + imports
* [`dhall`](./dhall)
* [`dhall-bash`](./dhall-bash)
* [`dhall-json`](./dhall-json)
* [`dhall-text`](./dhall-text)

You will probably want to read the language-agnostic README here:
Navigate to each package's directory for their respective `README`s

* [`dhall-lang` `README`](https://github.com/dhall-lang/dhall-lang/blob/master/README.md)
# Quick start

This repository (and this `README`) focuses on the Haskell implementation of
Dhall
You can build all of the packages by running:

## Motivation

*"Why not configure my program using JSON or YAML?"*

JSON or YAML are suitable for small configuration files, but larger
configuration files with complex schemas require programming language features
to reduce repetition. Otherwise, the repetitive configuration files become
error-prone and difficult to maintain/migrate.

This post explains in more detail the motivation behind programmable
configuration files:

* [Programmable configuration files](https://github.com/dhall-lang/dhall-lang/wiki/Programmable-configuration-files)

*"Why not configure my program using Haskell code?"*

You probably don't want to rebuild your program every time you make a
configuration change. Recompilation is slow and requires the GHC toolchain
to be installed anywhere you want to make configuration changes.

## Quick start

Given this Haskell program saved to `example.hs`:

```haskell
-- example.hs

{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}

import Dhall

data Example = Example { foo :: Integer, bar :: Vector Double }
deriving (Generic, Show)

instance Interpret Example

main :: IO ()
main = do
x <- input auto "./config"
print (x :: Example)
```

... which reads in this configuration file:

```bash
$ cat ./config
{ foo = 1
, bar = ./bar
}
```

... which in turn references this other file:

```
$ cat ./bar
[3.0, 4.0, 5.0]
```

... you can interpret the Haskell program like this:

```bash
$ nix-shell nix/test-dhall.nix
[nix-shell]$ runghc example.hs
Example {foo = 1, bar = [3.0,4.0,5.0]}
```

You can also interpret Dhall programs directly using the installed command-line
compiler:

```bash
$ dhall
List/head Double ./bar
<Ctrl-D>
Optional Double

Some 3.0
```

... and you can reference remote expressions or functions by their URL, too:

```bash
$ dhall
let null = https://raw.githubusercontent.com/dhall-lang/Prelude/35deff0d41f2bf86c42089c6ca16665537f54d75/List/null
in null Double ./bar
<Ctrl-D>
Bool

False
```

Now go read the
[Dhall tutorial](https://hackage.haskell.org/package/dhall/docs/Dhall-Tutorial.html)
to learn more

## Building this project

Nix + Cabal is the recommended workflow for project development since continuous
integration uses Nix to build and test the project. Other development tools and
workflows are also supported on a best-effort basis.

You can build the project using only Nix by running this command from the root
of the repository:

```bash
$ nix-build
```

More commonly, you will want to incrementally build the project using `cabal`.
You can either do so inside of a `nix-shell`:

```bash
$ nix-shell
[nix-shell]$ cabal configure
[nix-shell]$ cabal build
[nix-shell]$ cabal test
```

... or you can add `nix: True` to your `~/.cabal/config` file and then you can
run the same `cabal` commands without an explicit `nix-shell`:

```bash
$ cabal configure
$ cabal build
$ cabal test
```
... or you can run `nix-build` within each package's respective directory to
build just that one package.

## Development status

Expand Down
6 changes: 5 additions & 1 deletion default.nix
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
(import ./shared.nix {}).dhall
let
shared = import ./nix/shared.nix {};

in
{ inherit (shared) dhall dhall-bash dhall-json dhall-text; }
27 changes: 27 additions & 0 deletions dhall-bash/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
Copyright (c) 2018 Gabriel Gonzalez
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

3. Neither the name of the author nor the names of its contributors may be
used to endorse or promote products derived from this software without
specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 changes: 34 additions & 0 deletions dhall-bash/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# `dhall-bash 1.0.16`

[![Hackage](https://img.shields.io/hackage/v/dhall-bash.svg)](https://hackage.haskell.org/package/dhall-bash)

This `dhall-bash` package provides a Dhall to Bash compiler so that you can
easily marshall Dhall values into your Bash scripts

This does not compile all available Dhall language constructs into Bash and
only supports extracting primitive values, lists, optional values and records
from normalized expressions.

## Quick start

If you have Nix installed, then you can build and install this package using:

```bash
$ nix-env --install --file default.nix
$ dhall-to-bash <<< '1'
1
$ dhall-to-bash <<< '"ABC" ++ "DEF"'
ABCDEF
$ dhall-to-bash --declare FOO <<< '"ABC" ++ "DEF"'
declare -r FOO=ABCDEF
$ eval $(dhall-to-bash --declare FOO <<< '"ABC" ++ "DEF"')
$ echo "${FOO}"
ABCDEF
$ dhall-to-bash --declare BAR
let replicate = https://ipfs.io/ipfs/QmcTbCdS21pCxXysTzEiucDuwwLWbLUWNSKwkJVfwpy2zK/Prelude/List/replicate
in replicate +10 Integer 1
<Ctrl-D>
declare -r -a BAR=(1 1 1 1 1 1 1 1 1 1)
$ dhall-to-bash --declare BAZ <<< '{ qux = 1, xyzzy = True }'
declare -r -A BAZ=([qux]=1 [xyzzy]=true)
```
File renamed without changes.
1 change: 1 addition & 0 deletions dhall-bash/default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
(import ../nix/shared.nix {}).dhall-bash
51 changes: 51 additions & 0 deletions dhall-bash/dhall-bash.cabal
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
Name: dhall-bash
Version: 1.0.16
Cabal-Version: >=1.8.0.2
Build-Type: Simple
Tested-With: GHC == 7.10.2, GHC == 8.0.1
License: BSD3
License-File: LICENSE
Copyright: 2017 Gabriel Gonzalez
Author: Gabriel Gonzalez
Maintainer: Gabriel439@gmail.com
Bug-Reports: https://github.com/dhall-lang/dhall-haskell/issues
Synopsis: Compile Dhall to Bash
Description:
Use this package if you want to compile Dhall expressions to Bash.
You can use this package as a library or an executable:
.
* See the "Dhall.Bash" module if you want to use this package as a library
.
* Use the @dhall-to-bash@ if you want an executable
.
The "Dhall.Bash" module also contains instructions for how to use this
package
Category: Compiler
Source-Repository head
Type: git
Location: https://github.com/dhall-lang/dhall-haskell/tree/master/dhall-bash

Library
Hs-Source-Dirs: src
Build-Depends:
base >= 4.8.0.0 && < 5 ,
bytestring < 0.11,
containers < 0.6 ,
dhall >= 1.18.0 && < 1.19,
neat-interpolation < 0.4 ,
shell-escape < 0.3 ,
text >= 0.2 && < 1.3
Exposed-Modules: Dhall.Bash
GHC-Options: -Wall

Executable dhall-to-bash
Hs-Source-Dirs: exec
Main-Is: Main.hs
Build-Depends:
base ,
bytestring ,
dhall ,
dhall-bash ,
optparse-generic >= 1.1.1 && < 1.4 ,
text
GHC-Options: -Wall
73 changes: 73 additions & 0 deletions dhall-bash/exec/Main.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TypeOperators #-}

module Main where

import Control.Exception (SomeException)
import Data.ByteString (ByteString)
import Options.Generic (Generic, ParseRecord, type (<?>)(..))
import System.Exit (ExitCode(..))

import qualified Control.Exception
import qualified Data.ByteString
import qualified Data.Text.IO
import qualified Dhall
import qualified Dhall.Bash
import qualified Dhall.Import
import qualified Dhall.Parser
import qualified Dhall.TypeCheck
import qualified GHC.IO.Encoding
import qualified Options.Generic
import qualified System.Exit
import qualified System.IO

data Options = Options
{ explain :: Bool
<?> "Explain error messages in detail"
, declare :: Maybe ByteString
<?> "Declare the given variable as a statement instead of an expression"
} deriving (Generic, ParseRecord)

main :: IO ()
main = do
GHC.IO.Encoding.setLocaleEncoding GHC.IO.Encoding.utf8
Options {..} <- Options.Generic.getRecord "Compile Dhall to Bash"

(if unHelpful explain then Dhall.detailed else id) (handle (do
inText <- Data.Text.IO.getContents

expr <- case Dhall.Parser.exprFromText "(stdin)" inText of
Left err -> Control.Exception.throwIO err
Right expr -> return expr

expr' <- Dhall.Import.load expr
case Dhall.TypeCheck.typeOf expr' of
Left err -> Control.Exception.throwIO err
Right _ -> return ()

bytes <- case unHelpful declare of
Nothing -> do
case Dhall.Bash.dhallToExpression expr' of
Left err -> Control.Exception.throwIO err
Right bytes -> return bytes
Just var -> do
case Dhall.Bash.dhallToStatement expr' var of
Left err -> Control.Exception.throwIO err
Right bytes -> return bytes
Data.ByteString.putStr bytes ))

handle :: IO a -> IO a
handle = Control.Exception.handle handler
where
handler :: SomeException -> IO a
handler e = case Control.Exception.fromException e of
Just ExitSuccess -> do
Control.Exception.throwIO e
_ -> do
System.IO.hPutStrLn System.IO.stderr ""
System.IO.hPrint System.IO.stderr e
System.Exit.exitFailure
1 change: 1 addition & 0 deletions dhall-bash/shell.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
(import ../nix/shared.nix {}).shell-dhall-bash
Loading

0 comments on commit aecfbc9

Please sign in to comment.