gradle-haskell-plugin
Haskell plugin for Gradle
Usage
Put your source code to src/main/haskell
, the test code to src/test/haskell
and the cabal file to the project's root. Don't forget to set the source directory in the cabal file too:
hs-source-dirs: src/main/haskell
For the default operation all you have to do is apply the plugin:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.prezi.haskell:gradle-haskell-plugin:0.4+'
}
}
apply plugin: 'haskell'
Dependencies, artifacts
Haskell projects creates zipped sandboxes as artifacts, and handles dependencies by chaining the dependent sandboxes for each GHC/cabal/stack command. All the dependencies put into the configuration called main
must be haskell dependencies.
The following example shows both an external dependency and a project dependency, both pointing to an artifact produced by the this plugin.
dependencies {
main group: "something", name: "lib1", version: "1.+", configuration: 'main'
main project(path: ":lib2", configuration: "main")
}
Additional options
It is possible to change the source set used to determine the up-to-date status of the compilation task. See the following example:
haskell {
sources {
main {
haskell {
source.srcDir "TODO"
}
}
}
}
NOTE This only affects gradle's up-to-date checks. You still have to add the source directories to your cabal file too.
Stack support
The plugin now only works through stack.
In this case all you need is a working stack
executable, everything else is handled by the plugin and stack.
There are a few additional options available in stack mode:
Compiler and snapshot versions
To change the GHC version or the stackage snapshot to be used, use:
haskell {
ghcVersion = "ghc-7.10.2"
snapshotId = "lts-3.19"
}
Package flags
It is possible to customize the cabal flags of dependencies installed by stack, with the following syntax:
haskell {
packageFlags["text"] = ["integer-simple": "false"]
}
Profiling
Profiling is disabled by default. To turn it on, change the profiling
property of the haskell
extension:
haskell {
profiling = true
}
or use the -Pghc-enable-profiling
command line argument.
GHC and cabal location
It is possible to specify a cabal config file which can point to a non-default global package database, etc:
haskell {
cabalConfigFile = "~/custom/cabal.cfg"
}
or -Pcabal-config-file=~/custom/cabal.cfg
.
To manage which cabal
, ghc
etc. is executed by the plugin, you can override the PATH
and other environment variables with the following syntax:
haskell {
envConfigurer { Map<String, Object> envMap ->
def path = envMap.get("PATH")
envMap.put("PATH", [
"/custom-ghc-path/bin",
"/custom-cabal-path/bin",
path
].join(":"))
}
}
Explanation (stack mode)
The stack mode uses the extra-package-dbs
option of stack which was introduced to support this plugin. The idea is that gradle generates the stack.yaml
based on the existing .cabal
file and the gradle project, and this way it can set up the stack project to use the dependent gradle projects as binary artifacts.
The generated stack projects have the following properties:
- They use a compiler-only resolver (for example
ghc-7.10.2
) - All other dependencies are listed in the
extra-deps
section - The gradle-level dependencies are listed in as
extra-package-dbs
This way the stack project's local package database can be archived as a binary artifact.
To not loose the stackage snapshots, the plugin also uses another tool called snapshot-versions, which generates the extra-deps
section of the stack project by enumerating all the dependencies from the .cabal
file and reading the snapshot version number from the configured stackage snapshot.
To use a package that is not part of the configured stackage snapshot, but otherwise available from hackage, you have to specify it's exact version number in the .cabal file
, like:
Crypto ==4.2.5.1
For the dependencies that are part of the snapshot, the .cabal
file should not put any constraints on.
Details
Applying the plugin adds the following to the project:
Fields
ghcSandbox
is the project's internal sandbox model, used by the pluginghcSandboxRoot
is the root path of the project's sandboxghcPackageDb
is the package database inside the project's sandboxghcPrefix
is the directory where cabal installs the project in its sandboxhaskellTools
is a helper object used internally by the plugin
Configurations
main
is used to set up the sandbox chain from the dependencies and it also defines the project's sandbox as its artifacttest
extendsmain
but has no special role currently (because cabal configures the project with its tests in one phase)
Tasks
sandboxInfo
prints some basic information about the project's sandboxsandboxPackages
prints the package list of the project's and its dependent sandboxescompileMain
andcompileTest
all refers to the same task, compiling the whole cabal projectassemble
assembles all the files of the project; by default this means runningcompileMain
and generating the ghc-mod cradleclean
deletes thebuild
anddist
directoriestest
compiles the cabal package with tests enabled, and runs themcheck
executestest
. It is an extension point to execute other kind of tests.build
executesassemble
andcheck
zipSandbox
packs the whole sandbox as the artifact of themain
configuration of the projectfreeze
executescabal freeze
repl
executescabal repl
Additional tasks supporting the ones above:
sandboxDirectories
creates the sandbox directory structuresandbox
initializes the package database in the project's sandboxcopySandFix
extracts the bunled SandFix from the pluginconfigureSandboxes
sets upextractDependentSandboxes
andfixDependentSandboxes
tasks after the dependency resolution is doneextractDependentSandboxes
extracts the resolved artifacts to temporary directories insidebuild/deps
fixDependentSandboxes
clones the extracted sandboxes and runs SandFix on them