language-dockerfile

Forked from hadolint. All functions for parsing, printing and writting Dockerfiles are exported through Language.Dockerfile. For more fine-grained operations look for specific modules that implement a certain functionality. There are two flags in this package, which enable building two executables: hadolint Enables building the hadolint executable, though you might prefer to use the hadolint package directly - dockerfmt Builds example pretty-printer usage, which reads a Dockerfile and pretty-prints it to stdout See the GitHub project for the source-code and examples.


Keywords
gpl, library, test, Language.Dockerfile, Language.Dockerfile.Bash, Language.Dockerfile.EDSL, Language.Dockerfile.EDSL.Quasi, Language.Dockerfile.EDSL.Types, Language.Dockerfile.FormatCheck, Language.Dockerfile.Lexer, Language.Dockerfile.Normalize, Language.Dockerfile.Parser, Language.Dockerfile.Predef, Language.Dockerfile.PrettyPrint, Language.Dockerfile.Rules, Language.Dockerfile.Syntax, Language.Dockerfile.Syntax.Lift, Hackage, GH Pages Haddock, Blog Post in Portuguese, hadolint, language-dockerfile, Parsing files, Parsing strings, Pretty-printing files, Writing Dockerfiles in Haskell, Using the QuasiQuoter, Templating Dockerfiles in Haskell, Using IO in the DSL
License
GPL-3.0
Install
cabal install language-dockerfile-0.3.6.0

Documentation

haskell-language-dockerfile

Build Status CircleCI

Hackage

GH Pages Haddock

Blog Post in Portuguese


Dockerfile linter, parser, pretty-printer and embedded DSL, forked from hadolint.

Published on Hackage as language-dockerfile.

It extends hadolint with the pretty-printer and EDSL for writting Dockerfiles in Haskell.

Parsing files

import Language.Dockerfile
main = do
    ef <- parseFile "./Dockerfile"
    print ef

Parsing strings

import Language.Dockerfile
main = do
    c <- readFile "./Dockerfile"
    print (parseString c)

Pretty-printing files

import Language.Dockerfile
main = do
    Right d <- parseFile "./Dockerfile"
    putStr (prettyPrint d)

Writing Dockerfiles in Haskell

{-# LANGUAGE OverloadedStrings #-}
import Language.Dockerfile
main = putStr $ toDockerfileStr $ do
    from "node"
    run "apt-get update"
    runArgs ["apt-get", "install", "something"]
    -- ...

Using the QuasiQuoter

{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes       #-}
import Language.Dockerfile
main = putStr $ toDockerfileStr $ do
    from "node"
    run "apt-get update"
    [edockerfile|
    RUN apt-get update
    CMD node something.js
    |]
    -- ...

Templating Dockerfiles in Haskell

{-# LANGUAGE FlexibleContexts  #-}
{-# LANGUAGE OverloadedStrings #-}
import Control.Monad
import Language.Dockerfile
tags = ["7.8", "7.10", "8"]
cabalSandboxBuild packageName = do
    let cabalFile = packageName ++ ".cabal"
    run "cabal sandbox init"
    run "cabal update"
    add cabalFile ("/app/" ++ cabalFile)
    run "cabal install --only-dep -j"
    add "." "/app/"
    run "cabal build"
main =
    forM_ tags $ \tag -> do
        let df = toDockerfileStr $ do
            from ("haskell" `tagged` tag)
            cabalSandboxBuild "mypackage"
        writeFile ("./examples/templating-" ++ tag ++ ".dockerfile") df

Using IO in the DSL

By default the DSL runs in the Identity monad. By running in IO we can support more features like file globbing:

{-# LANGUAGE OverloadedStrings #-}
import           Language.Dockerfile
import qualified System.Directory     as Directory
import qualified System.FilePath      as FilePath
import qualified System.FilePath.Glob as Glob
main = do
    str <- toDockerfileStrIO $ do
        fs <- liftIO $ do
            cwd <- Directory.getCurrentDirectory
            fs <- Glob.glob "./test/*.hs"
            return (map (FilePath.makeRelative cwd) fs)
        from "ubuntu"
        mapM_ (\f -> add f ("/app/" ++ FilePath.takeFileName f)) fs
    putStr str

License

GPLv3