nemesis-titan 2013.7.13.1 → 2013.7.14
raw patch · 2 files changed
+126/−50 lines, 2 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- System.Nemesis.Titan: defaultConfig :: Config
- System.Nemesis.Titan: label :: Config -> String
+ System.Nemesis.Titan: MacAppArgs :: String -> Maybe String -> String -> [String] -> Config -> Maybe String -> Maybe String -> MacAppArgs
+ System.Nemesis.Titan: __bin_directory :: :-> Config String
+ System.Nemesis.Titan: __config_directory :: :-> Config String
+ System.Nemesis.Titan: __derived_data_path :: :-> MacAppArgs String
+ System.Nemesis.Titan: __file_name :: :-> Config String
+ System.Nemesis.Titan: __frameworks :: :-> MacAppArgs [String]
+ System.Nemesis.Titan: __ghc_arg_string :: :-> Config String
+ System.Nemesis.Titan: __ghc_default_arg_string :: :-> Config String
+ System.Nemesis.Titan: __guard_arg_string :: :-> Config String
+ System.Nemesis.Titan: __guard_default_arg_string :: :-> Config String
+ System.Nemesis.Titan: __haskell_source_directory :: :-> Config String
+ System.Nemesis.Titan: __mac_app_config :: :-> MacAppArgs Config
+ System.Nemesis.Titan: __mac_app_file_name :: :-> MacAppArgs (Maybe String)
+ System.Nemesis.Titan: __mac_app_project_name :: :-> MacAppArgs (Maybe String)
+ System.Nemesis.Titan: __pid_name :: :-> Config String
+ System.Nemesis.Titan: __project_name :: :-> Config String
+ System.Nemesis.Titan: __scheme_name :: :-> MacAppArgs (Maybe String)
+ System.Nemesis.Titan: __target_name :: :-> MacAppArgs String
+ System.Nemesis.Titan: data MacAppArgs
+ System.Nemesis.Titan: derived_data_path :: MacAppArgs -> String
+ System.Nemesis.Titan: frameworks :: MacAppArgs -> [String]
+ System.Nemesis.Titan: instance Default MacAppArgs
+ System.Nemesis.Titan: instance Show MacAppArgs
+ System.Nemesis.Titan: mac_app_config :: MacAppArgs -> Config
+ System.Nemesis.Titan: mac_app_file_name :: MacAppArgs -> Maybe String
+ System.Nemesis.Titan: mac_app_project_name :: MacAppArgs -> Maybe String
+ System.Nemesis.Titan: project_name :: Config -> String
+ System.Nemesis.Titan: scheme_name :: MacAppArgs -> Maybe String
+ System.Nemesis.Titan: target_name :: MacAppArgs -> String
- System.Nemesis.Titan: titan_mac_app :: String -> String -> FilePath -> String -> String -> Unit
+ System.Nemesis.Titan: titan_mac_app :: MacAppArgs -> Unit
Files
- nemesis-titan.cabal +1/−1
- src/System/Nemesis/Titan.hs +125/−49
nemesis-titan.cabal view
@@ -1,5 +1,5 @@ Name: nemesis-titan-Version: 2013.7.13.1+Version: 2013.7.14 Build-type: Simple Synopsis: A collection of Nemesis tasks to bootstrap a Haskell project with a focus on continuous integration Description:
src/System/Nemesis/Titan.hs view
@@ -7,9 +7,10 @@ import System.Nemesis.Env import System.Nemesis (Unit) -import Air.Env+import Air.Env hiding (mod) import Prelude ()-import Air.TH (here, mkDefault)+import Air.TH+import Air.Data.Record.SimpleLabel (get, set, mod) import qualified Data.ByteString.Char8 as B import qualified Data.UUID as UUID@@ -24,17 +25,19 @@ import Text.StringTemplate import Text.Printf +import Data.Maybe (fromMaybe)+ angel_template :: StringTemplate String angel_template = newSTMP - [here| server {- exec = "runghc Nemesis $label$/run"+ exec = "runghc Nemesis $project_name$/run" stdout = "/dev/stdout" stderr = "/dev/stderr" delay = 0 } code-reload {- exec = "runghc Nemesis $label$/guard"+ exec = "runghc Nemesis $project_name$/guard" stdout = "/dev/stdout" stderr = "/dev/stderr" delay = 0@@ -45,7 +48,7 @@ angel_live_template :: StringTemplate String angel_live_template = newSTMP - [here| server {- exec = "runghc Nemesis $label$/run"+ exec = "runghc Nemesis $project_name$/run" stdout = "/dev/stdout" stderr = "/dev/stderr" delay = 0@@ -70,7 +73,7 @@ sleep update_interval if event_time > update_time update_time = Time.now- system("runghc Nemesis $label$/compile-and-kill")+ system("runghc Nemesis $project_name$/compile-and-kill") end end end@@ -88,7 +91,7 @@ spec :: IO () spec = hspec \$ do- describe "$label$" \$ do+ describe "$project_name$" \$ do it "should run spec" True main = do@@ -102,7 +105,7 @@ it "should run spec" True it "should use templates" - do- let text = render - setAttribute "label" "Main" angel_template+ let text = render - setAttribute "project_name" "Main" angel_template -- puts text @@ -116,7 +119,7 @@ , bin_directory :: String , config_directory :: String , haskell_source_directory :: String- , label :: String+ , project_name :: String , file_name :: String , ghc_arg_string :: String , ghc_default_arg_string :: String@@ -125,46 +128,50 @@ } deriving (Show, Eq) -mkDefault ''Config-+mkLabel ''Config -defaultConfig :: Config-defaultConfig = def+instance Default Config where+ def = Config { pid_name = "uuid.txt" , bin_directory = ".bin" , config_directory = "config" , haskell_source_directory = "src"+ , project_name = "Main"+ , file_name = "Main.hs"+ , ghc_arg_string = def , ghc_default_arg_string = "-threaded"+ , guard_arg_string = def , guard_default_arg_string = "--no-bundler-warning --no-interactions" } + titan_with_config :: Config -> Unit titan_with_config config = do- namespace (config.label) - do+ namespace (config.project_name) - do let - _label = config.label- config_label_directory = config.config_directory / _label- angel_path = config_label_directory / "Angel.conf"- angel_live_path = config_label_directory / "AngelLive.conf"- guard_path = config_label_directory / "Guardfile"+ _project_name = config.project_name+ config_project_name_directory = config.config_directory / _project_name+ angel_path = config_project_name_directory / "Angel.conf"+ angel_live_path = config_project_name_directory / "AngelLive.conf"+ guard_path = config_project_name_directory / "Guardfile" - pid_directory = config.bin_directory / _label+ pid_directory = config.bin_directory / _project_name pid_path = pid_directory / config.pid_name haskell_source_path = config.haskell_source_directory / config.file_name desc "Initialize a Titan node" task "init" - io - do- createDirectoryIfMissing True config_label_directory+ createDirectoryIfMissing True config_project_name_directory createDirectoryIfMissing True (config.haskell_source_directory) let - angel_file_content = render - setAttribute "label" _label angel_template- angel_live_file_content = render - setAttribute "label" _label angel_live_template- guard_file_content = render - setAttribute "label" _label guard_template- haskell_file_content = render - setAttribute "label" _label haskell_template+ angel_file_content = render - setAttribute "project_name" _project_name angel_template+ angel_live_file_content = render - setAttribute "project_name" _project_name angel_live_template+ guard_file_content = render - setAttribute "project_name" _project_name guard_template+ haskell_file_content = render - setAttribute "project_name" _project_name haskell_template let { write_if_not_exist file_path str = do@@ -254,8 +261,8 @@ -- shortcut- let shortcut_task_name = printf "t:%s/titan" (config.label)- shortcut_description = printf "Short task name for %s/titan" (config.label)+ let shortcut_task_name = printf "t:%s/titan" (config.project_name)+ shortcut_description = printf "Short task name for %s/titan" (config.project_name) desc shortcut_description task shortcut_task_name - return ()@@ -263,36 +270,105 @@ titan :: String -> Unit titan _file_name = do- let _label = _file_name.takeBaseName- titan_with_config defaultConfig {file_name = _file_name, label = _label}+ let _project_name = _file_name.takeBaseName+ titan_with_config def {file_name = _file_name, project_name = _project_name} ++data MacAppArgs = MacAppArgs+ {+ derived_data_path :: String+ , scheme_name :: Maybe String+ , target_name :: String+ , frameworks :: [String]+ , mac_app_config :: Config+ , mac_app_project_name :: Maybe String+ , mac_app_file_name :: Maybe String+ }+ deriving (Show)++mkLabel ''MacAppArgs+ default_mac_app_config :: Config default_mac_app_config = + def.set __ghc_arg_string "-lobjc"++instance Default MacAppArgs where+ def = MacAppArgs+ {+ derived_data_path = "DerivedData"+ , scheme_name = def+ , target_name = "Hello World Application"+ , frameworks = ["Cocoa"]+ , mac_app_config = default_mac_app_config+ , mac_app_project_name = def+ , mac_app_file_name = def+ }++titan_mac_app :: MacAppArgs -> Unit+titan_mac_app args = do let - mac_ghc_arg_string = - [- "-lobjc"- , "-frameworkCocoa"- ].join " "- in- defaultConfig {ghc_arg_string = mac_ghc_arg_string}+ _target_name = args.target_name+ _dashed_target_name = _target_name.map (\x -> if x.is ' ' then '-' else x)+ _project_name = args.mac_app_project_name.fromMaybe _dashed_target_name+ _file_name = args.mac_app_file_name.fromMaybe (args.mac_app_config.file_name)+ + _new_ghc_arg_string = args.frameworks.map ("-framework" +) .join " "+ + _config = + args.mac_app_config+ .set __file_name _file_name+ .set __project_name _project_name+ .mod __ghc_arg_string (_new_ghc_arg_string + " " +) -titan_mac_app :: String -> String -> FilePath -> String -> String -> Unit-titan_mac_app _label _file_name derived_data_path scheme_name target_name = do- titan_with_config default_mac_app_config {file_name = _file_name, label = _label}+ titan_with_config _config++ let + _scheme_name = args.scheme_name.fromMaybe _target_name+ _derived_data_path = args.derived_data_path - task (_label / "clean") - do- sh - printf "rm -rf %s" derived_data_path- sh - printf "mkdir %s" derived_data_path++ + namespace _project_name - do+ + let config = _config+ haskell_source_path = config.haskell_source_directory / config.file_name+ bin = config.bin_directory / _project_name / "dummy_binary"+ + task ("clean") - do+ sh - printf "rm -rf %s" _derived_data_path+ sh - printf "mkdir %s" _derived_data_path+ sh - printf "rm %s" bin++ desc "Compile the binary"+ task ("compile:uuid") - do+ let { cmd =+ printf "ghc --make -i%s %s %s %s -o %s"+ (config.haskell_source_directory)+ (config.ghc_default_arg_string)+ (config.ghc_arg_string)+ haskell_source_path+ bin+ }++ sh cmd+ + let xcode_build_cmd = printf "cd .. && xcodebuild -scheme '%s' > /dev/null" _scheme_name+ sh xcode_build_cmd++ task ("kill") - do+ let osascript = printf "tell application \"%s\" to quit" _target_name+ sh - printf "osascript -e '%s'" (osascript :: String)++ task ("run") - do+ sh - printf "cd %s; find . -name '%s' -exec '{}' \\;" _derived_data_path _target_name - task (_label / "xcode-build") - do- sh - printf "cd .. && xcodebuild -scheme %s > /dev/null" scheme_name - task (_label / "kill") - do- sh - printf "killall -SIGTERM %s" target_name- - task (_label / "run" + ":" + _label / "xcode-build") - do- sh - printf "cd %s; find . -name '%s' -exec '{}' \\;" derived_data_path target_name+ -- shortcut+ let shortcut_task_name = printf "t:%s/kill %s/titan" _project_name _project_name+ shortcut_description = printf "%s/kill then %s/titan" _project_name _project_name++ desc shortcut_description+ task shortcut_task_name - return () -- Helpers safe_spec :: IO () -> IO ExitCode