| 
									
										
										
										
											2014-03-28 01:59:50 +01:00
										 |  |  | module Language | 
					
						
							|  |  |  |   module Haskell | 
					
						
							| 
									
										
										
										
											2015-12-23 13:19:14 +00:00
										 |  |  |     module Cabal | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |       def self.included(base) | 
					
						
							| 
									
										
										
										
											2015-12-23 13:19:14 +00:00
										 |  |  |         # use llvm-gcc on Lion or below, as when building GHC) | 
					
						
							| 
									
										
										
										
											2015-12-30 15:51:57 -04:00
										 |  |  |         base.fails_with(:clang) if MacOS.version <= :lion | 
					
						
							| 
									
										
										
										
											2015-05-28 19:30:10 -07:00
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-23 13:19:14 +00:00
										 |  |  |       def cabal_sandbox(options = {}) | 
					
						
							| 
									
										
										
										
											2014-03-28 01:59:50 +01:00
										 |  |  |         pwd = Pathname.pwd | 
					
						
							| 
									
										
										
										
											2015-12-23 13:19:14 +00:00
										 |  |  |         home = options[:home] || pwd | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # pretend HOME is elsewhere, so that ~/.cabal is kept as untouched | 
					
						
							|  |  |  |         # as possible (except for ~/.cabal/setup-exe-cache) | 
					
						
							|  |  |  |         # https://github.com/haskell/cabal/issues/1234 | 
					
						
							|  |  |  |         saved_home = ENV["HOME"] | 
					
						
							|  |  |  |         ENV["HOME"] = home | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         system "cabal", "sandbox", "init" | 
					
						
							| 
									
										
										
										
											2015-12-30 21:09:36 +00:00
										 |  |  |         cabal_sandbox_bin = pwd/".cabal-sandbox/bin" | 
					
						
							| 
									
										
										
										
											2014-03-28 01:59:50 +01:00
										 |  |  |         mkdir_p cabal_sandbox_bin | 
					
						
							| 
									
										
										
										
											2015-12-23 13:19:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # make available any tools that will be installed in the sandbox | 
					
						
							|  |  |  |         saved_path = ENV["PATH"] | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |         ENV.prepend_path "PATH", cabal_sandbox_bin | 
					
						
							| 
									
										
										
										
											2015-12-23 13:19:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # avoid updating the cabal package database more than once | 
					
						
							| 
									
										
										
										
											2015-12-30 21:09:36 +00:00
										 |  |  |         system "cabal", "update" unless (home/".cabal/packages").exist? | 
					
						
							| 
									
										
										
										
											2015-12-23 13:19:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-28 01:59:50 +01:00
										 |  |  |         yield | 
					
						
							| 
									
										
										
										
											2015-12-23 13:19:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # remove the sandbox and all build products | 
					
						
							|  |  |  |         rm_rf [".cabal-sandbox", "cabal.sandbox.config", "dist"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # avoid installing any Haskell libraries, as a matter of policy | 
					
						
							|  |  |  |         rm_rf lib unless options[:keep_lib] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-28 01:59:50 +01:00
										 |  |  |         # restore the environment | 
					
						
							| 
									
										
										
										
											2015-12-23 13:19:14 +00:00
										 |  |  |         ENV["HOME"] = saved_home | 
					
						
							|  |  |  |         ENV["PATH"] = saved_path | 
					
						
							| 
									
										
										
										
											2014-03-28 01:59:50 +01:00
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-23 13:19:14 +00:00
										 |  |  |       def cabal_sandbox_add_source(*args) | 
					
						
							|  |  |  |         system "cabal", "sandbox", "add-source", *args | 
					
						
							| 
									
										
										
										
											2014-03-28 01:59:50 +01:00
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-23 13:19:14 +00:00
										 |  |  |       def cabal_install(*args) | 
					
						
							| 
									
										
										
										
											2016-02-24 21:11:02 -08:00
										 |  |  |         # cabal hardcodes 64 as the maximum number of parallel jobs | 
					
						
							| 
									
										
										
										
											2016-05-01 14:55:45 +02:00
										 |  |  |         # https://github.com/Homebrew/legacy-homebrew/issues/49509 | 
					
						
							| 
									
										
										
										
											2017-05-29 18:24:52 +01:00
										 |  |  |         make_jobs = (ENV.make_jobs > 64) ? 64 : ENV.make_jobs | 
					
						
							| 
									
										
										
										
											2016-02-24 21:11:02 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-14 01:55:02 -08:00
										 |  |  |         # cabal-install's dependency-resolution backtracking strategy can easily | 
					
						
							|  |  |  |         # need more than the default 2,000 maximum number of "backjumps," since | 
					
						
							|  |  |  |         # Hackage is a fast-moving, rolling-release target. The highest known | 
					
						
							|  |  |  |         # needed value by a formula at this time (February 2016) was 43,478 for | 
					
						
							|  |  |  |         # git-annex, so 100,000 should be enough to avoid most gratuitous | 
					
						
							|  |  |  |         # backjumps build failures. | 
					
						
							| 
									
										
										
										
											2016-02-24 21:11:02 -08:00
										 |  |  |         system "cabal", "install", "--jobs=#{make_jobs}", "--max-backjumps=100000", *args | 
					
						
							| 
									
										
										
										
											2014-03-28 01:59:50 +01:00
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-10 18:31:55 -08:00
										 |  |  |       def cabal_configure(flags) | 
					
						
							|  |  |  |         system "cabal", "configure", flags | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-23 13:19:14 +00:00
										 |  |  |       def cabal_install_tools(*tools) | 
					
						
							|  |  |  |         # install tools sequentially, as some tools can depend on other tools | 
					
						
							|  |  |  |         tools.each { |tool| cabal_install tool } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # unregister packages installed as dependencies for the tools, so | 
					
						
							|  |  |  |         # that they can't cause dependency conflicts for the main package | 
					
						
							|  |  |  |         rm_rf Dir[".cabal-sandbox/*packages.conf.d/"] | 
					
						
							| 
									
										
										
										
											2014-03-28 01:59:50 +01:00
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-23 13:19:14 +00:00
										 |  |  |       def install_cabal_package(*args) | 
					
						
							| 
									
										
										
										
											2016-09-10 10:38:35 +01:00
										 |  |  |         options = args[-1].is_a?(Hash) ? args.pop : {} | 
					
						
							| 
									
										
										
										
											2015-12-23 13:19:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-28 01:59:50 +01:00
										 |  |  |         cabal_sandbox do | 
					
						
							| 
									
										
										
										
											2015-12-30 21:05:44 +00:00
										 |  |  |           cabal_install_tools(*options[:using]) if options[:using] | 
					
						
							| 
									
										
										
										
											2015-12-23 13:19:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-10 18:31:55 -08:00
										 |  |  |           # if we have build flags, we have to pass them to cabal install to resolve the necessary | 
					
						
							|  |  |  |           # dependencies, and call cabal configure afterwards to set the flags again for compile | 
					
						
							| 
									
										
										
										
											2016-09-23 11:01:40 +02:00
										 |  |  |           flags = "--flags=#{options[:flags].join(" ")}" if options[:flags] | 
					
						
							| 
									
										
										
										
											2016-01-10 18:31:55 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |           args_and_flags = args | 
					
						
							| 
									
										
										
										
											2016-09-23 11:01:40 +02:00
										 |  |  |           args_and_flags << flags unless flags.nil? | 
					
						
							| 
									
										
										
										
											2016-01-10 18:31:55 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-23 13:19:14 +00:00
										 |  |  |           # install dependencies in the sandbox | 
					
						
							| 
									
										
										
										
											2016-01-10 18:31:55 -08:00
										 |  |  |           cabal_install "--only-dependencies", *args_and_flags | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           # call configure if build flags are set | 
					
						
							| 
									
										
										
										
											2016-09-23 11:01:40 +02:00
										 |  |  |           cabal_configure flags unless flags.nil? | 
					
						
							| 
									
										
										
										
											2015-12-23 13:19:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |           # install the main package in the destination dir | 
					
						
							| 
									
										
										
										
											2015-01-17 19:29:36 +01:00
										 |  |  |           cabal_install "--prefix=#{prefix}", *args | 
					
						
							| 
									
										
										
										
											2015-12-23 13:19:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |           yield if block_given? | 
					
						
							| 
									
										
										
										
											2014-03-28 01:59:50 +01:00
										 |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | end |