Skip to content

Commit

Permalink
Parse proposed dockmaster.yml file
Browse files Browse the repository at this point in the history
  • Loading branch information
samtay committed Dec 13, 2016
1 parent deda625 commit e390a55
Show file tree
Hide file tree
Showing 8 changed files with 136 additions and 11 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
*.swp
dist
dist-*
cabal-dev
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
# dockmaster
command line utility providing conveniences around docker-compose

### resources
[wiki on arg handling](https://wiki.haskell.org/Tutorials/Programming_Haskell/Argument_handling)
[bad ass opt package](https://github.com/pcapriotti/optparse-applicative)
12 changes: 9 additions & 3 deletions app/Main.hs
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
{-# LANGUAGE OverloadedStrings #-}
module Main where

import Lib
import Dockmaster.Types

main :: IO ()
main = someFunc
import Data.Yaml
import qualified Data.ByteString as BS

main = do
ymlData <- BS.readFile "dockmaster.yml"
let d = decodeEither ymlData :: Either String Dockmaster
print d
10 changes: 9 additions & 1 deletion dockmaster.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,20 @@ cabal-version: >=1.10

library
hs-source-dirs: src
exposed-modules: Lib
exposed-modules: Dockmaster.Types
build-depends: base >= 4.7 && < 5
, yaml
, text
, unordered-containers
default-language: Haskell2010

executable dockmaster-exe
hs-source-dirs: app
main-is: Main.hs
ghc-options: -threaded -rtsopts -with-rtsopts=-N
build-depends: base
, yaml
, bytestring
, dockmaster
default-language: Haskell2010

Expand All @@ -33,6 +38,9 @@ test-suite dockmaster-test
main-is: Spec.hs
build-depends: base
, dockmaster
, directory
, yaml
, bytestring
ghc-options: -threaded -rtsopts -with-rtsopts=-N
default-language: Haskell2010

Expand Down
65 changes: 65 additions & 0 deletions src/Dockmaster/Types.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
{-# LANGUAGE OverloadedStrings #-}
module Dockmaster.Types where

import Data.Yaml
import Control.Applicative
import Data.HashMap.Lazy (HashMap, lookup, member)
import Prelude hiding (lookup)
import qualified Data.Text as T

-- | Dockmaster configuration (specified by dockmaster.yml)
data Dockmaster = Dockmaster { dmFile :: Maybe ComposeFile
, dmTargets :: [Target]
, dmCommands :: [HashMap T.Text CommandConfig]
} deriving (Show)

-- | Configuration for docker-compose.yml file template & vars
data ComposeFile = ComposeFile { cfPath :: Maybe String
, cfConfig :: [String]
} deriving (Show)

-- | Targets are used to identify where compositions are run
data Target = Target { targetName :: Maybe String
, targetType :: Maybe String
, targetMachine :: Maybe String
} deriving (Show)

-- | Hooks can be specified by filename or direct shell command
data Hook = File String | Shell String deriving (Show)

-- | Configuration for each command
data CommandConfig = CommandConfig { ccCompose :: Bool
, ccPreHooks :: [Hook]
, ccPostHooks :: [Hook]
} deriving (Show)

instance FromJSON ComposeFile where
parseJSON (Object v) = ComposeFile
<$> v .:? "path"
<*> v .:? "config" .!= []

instance FromJSON Target where
parseJSON (Object v) = Target
<$> v .:? "name"
<*> v .:? "type"
<*> v .:? "machine"

instance FromJSON Hook where
parseJSON (Object v)
| member "file" v = File <$> v .: "file"
| member "shell" v = Shell <$> v .: "shell"
| otherwise = error "Hooks are specified by file or shell only"

instance FromJSON CommandConfig where
parseJSON (Object v) = CommandConfig
<$> v .:? "compose" .!= True
<*> v .:? "pre_hooks" .!= []
<*> v .:? "post_hooks" .!= []

instance FromJSON Dockmaster where
parseJSON (Object v) = Dockmaster
<$> v .:? "file"
<*> v .:? "targets" .!= []
<*> v .:? "commands" .!= []
-- A non-Object value is of the wrong type, so fail.
parseJSON _ = error "Can't parse Dockmaster from YAML/JSON"
6 changes: 0 additions & 6 deletions src/Lib.hs

This file was deleted.

25 changes: 24 additions & 1 deletion test/Spec.hs
Original file line number Diff line number Diff line change
@@ -1,2 +1,25 @@
module Main where

import Data.Yaml
import Dockmaster.Types
import qualified Data.ByteString as BS
import Data.Maybe
import System.Exit
import System.Directory

parseDockmasterYml :: FilePath -> IO Bool
parseDockmasterYml "." = return True
parseDockmasterYml ".." = return True
parseDockmasterYml file = do
contents <- BS.readFile $ "./test/fixtures/" ++ file
case (decodeEither contents :: Either String Dockmaster) of
(Left e) -> putStrLn ("Failed to parse " ++ file ++":") >> putStrLn e >> return False
otherwise -> putStrLn ("Parsed " ++ file ++ " successfully.") >> return True

main :: IO ()
main = putStrLn "Test suite not yet implemented"
main = do
files <- getDirectoryContents "./test/fixtures/"
results <- mapM parseDockmasterYml files
if and results
then exitWith ExitSuccess
else exitWith (ExitFailure 1)
24 changes: 24 additions & 0 deletions test/fixtures/dockmaster.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
file:
path: docker-compose.j2
config:
- /etc/dockmaster/defaults.yml
- env.vars

targets:
- name: node-a
type: docker-machine

# optional, defaults to name
machine: node-a

commands:
- up:
pre_hooks:
- file: relative_path/to/hook.sh
- file: /absolute/path/to/hook.sh
- shell: rm -rf .working
- wiggle:
compose: false
# ^^^ does not call docker-compose between pre- and post- hooks.
pre_hooks:
- file: wiggle.sh

0 comments on commit e390a55

Please sign in to comment.