tmptation 1.1
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/.gitignore +1 -0
- data/LICENSE +19 -0
- data/README.md +54 -0
- data/Rakefile +7 -0
- data/lib/tmptation.rb +171 -0
- data/specs.watchr +35 -0
- data/test/tmptation_test.rb +256 -0
- data/tmptation.gemspec +17 -0
- metadata +91 -0
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
*.gem
|
data/LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright © 2009 Martin Aumont (mynyml)
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
4
|
+
this software and associated documentation files (the "Software"), to deal in
|
5
|
+
the Software without restriction, including without limitation the rights to
|
6
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
7
|
+
of the Software, and to permit persons to whom the Software is furnished to do
|
8
|
+
so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
11
|
+
copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
19
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
Summary
|
2
|
+
-------
|
3
|
+
Tmptation provides classes that help safely manipulate temporary files and
|
4
|
+
directories. Especially useful for use in tests.
|
5
|
+
|
6
|
+
Features
|
7
|
+
--------
|
8
|
+
* garbage collection of all created tmp files and dirs
|
9
|
+
* safe deletion - will refuse to delete non-tmp paths (where tmp within `Dir.tmpdir`)
|
10
|
+
|
11
|
+
Examples
|
12
|
+
--------
|
13
|
+
|
14
|
+
# TmpFile is a subclass of Tempfile, with a few additions
|
15
|
+
|
16
|
+
file = TmpFile.new('name', 'contents')
|
17
|
+
|
18
|
+
file.path.exist? #=> true
|
19
|
+
file.closed? #=> false
|
20
|
+
file.read #=> "contents"
|
21
|
+
|
22
|
+
TmpFile.delete_all
|
23
|
+
|
24
|
+
file.path.exist? #=> false
|
25
|
+
file.closed? #=> true
|
26
|
+
|
27
|
+
|
28
|
+
# TmpDir is a subclass of Pathname, with a few additions
|
29
|
+
|
30
|
+
path = TmpDir.new
|
31
|
+
path.exist? #=> true
|
32
|
+
|
33
|
+
TmpDir.delete_all
|
34
|
+
path.exist? #=> false
|
35
|
+
|
36
|
+
Mixins
|
37
|
+
------
|
38
|
+
|
39
|
+
Tmptation also contains two mixins, `SafeDeletable` and `SubclassTracking`.
|
40
|
+
They might be useful on their own. See the inline docs for more details.
|
41
|
+
|
42
|
+
Protip
|
43
|
+
------
|
44
|
+
|
45
|
+
If you use Tmptation in specs, add `TmpFile.delete_all` and `TmpDir.delete_all`
|
46
|
+
to your global teardown method:
|
47
|
+
|
48
|
+
class MiniTest::Unit::TestCase
|
49
|
+
def teardown
|
50
|
+
TmpFile.delete_all
|
51
|
+
TmpDir.delete_all
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
data/Rakefile
ADDED
data/lib/tmptation.rb
ADDED
@@ -0,0 +1,171 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require 'tempfile'
|
3
|
+
require 'tmpdir'
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
module Tmptation
|
7
|
+
VERSION = 1.1
|
8
|
+
|
9
|
+
# Adds a #safe_delete method that will delete the object's associated path
|
10
|
+
# (either #path or #to_s, if it exists) only if it lives within the system's
|
11
|
+
# temporary directory (as defined by Dir.tmpdir)
|
12
|
+
#
|
13
|
+
# @example
|
14
|
+
#
|
15
|
+
# path = Pathname.new('~/Documents')
|
16
|
+
# path.extend(SafeDeletable)
|
17
|
+
#
|
18
|
+
# path.to_s #=> '~/Documents'
|
19
|
+
# path.safe_delete #=> raises UnsafeDelete
|
20
|
+
#
|
21
|
+
# # however:
|
22
|
+
#
|
23
|
+
# path = Pathname(Dir.mktmpdir).expand_path
|
24
|
+
#
|
25
|
+
# Dir.tmpdir #=> /var/folders/l8/l8EJIxZoHGGj+y1RvV0r6U+++TM/-Tmp-/
|
26
|
+
# path.to_s #=> /var/folders/l8/l8EJIxZoHGGj+y1RvV0r6U+++TM/-Tmp-/20101103-94996-1iywsjo
|
27
|
+
#
|
28
|
+
# path.exist? #=> true
|
29
|
+
# path.safe_delete
|
30
|
+
# path.exist? #=> false
|
31
|
+
#
|
32
|
+
module SafeDeletable
|
33
|
+
UnsafeDelete = Class.new(RuntimeError)
|
34
|
+
|
35
|
+
# Delete `#path` or `#to_s` if it exists, and only if it lives within
|
36
|
+
# `Dir.tmpdir`. If the path is a directory, it is deleted recursively.
|
37
|
+
#
|
38
|
+
# @raises SafeDeletable::UnsafeDelete if directory isn't within `Dir.tmpdir`
|
39
|
+
#
|
40
|
+
def safe_delete
|
41
|
+
path = self.respond_to?(:path) ? self.path : self.to_s
|
42
|
+
path = Pathname(path).expand_path
|
43
|
+
|
44
|
+
unless path.to_s.match(/^#{Regexp.escape(Dir.tmpdir)}/)
|
45
|
+
raise UnsafeDelete.new("refusing to remove non-tmp directory '#{path}'")
|
46
|
+
end
|
47
|
+
FileUtils.remove_entry_secure(path.to_s)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Keep track of a class's instances
|
52
|
+
#
|
53
|
+
# @example
|
54
|
+
#
|
55
|
+
# class Foo
|
56
|
+
# include InstanceTracking
|
57
|
+
# end
|
58
|
+
#
|
59
|
+
# a, b, c = Foo.new, Foo.new, Foo.new
|
60
|
+
#
|
61
|
+
# [a,b,c] == Foo.instances #=> true
|
62
|
+
#
|
63
|
+
module InstanceTracking
|
64
|
+
def self.included(base)
|
65
|
+
base.class_eval do
|
66
|
+
extend ClassMethods
|
67
|
+
include InstanceMethods
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
module ClassMethods
|
72
|
+
def instances
|
73
|
+
@instances ||= []
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
module InstanceMethods
|
78
|
+
def initialize(*args)
|
79
|
+
super
|
80
|
+
self.class.instances << self
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# Subclass of core lib's Tempfile that allows safely deleting all of its
|
86
|
+
# instances. It also provides a convenient way to add content to the file.
|
87
|
+
#
|
88
|
+
# @example
|
89
|
+
#
|
90
|
+
# file = TmpFile.new('name', 'contents')
|
91
|
+
#
|
92
|
+
# file.path.class #=> Pathname
|
93
|
+
# file.path.exist? #=> true
|
94
|
+
# file.closed? #=> false
|
95
|
+
# file.read #=> "contents"
|
96
|
+
#
|
97
|
+
# TmpFile.delete_all
|
98
|
+
#
|
99
|
+
# file.path.exist? #=> false
|
100
|
+
# file.closed? #=> true
|
101
|
+
#
|
102
|
+
class TmpFile < Tempfile
|
103
|
+
include SafeDeletable
|
104
|
+
include InstanceTracking
|
105
|
+
|
106
|
+
class << self
|
107
|
+
|
108
|
+
# Safe deletes and closes all instances
|
109
|
+
def delete_all
|
110
|
+
instances.each do |instance|
|
111
|
+
instance.safe_delete
|
112
|
+
instance.close
|
113
|
+
end
|
114
|
+
end
|
115
|
+
alias -@ delete_all
|
116
|
+
end
|
117
|
+
|
118
|
+
# @param name<String> optional
|
119
|
+
# prefix name of file
|
120
|
+
#
|
121
|
+
# @param body<String> optional
|
122
|
+
# contents of file
|
123
|
+
#
|
124
|
+
def initialize(name='anon', body='')
|
125
|
+
super(name)
|
126
|
+
self << body
|
127
|
+
self.rewind
|
128
|
+
end
|
129
|
+
|
130
|
+
# File's path as a Pathname
|
131
|
+
#
|
132
|
+
# @return path<Pathname>
|
133
|
+
#
|
134
|
+
def path
|
135
|
+
Pathname(super)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
# Subclass of core lib's Pathname that allows safely deleting all of its
|
140
|
+
# instances.
|
141
|
+
#
|
142
|
+
# @example
|
143
|
+
#
|
144
|
+
# path = TmpDir.new
|
145
|
+
# path.exist? #=> true
|
146
|
+
#
|
147
|
+
# TmpDir.delete_all
|
148
|
+
# path.exist? #=> false
|
149
|
+
#
|
150
|
+
class TmpDir < Pathname
|
151
|
+
include SafeDeletable
|
152
|
+
include InstanceTracking
|
153
|
+
|
154
|
+
class << self
|
155
|
+
|
156
|
+
# Safe deletes and closes all instances
|
157
|
+
def delete_all
|
158
|
+
instances.each {|instance| instance.safe_delete }
|
159
|
+
end
|
160
|
+
alias -@ delete_all
|
161
|
+
end
|
162
|
+
|
163
|
+
# @param prefix<String> optional
|
164
|
+
# prefix of directory name
|
165
|
+
#
|
166
|
+
def initialize(prefix='TmpDir-')
|
167
|
+
super(Pathname(Dir.mktmpdir(prefix)).expand_path)
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
data/specs.watchr
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
#!/usr/bin/env watchr
|
2
|
+
|
3
|
+
# --------------------------------------------------
|
4
|
+
# Rules
|
5
|
+
# --------------------------------------------------
|
6
|
+
watch( '^test.*_test\.rb' ) {|m| ruby m[0] }
|
7
|
+
watch( '^lib/(.*)\.rb' ) {|m| ruby "test/#{m[1]}_test.rb" }
|
8
|
+
|
9
|
+
# --------------------------------------------------
|
10
|
+
# Signal Handling
|
11
|
+
# --------------------------------------------------
|
12
|
+
Signal.trap('QUIT') { ruby tests } # Ctrl-\
|
13
|
+
Signal.trap('INT' ) { abort("\n") } # Ctrl-C
|
14
|
+
|
15
|
+
# --------------------------------------------------
|
16
|
+
# Helpers
|
17
|
+
# --------------------------------------------------
|
18
|
+
def ruby(*paths)
|
19
|
+
paths = paths.flatten.select {|p| File.exist?(p) && !File.directory?(p) }.join(' ')
|
20
|
+
run "ruby #{gem_opt} -I.:lib:test -e'%w( #{paths} ).each {|p| require p }'" unless paths.empty?
|
21
|
+
end
|
22
|
+
|
23
|
+
def tests
|
24
|
+
Dir['test/**/*_test.rb']
|
25
|
+
end
|
26
|
+
|
27
|
+
def run( cmd )
|
28
|
+
puts cmd
|
29
|
+
system cmd
|
30
|
+
end
|
31
|
+
|
32
|
+
def gem_opt
|
33
|
+
defined?(Gem) ? "-rubygems" : ""
|
34
|
+
end
|
35
|
+
|
@@ -0,0 +1,256 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'minitest/spec'
|
3
|
+
require 'rr'
|
4
|
+
|
5
|
+
begin require 'ruby-debug'; rescue LoadError; end
|
6
|
+
begin require 'redgreen' ; rescue LoadError; end
|
7
|
+
begin require 'phocus' ; rescue LoadError; end
|
8
|
+
|
9
|
+
class MiniTest::Unit::TestCase
|
10
|
+
include RR::Adapters::TestUnit
|
11
|
+
end
|
12
|
+
|
13
|
+
require 'tmptation'
|
14
|
+
include Tmptation
|
15
|
+
|
16
|
+
describe Tmptation do
|
17
|
+
it "should have a version" do
|
18
|
+
assert_kind_of Float, Tmptation::VERSION
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe Tmptation::SafeDeletable do
|
23
|
+
|
24
|
+
it "should delete a tmp directory" do
|
25
|
+
begin
|
26
|
+
dir = Pathname(Dir.mktmpdir('SafeDeletable-')).expand_path
|
27
|
+
dir.extend(SafeDeletable)
|
28
|
+
|
29
|
+
assert dir.exist?
|
30
|
+
assert_match /^#{Regexp.quote(Dir.tmpdir)}/, dir.to_s
|
31
|
+
|
32
|
+
dir.safe_delete
|
33
|
+
|
34
|
+
refute dir.exist?
|
35
|
+
ensure
|
36
|
+
dir.rmdir if dir.directory?
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should refuse to delete a non-tmp directory" do
|
41
|
+
begin
|
42
|
+
dir = Pathname(Dir.mktmpdir('SafeDeletable-')).expand_path
|
43
|
+
dir.extend(SafeDeletable)
|
44
|
+
|
45
|
+
stub(dir).to_s { '/not/a/tmp/dir' }
|
46
|
+
refute_match /^#{Regexp.quote(Dir.tmpdir)}/, dir.to_s
|
47
|
+
|
48
|
+
assert_raises(SafeDeletable::UnsafeDelete) { dir.safe_delete }
|
49
|
+
ensure
|
50
|
+
dir.rmdir if dir.directory?
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should hanled relative paths" do
|
55
|
+
begin
|
56
|
+
dir = Pathname(Dir.mktmpdir('SafeDeletable-')).relative_path_from(Pathname(Dir.pwd))
|
57
|
+
dir.extend(SafeDeletable)
|
58
|
+
|
59
|
+
assert_match /^#{Regexp.quote(Dir.tmpdir)}/, dir.expand_path.to_s
|
60
|
+
assert dir.relative?
|
61
|
+
|
62
|
+
dir.safe_delete
|
63
|
+
|
64
|
+
refute dir.exist?
|
65
|
+
ensure
|
66
|
+
dir.rmdir if dir.directory?
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should use an object's #path if it exists" do
|
71
|
+
begin
|
72
|
+
file = Tempfile.new('safe_deletable')
|
73
|
+
file.extend(SafeDeletable)
|
74
|
+
|
75
|
+
assert File.exist?(file.path)
|
76
|
+
assert_match /^#{Regexp.quote(Dir.tmpdir)}/, file.path.to_s
|
77
|
+
|
78
|
+
file.safe_delete
|
79
|
+
|
80
|
+
refute File.exist?(file.path)
|
81
|
+
ensure
|
82
|
+
file.delete if File.exist?(file)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe Tmptation::InstanceTracking do
|
88
|
+
|
89
|
+
before do
|
90
|
+
TmpFile.instance_variable_set(:@instances, nil)
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should keep track of class instances" do
|
94
|
+
klass = Class.new
|
95
|
+
klass.class_eval { include InstanceTracking }
|
96
|
+
|
97
|
+
assert_empty klass.instances
|
98
|
+
|
99
|
+
foo, bar = klass.new, klass.new
|
100
|
+
assert_equal [foo,bar], klass.instances
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
describe Tmptation::TmpFile do
|
105
|
+
|
106
|
+
before do
|
107
|
+
TmpFile.instance_variable_set(:@instances, nil)
|
108
|
+
end
|
109
|
+
|
110
|
+
it "should implement SafeDeletable" do
|
111
|
+
assert_includes TmpFile.included_modules, SafeDeletable
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should implement InstanceTracking" do
|
115
|
+
assert_includes TmpFile.included_modules, InstanceTracking
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should create a new temporary file on init" do
|
119
|
+
begin
|
120
|
+
foo = TmpFile.new
|
121
|
+
|
122
|
+
assert File.exist?(foo.path)
|
123
|
+
assert_match /^#{Regexp.quote(Dir.tmpdir)}/, foo.path.to_s
|
124
|
+
ensure
|
125
|
+
foo.delete if foo.path.exist?
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
it "should provide a path as Pathname" do
|
130
|
+
begin
|
131
|
+
foo = TmpFile.new
|
132
|
+
assert_kind_of Pathname, foo.path
|
133
|
+
ensure
|
134
|
+
foo.delete if foo.path.exist?
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
it "should allow setting a name and body on init" do
|
139
|
+
begin
|
140
|
+
foo = TmpFile.new('name', 'body')
|
141
|
+
|
142
|
+
assert_match /^name/, foo.path.basename.to_s
|
143
|
+
assert_equal 'body', foo.read
|
144
|
+
ensure
|
145
|
+
foo.delete if foo.path.exist?
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
it "should delete all instances" do
|
150
|
+
begin
|
151
|
+
foo, bar = TmpFile.new, TmpFile.new
|
152
|
+
|
153
|
+
assert foo.path.exist?
|
154
|
+
assert bar.path.exist?
|
155
|
+
|
156
|
+
TmpFile.delete_all
|
157
|
+
|
158
|
+
refute foo.path.exist?
|
159
|
+
refute bar.path.exist?
|
160
|
+
ensure
|
161
|
+
foo.delete if foo.path.exist?
|
162
|
+
bar.delete if bar.path.exist?
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
it "should use #safe_delete" do
|
167
|
+
begin
|
168
|
+
foo = TmpFile.new
|
169
|
+
|
170
|
+
mock(foo).safe_delete
|
171
|
+
TmpFile.delete_all
|
172
|
+
|
173
|
+
RR.verify
|
174
|
+
ensure
|
175
|
+
foo.delete if foo.path.exist?
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
it "should close files when deleting all instances" do
|
180
|
+
begin
|
181
|
+
foo = TmpFile.new
|
182
|
+
refute foo.closed?
|
183
|
+
|
184
|
+
TmpFile.delete_all
|
185
|
+
assert foo.closed?
|
186
|
+
ensure
|
187
|
+
foo.delete if foo.path.exist?
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
describe Tmptation::TmpDir do
|
193
|
+
|
194
|
+
before do
|
195
|
+
TmpDir.instance_variable_set(:@instances, nil)
|
196
|
+
end
|
197
|
+
|
198
|
+
it "should implement SafeDeletable" do
|
199
|
+
assert_includes TmpDir.included_modules, SafeDeletable
|
200
|
+
end
|
201
|
+
|
202
|
+
it "should implement InstanceTracking" do
|
203
|
+
assert_includes TmpFile.included_modules, InstanceTracking
|
204
|
+
end
|
205
|
+
|
206
|
+
it "should create a temporary directory on init" do
|
207
|
+
begin
|
208
|
+
foo = TmpDir.new
|
209
|
+
|
210
|
+
assert foo.exist?
|
211
|
+
assert_match /^#{Regexp.quote(Dir.tmpdir)}/, foo.to_s
|
212
|
+
ensure
|
213
|
+
foo.rmdir if foo.exist?
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
it "should allow setting a prefix on init" do
|
218
|
+
begin
|
219
|
+
foo = TmpDir.new('prefix-')
|
220
|
+
assert_match /^prefix/, foo.to_s.split('/').last
|
221
|
+
ensure
|
222
|
+
foo.rmdir if foo.exist?
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
it "should delete all instances" do
|
227
|
+
begin
|
228
|
+
foo, bar = TmpDir.new, TmpDir.new
|
229
|
+
|
230
|
+
assert foo.exist?
|
231
|
+
assert bar.exist?
|
232
|
+
|
233
|
+
TmpDir.delete_all
|
234
|
+
|
235
|
+
refute foo.exist?
|
236
|
+
refute bar.exist?
|
237
|
+
ensure
|
238
|
+
foo.rmdir if foo.exist?
|
239
|
+
bar.rmdir if foo.exist?
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
it "should use #safe_delete" do
|
244
|
+
begin
|
245
|
+
foo = TmpDir.new
|
246
|
+
|
247
|
+
mock(foo).safe_delete
|
248
|
+
TmpDir.delete_all
|
249
|
+
|
250
|
+
RR.verify
|
251
|
+
ensure
|
252
|
+
foo.rmdir if foo.exist?
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
data/tmptation.gemspec
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'lib/tmptation'
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = "tmptation"
|
5
|
+
s.version = Tmptation::VERSION
|
6
|
+
s.summary = "Classes that help safely manipulate temporary files and directories"
|
7
|
+
s.description = "Classes that help safely manipulate temporary files and directories."
|
8
|
+
s.author = "Martin Aumont"
|
9
|
+
s.email = "mynyml@gmail.com"
|
10
|
+
s.homepage = "http://github.com/mynyml/tmptation"
|
11
|
+
s.rubyforge_project = ""
|
12
|
+
s.require_path = "lib"
|
13
|
+
s.files = `git ls-files`.strip.split("\n")
|
14
|
+
|
15
|
+
s.add_development_dependency 'minitest'
|
16
|
+
s.add_development_dependency 'rr'
|
17
|
+
end
|
metadata
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: tmptation
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 1
|
7
|
+
- 1
|
8
|
+
version: "1.1"
|
9
|
+
platform: ruby
|
10
|
+
authors:
|
11
|
+
- Martin Aumont
|
12
|
+
autorequire:
|
13
|
+
bindir: bin
|
14
|
+
cert_chain: []
|
15
|
+
|
16
|
+
date: 2010-11-04 00:00:00 -07:00
|
17
|
+
default_executable:
|
18
|
+
dependencies:
|
19
|
+
- !ruby/object:Gem::Dependency
|
20
|
+
name: minitest
|
21
|
+
prerelease: false
|
22
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
segments:
|
27
|
+
- 0
|
28
|
+
version: "0"
|
29
|
+
type: :development
|
30
|
+
version_requirements: *id001
|
31
|
+
- !ruby/object:Gem::Dependency
|
32
|
+
name: rr
|
33
|
+
prerelease: false
|
34
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
35
|
+
requirements:
|
36
|
+
- - ">="
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
segments:
|
39
|
+
- 0
|
40
|
+
version: "0"
|
41
|
+
type: :development
|
42
|
+
version_requirements: *id002
|
43
|
+
description: Classes that help safely manipulate temporary files and directories.
|
44
|
+
email: mynyml@gmail.com
|
45
|
+
executables: []
|
46
|
+
|
47
|
+
extensions: []
|
48
|
+
|
49
|
+
extra_rdoc_files: []
|
50
|
+
|
51
|
+
files:
|
52
|
+
- .gitignore
|
53
|
+
- LICENSE
|
54
|
+
- README.md
|
55
|
+
- Rakefile
|
56
|
+
- lib/tmptation.rb
|
57
|
+
- specs.watchr
|
58
|
+
- test/tmptation_test.rb
|
59
|
+
- tmptation.gemspec
|
60
|
+
has_rdoc: true
|
61
|
+
homepage: http://github.com/mynyml/tmptation
|
62
|
+
licenses: []
|
63
|
+
|
64
|
+
post_install_message:
|
65
|
+
rdoc_options: []
|
66
|
+
|
67
|
+
require_paths:
|
68
|
+
- lib
|
69
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
segments:
|
74
|
+
- 0
|
75
|
+
version: "0"
|
76
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
segments:
|
81
|
+
- 0
|
82
|
+
version: "0"
|
83
|
+
requirements: []
|
84
|
+
|
85
|
+
rubyforge_project: ""
|
86
|
+
rubygems_version: 1.3.6
|
87
|
+
signing_key:
|
88
|
+
specification_version: 3
|
89
|
+
summary: Classes that help safely manipulate temporary files and directories
|
90
|
+
test_files: []
|
91
|
+
|