Error message to detect unspecified transitive dependencies. This seem to be a probl...
[buildr.git] / spec / sandbox.rb
bloba607ca86e52f99a09ea2eaae0c3cd3a6b21980ca
1 # Licensed to the Apache Software Foundation (ASF) under one or more
2 # contributor license agreements.  See the NOTICE file distributed with this
3 # work for additional information regarding copyright ownership.  The ASF
4 # licenses this file to you under the Apache License, Version 2.0 (the
5 # "License"); you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
8 #    http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
13 # License for the specific language governing permissions and limitations under
14 # the License.
17 # The local repository we use for testing is void of any artifacts, which will break given
18 # that the code requires several artifacts. So we establish them first using the real local
19 # repository and cache these across test cases.
20 Buildr.application.instance_eval { @rakefile = File.expand_path('buildfile') }
21 repositories.remote << 'http://repo1.maven.org/maven2'
22 repositories.remote << 'http://scala-tools.org/repo-releases'
24 # Add a 'require' here only for optional extensions, not for extensions that should be loaded by default.
25 require 'buildr/groovy'
27 Java.load # Anything added to the classpath.
28 artifacts(TestFramework.frameworks.map(&:dependencies).flatten, JUnit.ant_taskdef).each do |path|
29   file(path).invoke
30 end
32 ENV['HOME'] = File.expand_path('tmp/home')
34 # We need to run all tests inside a _sandbox, tacking a snapshot of Buildr before the test,
35 # and restoring everything to its previous state after the test. Damn state changes.
36 module Sandbox
38   class << self
39     attr_reader :tasks, :rules
41     def included(spec)
42       spec.before(:each) { sandbox }
43       spec.after(:each) { reset }
44     end
45     
46     # Require an optional extension without letting its callbacks pollute the Project class.
47     def require_optional_extension(extension_require_path)
48       project_callbacks_without_extension = Project.class_eval { @callbacks }.dup
49       begin
50         require extension_require_path
51       ensure
52         Project.class_eval { @callbacks = project_callbacks_without_extension }
53       end
54     end
55   end
57   @tasks = Buildr.application.tasks.collect do |original|
58     prerequisites = original.send(:prerequisites).map(&:to_s)
59     actions = original.instance_eval { @actions }.clone
60     lambda do
61       original.class.send(:define_task, original.name=>prerequisites).tap do |task|
62         task.comment = original.comment
63         actions.each { |action| task.enhance &action }
64       end
65     end
66   end
67   @rules = Buildr.application.instance_variable_get(:@rules)
69   def sandbox
70     @_sandbox = {}
71     
72     # Create a temporary directory where we can create files, e.g,
73     # for projects, compilation. We need a place that does not depend
74     # on the current directory.
75     @_sandbox[:original_dir] = Dir.pwd
76     @temp = File.join(File.dirname(__FILE__), '../tmp')
77     FileUtils.mkpath @temp
78     Dir.chdir @temp
80     ARGV.clear
81     Buildr.application = Buildr::Application.new
82     Sandbox.tasks.each { |block| block.call }
83     Buildr.application.instance_variable_set :@rules, Sandbox.rules.clone
84     Buildr.application.instance_eval { @rakefile = File.expand_path('buildfile') }
86     @_sandbox[:load_path] = $LOAD_PATH.clone
87     #@_sandbox[:loaded_features] = $LOADED_FEATURES.clone
88     
89     # Later on we'll want to lose all the on_define created during the test.
90     @_sandbox[:on_define] = Project.class_eval { (@on_define || []).dup }
91     @_sandbox[:callbacks] = Project.class_eval { (@callbacks || []).dup }
92     @_sandbox[:layout] = Layout.default.clone
94     # Create a local repository we can play with. However, our local repository will be void
95     # of some essential artifacts (e.g. JUnit artifacts required by build task), so we create
96     # these first (see above) and keep them across test cases.
97     @_sandbox[:artifacts] = Artifact.class_eval { @artifacts }.clone
98     Buildr.repositories.local = File.expand_path('repository')
99     ENV['HOME'] = File.expand_path('home')
100     ENV['BUILDR_ENV'] = 'development'
102     @_sandbox[:env_keys] = ENV.keys
103     ['DEBUG', 'TEST', 'HTTP_PROXY', 'USER'].each { |k| ENV.delete(k) ; ENV.delete(k.downcase) }
105     # Remove testing local repository, and reset all repository settings.
106     Buildr.repositories.instance_eval do
107       @local = @remote = @release_to = nil
108     end
109     Buildr.options.proxy.http = nil
111     # Don't output crap to the console.
112     trace false
113     verbose false
114   end
116   # Call this from teardown.
117   def reset
118     # Get rid of all the projects and the on_define blocks we used.
119     Project.clear
120     on_define = @_sandbox[:on_define]
121     Project.class_eval { @on_define = on_define }
122     callbacks = @_sandbox[:callbacks]
123     Project.class_eval { @callbacks = callbacks }
124     Layout.default = @_sandbox[:layout].clone
126     $LOAD_PATH.replace @_sandbox[:load_path]
127     FileUtils.rm_rf @temp
129     # Get rid of all artifacts.
130     @_sandbox[:artifacts].tap { |artifacts| Artifact.class_eval { @artifacts = artifacts } }
132     # Restore options.
133     Buildr.options.test = nil
134     (ENV.keys - @_sandbox[:env_keys]).each { |key| ENV.delete key }
136     Dir.chdir @_sandbox[:original_dir]
137   end