public
Last active

Some ruby-based tooling for haskell projects that makes development easier for me. Sandboxing requires cabal >= 0.1.7

  • Download Gist
Gemfile
Ruby
1 2 3 4
source "http://rubygems.org"
 
gem "guard-shell"
gem "rake"
Guardfile
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
guard :shell, :all_after_pass => true do
watch(%r{.*\.cabal$}) do
run_all_tests
end
 
watch(%r{test/SpecHelper.hs$}) do
run_all_tests
end
 
def run_all_tests
ncmd("cabal configure && cabal build && cabal test")
end
 
def ncmd(cmd, msg = cmd)
output = `#{cmd}`
puts output
summary = output.lines.grep(/examples/).first
 
if $?.success?
n "Build Success!", summary
else
n "Failed", summary
end
end
def run_tests(mod)
specfile = "test/#{mod}Spec.hs"
if File.exists?(specfile)
files = [specfile]
else
files = Dir['test/**/*.hs']
end
 
if package_db = Dir[".cabal-sandbox/*packages.conf.d", "cabal-dev/*packages.conf.d"].first
package_db_flag = "-package-db #{package_db}"
end
 
ncmd("ghc -isrc -itest #{package_db_flag} -e 'Test.Hspec.hspec spec' #{files.join(' ')}")
end
 
# can we join these? why does run all loop through each file?
watch(%r{src/(.+)\.hs$}) do |m|
run_tests(m[1])
end
watch(%r{test/(.+)Spec\.hs$}) do |m|
run_tests(m[1])
end
end
Rakefile
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
#!/usr/bin/env rake
 
def number_of_cores
`nproc`.chomp
end
 
def build_flags
"-j#{number_of_cores}"
end
 
desc "run ghci scoped to the sandboxed cabal project"
task :ghci => FileList.new(".cabal-sandbox/*packages.conf.d", "cabal-dev/*packages.conf.d") do |x|
cmd = "ghci -isrc"
if package_db = x.prerequisites.first
cmd += " -package-db #{package_db}"
end
 
sh cmd
end
 
desc "sandbox with cabal (requires cabal >= 0.17)"
task :sandbox do
sh "cabal sandbox init"
end
 
desc "install only essential dependencies. build does this for you"
task :install_dependencies do
sh "cabal install #{build_flags} --only-dependencies"
end
 
desc "install only essential dependencies. test does this for you"
task :install_dependencies_for_test do
sh "cabal install #{build_flags} --only-dependencies --enable-tests"
end
 
desc "just build the project for production"
task :build => [:configure, :install_dependencies] do
sh "cabal build #{build_flags}"
end
 
desc "run tests once. consider using guard afterwards for faster feedback"
task :test => :build_for_test do
sh "cabal test"
end
 
desc "clean all artifacts generated by cabal"
task :clean do
sh "cabal clean"
end
 
task :configure do
sh "cabal configure"
end
 
task :build_for_test => [:configure, :install_dependencies_for_test] do
sh "cabal build #{build_flags}"
end
 
task :default => :build

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.