isolate 1.3.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.rdoc +5 -0
- data/README.rdoc +12 -9
- data/lib/isolate.rb +63 -21
- data/test/test_isolate.rb +57 -18
- metadata +2 -2
data/CHANGELOG.rdoc
CHANGED
data/README.rdoc
CHANGED
@@ -78,11 +78,17 @@ exceptions, <tt>:source</tt> and <tt>:args</tt>.
|
|
78
78
|
|
79
79
|
=== Installing Isolated Gems
|
80
80
|
|
81
|
-
By default, Isolate will install
|
82
|
-
<tt>:
|
81
|
+
By default, Isolate will install and clean up your gems
|
82
|
+
automatically. You can pass the <tt>:cleanup</tt>, <tt>:install</tt>,
|
83
|
+
and <tt>:verbose</tt> options to control things:
|
84
|
+
|
85
|
+
# don't remove unnecesary gems
|
86
|
+
Isolate.gems "vendor/isolated", :cleanup => false do
|
87
|
+
...
|
88
|
+
end
|
83
89
|
|
84
90
|
# install, but quietly
|
85
|
-
Isolate.gems "vendor/isolated" :verbose => false do
|
91
|
+
Isolate.gems "vendor/isolated", :verbose => false do
|
86
92
|
...
|
87
93
|
end
|
88
94
|
|
@@ -129,16 +135,13 @@ the preinitializer:
|
|
129
135
|
# Twitter authentication
|
130
136
|
gem "oauth", "~> 0.3"
|
131
137
|
|
132
|
-
environment :development, :test do
|
133
|
-
gem "
|
138
|
+
environment :cucumber, :development, :test do
|
139
|
+
gem "cucumber" # stories!
|
140
|
+
gem "modelizer" # easy model factories
|
134
141
|
gem "sqlite3-ruby" # database support
|
135
142
|
gem "vlad" # deployment
|
136
143
|
gem "webrat" # integration tests
|
137
144
|
end
|
138
|
-
|
139
|
-
environment :cucumber do
|
140
|
-
gem "cucumber" # stories!
|
141
|
-
end
|
142
145
|
end
|
143
146
|
|
144
147
|
Since this is in the preinitializer, Isolate will install and activate
|
data/lib/isolate.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require "rubygems/dependency_installer"
|
2
|
+
require "rubygems/uninstaller"
|
2
3
|
require "rubygems/requirement"
|
3
4
|
|
4
5
|
# Restricts +GEM_PATH+ and +GEM_HOME+ and provides a DSL for
|
@@ -14,9 +15,13 @@ class Isolate
|
|
14
15
|
def matches? environment # :nodoc:
|
15
16
|
environments.empty? || environments.include?(environment)
|
16
17
|
end
|
18
|
+
|
19
|
+
def matches_spec? spec
|
20
|
+
self.name == spec.name and self.requirement.satisfied_by? spec.version
|
21
|
+
end
|
17
22
|
end
|
18
23
|
|
19
|
-
VERSION = "1.
|
24
|
+
VERSION = "1.4.0" # :nodoc:
|
20
25
|
|
21
26
|
attr_reader :entries # :nodoc:
|
22
27
|
|
@@ -28,6 +33,7 @@ class Isolate
|
|
28
33
|
|
29
34
|
def self.activate environment
|
30
35
|
instance.activate environment
|
36
|
+
instance.cleanup if instance.cleanup?
|
31
37
|
end
|
32
38
|
|
33
39
|
# Declare an isolated RubyGems environment, installed in +path+. The
|
@@ -36,7 +42,7 @@ class Isolate
|
|
36
42
|
#
|
37
43
|
# Option defaults:
|
38
44
|
#
|
39
|
-
# { :install => true, :verbose => true }
|
45
|
+
# { :cleanup => true, :install => true, :verbose => true }
|
40
46
|
|
41
47
|
def self.gems path, options = {}, &block
|
42
48
|
@@instance = new path, options, &block
|
@@ -65,9 +71,11 @@ class Isolate
|
|
65
71
|
@enabled = false
|
66
72
|
@entries = []
|
67
73
|
@environments = []
|
68
|
-
@install = options.key?(:install) ? options[:install] : true
|
69
74
|
@path = path
|
70
|
-
|
75
|
+
|
76
|
+
@install = options.fetch :install, true
|
77
|
+
@verbose = options.fetch :verbose, true
|
78
|
+
@cleanup = @install && options.fetch(:cleanup, true)
|
71
79
|
|
72
80
|
instance_eval(&block) if block_given?
|
73
81
|
end
|
@@ -85,6 +93,34 @@ class Isolate
|
|
85
93
|
self
|
86
94
|
end
|
87
95
|
|
96
|
+
def cleanup
|
97
|
+
activated = Gem.loaded_specs.values.map { |s| s.full_name }
|
98
|
+
extra = Gem.source_index.gems.values.sort.reject { |spec|
|
99
|
+
activated.include? spec.full_name or
|
100
|
+
entries.any? { |e| e.matches_spec? spec }
|
101
|
+
}
|
102
|
+
|
103
|
+
log "Cleaning..." unless extra.empty?
|
104
|
+
|
105
|
+
padding = extra.size.to_s.size # omg... heaven forbid you use math
|
106
|
+
format = "[%0#{padding}d/%s] Nuking %s."
|
107
|
+
extra.each_with_index do |e, i|
|
108
|
+
log format % [i + 1, extra.size, e.full_name]
|
109
|
+
|
110
|
+
Gem::DefaultUserInteraction.use_ui Gem::SilentUI.new do
|
111
|
+
Gem::Uninstaller.new(e.name,
|
112
|
+
:version => e.version,
|
113
|
+
:ignore => true,
|
114
|
+
:executables => true,
|
115
|
+
:install_dir => self.path).uninstall
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def cleanup? # :nodoc:
|
121
|
+
@cleanup
|
122
|
+
end
|
123
|
+
|
88
124
|
def disable # :nodoc:
|
89
125
|
return self unless enabled?
|
90
126
|
|
@@ -130,14 +166,12 @@ class Isolate
|
|
130
166
|
# Restricts +gem+ calls inside +block+ to a set of +environments+.
|
131
167
|
|
132
168
|
def environment *environments, &block
|
133
|
-
old = @environments
|
134
|
-
@environments.concat environments.map { |e| e.to_s }
|
169
|
+
old = @environments
|
170
|
+
@environments = @environments.dup.concat environments.map { |e| e.to_s }
|
135
171
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
@environments = old
|
140
|
-
end
|
172
|
+
instance_eval(&block)
|
173
|
+
ensure
|
174
|
+
@environments = old
|
141
175
|
end
|
142
176
|
|
143
177
|
# Express a gem dependency. Works pretty much like RubyGems' +gem+
|
@@ -147,16 +181,22 @@ class Isolate
|
|
147
181
|
def gem name, *requirements
|
148
182
|
options = Hash === requirements.last ? requirements.pop : {}
|
149
183
|
|
150
|
-
requirement = requirements.empty?
|
151
|
-
|
152
|
-
|
184
|
+
requirement = if requirements.empty? then
|
185
|
+
Gem::Requirement.default
|
186
|
+
else
|
187
|
+
Gem::Requirement.new(requirements)
|
188
|
+
end
|
153
189
|
|
154
|
-
entry = Entry.new name, requirement, @environments
|
190
|
+
entry = Entry.new name, requirement, @environments, options
|
155
191
|
|
156
192
|
entries << entry
|
157
193
|
entry
|
158
194
|
end
|
159
195
|
|
196
|
+
def log s
|
197
|
+
$stderr.puts s if verbose?
|
198
|
+
end
|
199
|
+
|
160
200
|
def install environment = nil # :nodoc:
|
161
201
|
env = environment.to_s if environment
|
162
202
|
|
@@ -164,15 +204,17 @@ class Isolate
|
|
164
204
|
!Gem.available?(e.name, *e.requirement.as_list) && e.matches?(env)
|
165
205
|
end
|
166
206
|
|
207
|
+
log "Isolating #{environment}..." unless installable.empty?
|
208
|
+
|
209
|
+
padding = installable.size.to_s.size # omg... heaven forbid you use math
|
210
|
+
format = "[%0#{padding}d/%s] Isolating %s (%s)."
|
167
211
|
installable.each_with_index do |e, i|
|
168
|
-
|
169
|
-
padding = installable.size.to_s.size
|
170
|
-
progress = "[%0#{padding}d/%s]" % [i + 1, installable.size]
|
171
|
-
warn "#{progress} Isolating #{e.name} (#{e.requirement})."
|
172
|
-
end
|
212
|
+
log format % [i + 1, installable.size, e.name, e.requirement]
|
173
213
|
|
174
214
|
old = Gem.sources.dup
|
175
|
-
options = e.options.merge
|
215
|
+
options = e.options.merge(:install_dir => path,
|
216
|
+
:generate_rdoc => false,
|
217
|
+
:generate_ri => false)
|
176
218
|
source = options.delete :source
|
177
219
|
args = options.delete :args
|
178
220
|
Gem.sources = Array(source) if source
|
data/test/test_isolate.rb
CHANGED
@@ -4,6 +4,8 @@ require "rubygems/requirement"
|
|
4
4
|
require "isolate"
|
5
5
|
|
6
6
|
class TestIsolate < MiniTest::Unit::TestCase
|
7
|
+
WITH_HOE = "test/fixtures/with-hoe"
|
8
|
+
|
7
9
|
def setup
|
8
10
|
@isolate = Isolate.new "tmp/gems", :install => false, :verbose => false
|
9
11
|
end
|
@@ -11,24 +13,25 @@ class TestIsolate < MiniTest::Unit::TestCase
|
|
11
13
|
def teardown
|
12
14
|
@isolate.disable
|
13
15
|
Isolate.instance.disable if Isolate.instance
|
14
|
-
Gem::DependencyInstaller.
|
16
|
+
Gem::DependencyInstaller.reset_value
|
17
|
+
Gem::Uninstaller.reset_value
|
15
18
|
FileUtils.rm_rf "tmp/gems"
|
16
19
|
end
|
17
20
|
|
18
21
|
def test_self_gems
|
19
22
|
assert_nil Isolate.instance
|
20
23
|
|
21
|
-
Isolate.gems
|
24
|
+
Isolate.gems WITH_HOE do
|
22
25
|
gem "hoe"
|
23
26
|
end
|
24
27
|
|
25
28
|
refute_nil Isolate.instance
|
26
|
-
assert_equal
|
29
|
+
assert_equal WITH_HOE, Isolate.instance.path
|
27
30
|
assert_equal "hoe", Isolate.instance.entries.first.name
|
28
31
|
end
|
29
32
|
|
30
33
|
def test_activate
|
31
|
-
@isolate = Isolate.new
|
34
|
+
@isolate = Isolate.new WITH_HOE
|
32
35
|
|
33
36
|
assert_nil Gem.loaded_specs["hoe"]
|
34
37
|
|
@@ -39,7 +42,7 @@ class TestIsolate < MiniTest::Unit::TestCase
|
|
39
42
|
end
|
40
43
|
|
41
44
|
def test_activate_environment
|
42
|
-
@isolate = Isolate.new
|
45
|
+
@isolate = Isolate.new WITH_HOE
|
43
46
|
@isolate.gem "rubyforge"
|
44
47
|
|
45
48
|
@isolate.environment "borg" do
|
@@ -52,7 +55,7 @@ class TestIsolate < MiniTest::Unit::TestCase
|
|
52
55
|
end
|
53
56
|
|
54
57
|
def test_activate_environment_explicit
|
55
|
-
@isolate = Isolate.new
|
58
|
+
@isolate = Isolate.new WITH_HOE
|
56
59
|
|
57
60
|
@isolate.gem "rubyforge"
|
58
61
|
|
@@ -74,7 +77,7 @@ class TestIsolate < MiniTest::Unit::TestCase
|
|
74
77
|
begin; @isolate.activate; rescue Gem::LoadError; end
|
75
78
|
|
76
79
|
assert_equal ["foo", Gem::Requirement.default],
|
77
|
-
Gem::DependencyInstaller.
|
80
|
+
Gem::DependencyInstaller.value.shift
|
78
81
|
end
|
79
82
|
|
80
83
|
def test_activate_install_environment
|
@@ -82,13 +85,29 @@ class TestIsolate < MiniTest::Unit::TestCase
|
|
82
85
|
@isolate.environment(:nope) { gem "foo" }
|
83
86
|
|
84
87
|
@isolate.activate
|
85
|
-
|
88
|
+
assert_empty Gem::DependencyInstaller.value
|
86
89
|
end
|
87
90
|
|
88
91
|
def test_activate_ret
|
89
92
|
assert_equal @isolate, @isolate.activate
|
90
93
|
end
|
91
94
|
|
95
|
+
# TODO: cleanup with 2 versions of same gem, 1 activated
|
96
|
+
# TODO: install with 1 older version, 1 new gem to be installed
|
97
|
+
|
98
|
+
def test_cleanup
|
99
|
+
@isolate = Isolate.new WITH_HOE, :verbose => false
|
100
|
+
# no gems specified on purpose
|
101
|
+
@isolate.activate
|
102
|
+
@isolate.cleanup
|
103
|
+
|
104
|
+
expected = [["hoe", "2.3.3", WITH_HOE],
|
105
|
+
["rake", "0.8.7", WITH_HOE],
|
106
|
+
["rubyforge", "1.0.4", WITH_HOE]]
|
107
|
+
|
108
|
+
assert_equal expected, Gem::Uninstaller.value
|
109
|
+
end
|
110
|
+
|
92
111
|
def test_disable
|
93
112
|
home, path = ENV.values_at "GEM_HOME", "GEM_PATH"
|
94
113
|
load_path = $LOAD_PATH.dup
|
@@ -111,7 +130,7 @@ class TestIsolate < MiniTest::Unit::TestCase
|
|
111
130
|
end
|
112
131
|
|
113
132
|
def test_enable
|
114
|
-
|
133
|
+
refute_empty Gem.find_files("minitest/unit.rb"),
|
115
134
|
"There's a minitest/unit in the current env, since we're running it."
|
116
135
|
|
117
136
|
@isolate.enable
|
@@ -122,7 +141,7 @@ class TestIsolate < MiniTest::Unit::TestCase
|
|
122
141
|
assert_equal [], Gem.find_files("minitest/unit.rb"),
|
123
142
|
"Can't find minitest/unit now, 'cause we're activated!"
|
124
143
|
|
125
|
-
|
144
|
+
assert_empty Gem.loaded_specs
|
126
145
|
assert_equal [@isolate.path], Gem.path
|
127
146
|
end
|
128
147
|
|
@@ -150,7 +169,7 @@ class TestIsolate < MiniTest::Unit::TestCase
|
|
150
169
|
|
151
170
|
def test_gem
|
152
171
|
g = @isolate.gem "foo"
|
153
|
-
|
172
|
+
assert_includes @isolate.entries, g
|
154
173
|
|
155
174
|
assert_equal "foo", g.name
|
156
175
|
assert_equal Gem::Requirement.create(">= 0"), g.requirement
|
@@ -175,23 +194,43 @@ class TestIsolate < MiniTest::Unit::TestCase
|
|
175
194
|
i = Isolate.new "foo/gems"
|
176
195
|
assert i.install?
|
177
196
|
assert i.verbose?
|
197
|
+
assert i.cleanup?
|
198
|
+
|
199
|
+
i = Isolate.new "foo/gems",
|
200
|
+
:cleanup => false, :install => false, :verbose => false
|
178
201
|
|
179
|
-
i
|
202
|
+
refute i.cleanup?
|
180
203
|
refute i.install?
|
181
204
|
refute i.verbose?
|
205
|
+
|
206
|
+
i = Isolate.new "foo/gems", :install => false
|
207
|
+
refute i.cleanup?, "no install, no cleanup"
|
182
208
|
end
|
183
209
|
end
|
184
210
|
|
185
|
-
|
211
|
+
module BrutalStub
|
212
|
+
@@value = []
|
213
|
+
def value; @@value end
|
214
|
+
def reset_value; value.clear end
|
215
|
+
end
|
186
216
|
|
187
217
|
class Gem::DependencyInstaller
|
188
|
-
|
189
|
-
def self.last_install; @@last_install end
|
190
|
-
def self.reset_last_install; @@last_install = nil end
|
218
|
+
extend BrutalStub
|
191
219
|
|
192
220
|
alias old_install install
|
193
|
-
|
194
221
|
def install name, requirement
|
195
|
-
|
222
|
+
self.class.value << [name, requirement]
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
class Gem::Uninstaller
|
227
|
+
extend BrutalStub
|
228
|
+
|
229
|
+
attr_reader :gem, :version, :gem_home
|
230
|
+
alias old_uninstall uninstall
|
231
|
+
def uninstall
|
232
|
+
self.class.value << [self.gem,
|
233
|
+
self.version.to_s,
|
234
|
+
self.gem_home.sub(Dir.pwd + "/", '')]
|
196
235
|
end
|
197
236
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: isolate
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Barnette
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2009-09-
|
13
|
+
date: 2009-09-30 00:00:00 -07:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|