Getting started¶
Marvin projects basically comprise of a collection of individual scripts and a main file which ties them all together.
To start a new project marvin provides an initializer, called marvin-init
.
The initializer will set up a new project for you, including a sample script, the main file and the Haskell project configuration to make compiling smooth and easy.
Note
Always run marvin-init
in an empty directory, as it will place certain files there and overwrite existing files with the same name.
If you install marvin through cabal (cabal install marvin
) or stack (stack install marvin
) it will install the initializer as well and add it to your path.
To see the options of the initializer run marvin-init --help
on your command line.
marvin-init ~ make a new marvin project
Usage: marvin-init BOTNAME [-a|--adapter ID]
Available options:
-h,--help Show this help text
-a,--adapter ID id of the adapter to use
Information on Adapters and their id’s can be found in the Adapters section.
Installing marvin¶
You can get a release version of marvin on Hackage
However the recommended way to install this package is via stack.
The marvin package is part if the stack lts as of lts-8.5
.
You can let stack do the resolving for you if you’ve added marvin in your .cabal
file you can simply run stack solver --update-config
and it will choose the right versions for you.
After that stack build
will pull and install marvin for you.
Important
Marvin uses the text-icu
library for regexes.
It therefore requires the -dev
version of the icu
C library.
- Linux
Simply install the
-dev
version of the icu library.For instance
apt install libicu-dev
on Ubuntu.- OSX
You also need the icu library. If you are using Homebrew you are looking for the
icu4c
package (brew install icu4c
). Because OSX also provides some headers you will also need to link the headers manually. If you are using stack to build your projects the easiest way is to add the following lines to$HOME/.stack/config.yaml
.extra-include-dirs: - /usr/local/opt/icu4c/include extra-lib-dirs: - /usr/local/opt/icu4c/lib
alternatively you can pass the paths via
--extra-include-dirs
andextra-lib-dirs
to thestack build
andstack install
command.
Scripts¶
The functionality for your marvin installation is split into individual parts, called scripts.
Each script is some Haskell structure created with defineScript
.
Scripts can be user defined or be included externally.
External scripts¶
You can include external scripts in the form of a library.
To do this you must add the library name to the .cabal
and stack.yaml
file of your project.
You can find more information on external scripts and an example external-scripts.json
file in the external scripts section
User defined scripts¶
You can also write some scripts yourself.
Typically scripts are a Haskell source file which defines a script
value.
As an example, a “hello world” script.
-- file named "HelloWorld.hs" (must be the same as module name + ".hs")
module HelloWorld where
import Marvin.Prelude
-- This type signature is necessary to help the compiler
script :: IsAdapter a => ScriptInit a
script = defineScript
"hello-world" -- script name (for logging and config)
$ do -- here follows the actual script definition
...
You can find more information on the actual script content in the Writing marvin scripts section.
The main file¶
This file (ususally called Main.hs
) ties the scripts together and defines the Adapters which your marvin project uses.
Note
If you use the initializer marvin-init
the main file will already be defined for you and registered in the .cabal
file.
The file must be a Haskell source file i.e. end with .hs
and be mentioned in the main-is
section of your .cabal
file.
It will look someting like this:
-- import marvin runner
import Marvin.Run
-- imports chosen adapter
import Marvin.Adapter.Slack
-- import all scripts
import qualified HelloWorld
import qualified MyScript
-- list of all scripts to use
scripts :: [ScriptInit SlackRTMAdapter]
scripts = [ HelloWorld.script
, MyScript.script
]
main :: IO ()
main = runMarvin scripts
You can write the main file yourself, but this can get tedious as you add more and more scripts.
To make this easier Marvin includes a utility which allows you to let the main file be generated automatically, called The marvin preprocessor (marvin-pp).
marvin-pp
creates the main file dynamically at compile time by scanning your project for scripts.
You can add external scripts by adding an external-scripts.json file and marvin-pp
will add those to your main file then.
To use marvin-pp
simply add an empty main file, except for this line: {-# OPTIONS_GHC -F -pgmF marvin-pp -optF --adapter -optF slack-rtm #-}
(this is what marvin-init
does as well).
Important
The marvin-pp
generator is a compile time preprocessor and thus its output is often cached by your build system. As a result you have to run cabal clean
or stack clean
after you added or removed a script to force the build system to regenerate the main file.