perennial 0.2.2.2 → 1.0.0.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/bin/perennial +1 -2
- data/lib/perennial/application.rb +65 -22
- data/lib/perennial/core_ext/attribute_accessors.rb +25 -0
- data/lib/perennial/core_ext/hash_key_conversions.rb +26 -0
- data/lib/perennial/core_ext/inflections.rb +33 -0
- data/lib/perennial/core_ext/misc.rb +33 -43
- data/lib/perennial/core_ext/proxy.rb +16 -0
- data/lib/perennial/core_ext.rb +4 -1
- data/lib/perennial/daemon.rb +9 -2
- data/lib/perennial/delegateable.rb +48 -0
- data/lib/perennial/dispatchable.rb +67 -24
- data/lib/perennial/generator.rb +43 -8
- data/lib/perennial/loader.rb +5 -1
- data/lib/perennial/logger.rb +14 -4
- data/lib/perennial/nash.rb +217 -0
- data/lib/perennial/option_parser.rb +3 -3
- data/lib/perennial/reloading.rb +45 -0
- data/lib/perennial/settings.rb +59 -31
- data/lib/perennial.rb +7 -5
- data/templates/application.erb +3 -2
- data/templates/rakefile.erb +1 -0
- metadata +10 -17
- data/test/dispatchable_test.rb +0 -129
- data/test/hookable_test.rb +0 -61
- data/test/loader_test.rb +0 -1
- data/test/loggable_test.rb +0 -38
- data/test/logger_test.rb +0 -57
- data/test/settings_test.rb +0 -99
- data/test/test_helper.rb +0 -38
- data/vendor/fakefs/LICENSE +0 -20
- data/vendor/fakefs/README.markdown +0 -37
- data/vendor/fakefs/Rakefile +0 -3
- data/vendor/fakefs/lib/fakefs.rb +0 -448
- data/vendor/fakefs/test/fakefs_test.rb +0 -511
- data/vendor/fakefs/test/verify.rb +0 -27
data/vendor/fakefs/lib/fakefs.rb
DELETED
@@ -1,448 +0,0 @@
|
|
1
|
-
require 'fileutils'
|
2
|
-
require 'pathname'
|
3
|
-
|
4
|
-
RealFile = File
|
5
|
-
RealFileUtils = FileUtils
|
6
|
-
RealDir = Dir
|
7
|
-
RealFileUtils::Dir = RealDir
|
8
|
-
RealFileUtils::File = RealFile
|
9
|
-
|
10
|
-
module FakeFS
|
11
|
-
module FileUtils
|
12
|
-
extend self
|
13
|
-
|
14
|
-
def mkdir_p(path)
|
15
|
-
FileSystem.add(path, MockDir.new)
|
16
|
-
end
|
17
|
-
|
18
|
-
def rm(path)
|
19
|
-
FileSystem.delete(path)
|
20
|
-
end
|
21
|
-
alias_method :rm_rf, :rm
|
22
|
-
|
23
|
-
def ln_s(target, path)
|
24
|
-
raise Errno::EEXIST, path if FileSystem.find(path)
|
25
|
-
FileSystem.add(path, MockSymlink.new(target))
|
26
|
-
end
|
27
|
-
|
28
|
-
def cp(src, dest)
|
29
|
-
dst_file = FileSystem.find(dest)
|
30
|
-
src_file = FileSystem.find(src)
|
31
|
-
|
32
|
-
if !src_file
|
33
|
-
raise Errno::ENOENT, src
|
34
|
-
end
|
35
|
-
|
36
|
-
if File.directory? src_file
|
37
|
-
raise Errno::EISDIR, src
|
38
|
-
end
|
39
|
-
|
40
|
-
if dst_file and File.directory?(dst_file)
|
41
|
-
FileSystem.add(File.join(dest, src), src_file.entry.clone(dst_file))
|
42
|
-
else
|
43
|
-
FileSystem.delete(dest)
|
44
|
-
FileSystem.add(dest, src_file.entry.clone)
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
def cp_r(src, dest)
|
49
|
-
# This error sucks, but it conforms to the original Ruby
|
50
|
-
# method.
|
51
|
-
raise "unknown file type: #{src}" unless dir = FileSystem.find(src)
|
52
|
-
|
53
|
-
new_dir = FileSystem.find(dest)
|
54
|
-
|
55
|
-
if new_dir && !File.directory?(dest)
|
56
|
-
raise Errno::EEXIST, dest
|
57
|
-
end
|
58
|
-
|
59
|
-
if !new_dir && !FileSystem.find(dest+'/../')
|
60
|
-
raise Errno::ENOENT, dest
|
61
|
-
end
|
62
|
-
|
63
|
-
# This last bit is a total abuse and should be thought hard
|
64
|
-
# about and cleaned up.
|
65
|
-
if new_dir
|
66
|
-
if src[-2..-1] == '/.'
|
67
|
-
dir.values.each{|f| new_dir[f.name] = f.clone(new_dir) }
|
68
|
-
else
|
69
|
-
new_dir[dir.name] = dir.entry.clone(new_dir)
|
70
|
-
end
|
71
|
-
else
|
72
|
-
FileSystem.add(dest, dir.entry.clone)
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
def mv(src, dest)
|
77
|
-
if target = FileSystem.find(src)
|
78
|
-
FileSystem.add(dest, target.entry.clone)
|
79
|
-
FileSystem.delete(src)
|
80
|
-
else
|
81
|
-
raise Errno::ENOENT, src
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
def chown(user, group, list, options={})
|
86
|
-
list = Array(list)
|
87
|
-
list.each do |f|
|
88
|
-
unless File.exists?(f)
|
89
|
-
raise Errno::ENOENT, f
|
90
|
-
end
|
91
|
-
end
|
92
|
-
list
|
93
|
-
end
|
94
|
-
|
95
|
-
def chown_R(user, group, list, options={})
|
96
|
-
chown(user, group, list, options={})
|
97
|
-
end
|
98
|
-
|
99
|
-
def touch(list, options={})
|
100
|
-
Array(list).each do |f|
|
101
|
-
directory = File.dirname(f)
|
102
|
-
# FIXME this explicit check for '.' shouldn't need to happen
|
103
|
-
if File.exists?(directory) || directory == '.'
|
104
|
-
FileSystem.add(f, MockFile.new)
|
105
|
-
else
|
106
|
-
raise Errno::ENOENT, f
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
class File
|
113
|
-
PATH_SEPARATOR = '/'
|
114
|
-
|
115
|
-
def self.join(*parts)
|
116
|
-
parts * PATH_SEPARATOR
|
117
|
-
end
|
118
|
-
|
119
|
-
def self.exist?(path)
|
120
|
-
FileSystem.find(path) || false
|
121
|
-
end
|
122
|
-
|
123
|
-
class << self
|
124
|
-
alias_method :exists?, :exist?
|
125
|
-
end
|
126
|
-
|
127
|
-
def self.directory?(path)
|
128
|
-
if path.respond_to? :entry
|
129
|
-
path.entry.is_a? MockDir
|
130
|
-
else
|
131
|
-
result = FileSystem.find(path)
|
132
|
-
result ? result.entry.is_a?(MockDir) : false
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
def self.symlink?(path)
|
137
|
-
if path.respond_to? :entry
|
138
|
-
path.is_a? MockSymlink
|
139
|
-
else
|
140
|
-
FileSystem.find(path).is_a? MockSymlink
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
def self.file?(path)
|
145
|
-
if path.respond_to? :entry
|
146
|
-
path.entry.is_a? MockFile
|
147
|
-
else
|
148
|
-
result = FileSystem.find(path)
|
149
|
-
result ? result.entry.is_a?(MockFile) : false
|
150
|
-
end
|
151
|
-
end
|
152
|
-
|
153
|
-
def self.expand_path(*args)
|
154
|
-
RealFile.expand_path(*args)
|
155
|
-
end
|
156
|
-
|
157
|
-
def self.basename(*args)
|
158
|
-
RealFile.basename(*args)
|
159
|
-
end
|
160
|
-
|
161
|
-
def self.dirname(path)
|
162
|
-
RealFile.dirname(path)
|
163
|
-
end
|
164
|
-
|
165
|
-
def self.readlink(path)
|
166
|
-
symlink = FileSystem.find(path)
|
167
|
-
FileSystem.find(symlink.target).to_s
|
168
|
-
end
|
169
|
-
|
170
|
-
def self.open(path, mode='r')
|
171
|
-
if block_given?
|
172
|
-
yield new(path, mode)
|
173
|
-
else
|
174
|
-
new(path, mode)
|
175
|
-
end
|
176
|
-
end
|
177
|
-
|
178
|
-
def self.read(path)
|
179
|
-
file = new(path)
|
180
|
-
if file.exists?
|
181
|
-
file.read
|
182
|
-
else
|
183
|
-
raise Errno::ENOENT
|
184
|
-
end
|
185
|
-
end
|
186
|
-
|
187
|
-
def self.readlines(path)
|
188
|
-
read(path).split("\n")
|
189
|
-
end
|
190
|
-
|
191
|
-
attr_reader :path
|
192
|
-
def initialize(path, mode = nil)
|
193
|
-
@path = path
|
194
|
-
@mode = mode
|
195
|
-
@file = FileSystem.find(path)
|
196
|
-
@open = true
|
197
|
-
end
|
198
|
-
|
199
|
-
def close
|
200
|
-
@open = false
|
201
|
-
end
|
202
|
-
|
203
|
-
def read
|
204
|
-
raise IOError.new('closed stream') unless @open
|
205
|
-
@file.content
|
206
|
-
end
|
207
|
-
|
208
|
-
def exists?
|
209
|
-
@file
|
210
|
-
end
|
211
|
-
|
212
|
-
def puts(content)
|
213
|
-
write(content + "\n")
|
214
|
-
end
|
215
|
-
|
216
|
-
def write(content)
|
217
|
-
raise IOError.new('closed stream') unless @open
|
218
|
-
|
219
|
-
if !File.exists?(@path)
|
220
|
-
@file = FileSystem.add(path, MockFile.new)
|
221
|
-
end
|
222
|
-
|
223
|
-
@file.content += content
|
224
|
-
end
|
225
|
-
alias_method :print, :write
|
226
|
-
alias_method :<<, :write
|
227
|
-
|
228
|
-
def flush; self; end
|
229
|
-
end
|
230
|
-
|
231
|
-
class Dir
|
232
|
-
def self.glob(pattern)
|
233
|
-
if pattern[-1,1] == '*'
|
234
|
-
blk = proc { |entry| entry.to_s }
|
235
|
-
else
|
236
|
-
blk = proc { |entry| entry[1].parent.to_s }
|
237
|
-
end
|
238
|
-
(FileSystem.find(pattern) || []).map(&blk).uniq.sort
|
239
|
-
end
|
240
|
-
|
241
|
-
def self.[](pattern)
|
242
|
-
glob(pattern)
|
243
|
-
end
|
244
|
-
|
245
|
-
def self.chdir(dir, &blk)
|
246
|
-
FileSystem.chdir(dir, &blk)
|
247
|
-
end
|
248
|
-
end
|
249
|
-
|
250
|
-
module FileSystem
|
251
|
-
extend self
|
252
|
-
|
253
|
-
def dir_levels
|
254
|
-
@dir_levels ||= []
|
255
|
-
end
|
256
|
-
|
257
|
-
def fs
|
258
|
-
@fs ||= MockDir.new('.')
|
259
|
-
end
|
260
|
-
|
261
|
-
def clear
|
262
|
-
@dir_levels = nil
|
263
|
-
@fs = nil
|
264
|
-
end
|
265
|
-
|
266
|
-
def files
|
267
|
-
fs.values
|
268
|
-
end
|
269
|
-
|
270
|
-
def find(path)
|
271
|
-
parts = path_parts(normalize_path(path))
|
272
|
-
|
273
|
-
target = parts[0...-1].inject(fs) do |dir, part|
|
274
|
-
dir[part] || {}
|
275
|
-
end
|
276
|
-
|
277
|
-
case parts.last
|
278
|
-
when '*'
|
279
|
-
target.values
|
280
|
-
else
|
281
|
-
target[parts.last]
|
282
|
-
end
|
283
|
-
end
|
284
|
-
|
285
|
-
def add(path, object=MockDir.new)
|
286
|
-
parts = path_parts(normalize_path(path))
|
287
|
-
|
288
|
-
d = parts[0...-1].inject(fs) do |dir, part|
|
289
|
-
dir[part] ||= MockDir.new(part, dir)
|
290
|
-
end
|
291
|
-
|
292
|
-
object.name = parts.last
|
293
|
-
object.parent = d
|
294
|
-
d[parts.last] ||= object
|
295
|
-
end
|
296
|
-
|
297
|
-
# copies directories and files from the real filesystem
|
298
|
-
# into our fake one
|
299
|
-
def clone(path)
|
300
|
-
path = File.expand_path(path)
|
301
|
-
pattern = File.join(path, '**', '*')
|
302
|
-
files = RealFile.file?(path) ? [path] : [path] + RealDir.glob(pattern, RealFile::FNM_DOTMATCH)
|
303
|
-
|
304
|
-
files.each do |f|
|
305
|
-
if RealFile.file?(f)
|
306
|
-
FileUtils.mkdir_p(File.dirname(f))
|
307
|
-
File.open(f, 'w') do |g|
|
308
|
-
g.print RealFile.open(f){|h| h.read }
|
309
|
-
end
|
310
|
-
elsif RealFile.directory?(f)
|
311
|
-
FileUtils.mkdir_p(f)
|
312
|
-
elsif RealFile.symlink?(f)
|
313
|
-
FileUtils.ln_s()
|
314
|
-
end
|
315
|
-
end
|
316
|
-
end
|
317
|
-
|
318
|
-
def delete(path)
|
319
|
-
if dir = FileSystem.find(path)
|
320
|
-
dir.parent.delete(dir.name)
|
321
|
-
end
|
322
|
-
end
|
323
|
-
|
324
|
-
def chdir(dir, &blk)
|
325
|
-
new_dir = find(dir)
|
326
|
-
dir_levels.push dir if blk
|
327
|
-
|
328
|
-
raise Errno::ENOENT, dir unless new_dir
|
329
|
-
|
330
|
-
dir_levels.push dir if !blk
|
331
|
-
blk.call if blk
|
332
|
-
ensure
|
333
|
-
dir_levels.pop if blk
|
334
|
-
end
|
335
|
-
|
336
|
-
def path_parts(path)
|
337
|
-
path.split(File::PATH_SEPARATOR).reject { |part| part.empty? }
|
338
|
-
end
|
339
|
-
|
340
|
-
def normalize_path(path)
|
341
|
-
if Pathname.new(path).absolute?
|
342
|
-
File.expand_path(path)
|
343
|
-
else
|
344
|
-
parts = dir_levels + [path]
|
345
|
-
File.expand_path(File.join(*parts))
|
346
|
-
end
|
347
|
-
end
|
348
|
-
|
349
|
-
def current_dir
|
350
|
-
find(normalize_path('.'))
|
351
|
-
end
|
352
|
-
end
|
353
|
-
|
354
|
-
class MockFile
|
355
|
-
attr_accessor :name, :parent, :content
|
356
|
-
|
357
|
-
def initialize(name = nil, parent = nil)
|
358
|
-
@name = name
|
359
|
-
@parent = parent
|
360
|
-
@content = ''
|
361
|
-
end
|
362
|
-
|
363
|
-
def clone(parent = nil)
|
364
|
-
clone = super()
|
365
|
-
clone.parent = parent if parent
|
366
|
-
clone
|
367
|
-
end
|
368
|
-
|
369
|
-
def entry
|
370
|
-
self
|
371
|
-
end
|
372
|
-
|
373
|
-
def inspect
|
374
|
-
"(MockFile name:#{name.inspect} parent:#{parent.to_s.inspect} size:#{content.size})"
|
375
|
-
end
|
376
|
-
|
377
|
-
def to_s
|
378
|
-
File.join(parent.to_s, name)
|
379
|
-
end
|
380
|
-
end
|
381
|
-
|
382
|
-
class MockDir < Hash
|
383
|
-
attr_accessor :name, :parent
|
384
|
-
|
385
|
-
def initialize(name = nil, parent = nil)
|
386
|
-
@name = name
|
387
|
-
@parent = parent
|
388
|
-
end
|
389
|
-
|
390
|
-
def entry
|
391
|
-
self
|
392
|
-
end
|
393
|
-
|
394
|
-
def inspect
|
395
|
-
"(MockDir name:#{name.inspect} parent:#{parent.to_s.inspect} size:#{size})"
|
396
|
-
end
|
397
|
-
|
398
|
-
def clone(parent = nil)
|
399
|
-
clone = Marshal.load(Marshal.dump(self))
|
400
|
-
clone.each do |key, value|
|
401
|
-
value.parent = clone
|
402
|
-
end
|
403
|
-
clone.parent = parent if parent
|
404
|
-
clone
|
405
|
-
end
|
406
|
-
|
407
|
-
def to_s
|
408
|
-
if parent && parent.to_s != '.'
|
409
|
-
File.join(parent.to_s, name)
|
410
|
-
elsif parent && parent.to_s == '.'
|
411
|
-
"#{File::PATH_SEPARATOR}#{name}"
|
412
|
-
else
|
413
|
-
name
|
414
|
-
end
|
415
|
-
end
|
416
|
-
end
|
417
|
-
|
418
|
-
class MockSymlink
|
419
|
-
attr_accessor :name, :target
|
420
|
-
alias_method :to_s, :name
|
421
|
-
|
422
|
-
def initialize(target)
|
423
|
-
@target = target
|
424
|
-
end
|
425
|
-
|
426
|
-
def inspect
|
427
|
-
"symlink(#{target.split('/').last})"
|
428
|
-
end
|
429
|
-
|
430
|
-
def entry
|
431
|
-
FileSystem.find(target)
|
432
|
-
end
|
433
|
-
|
434
|
-
def method_missing(*args, &block)
|
435
|
-
entry.send(*args, &block)
|
436
|
-
end
|
437
|
-
end
|
438
|
-
end
|
439
|
-
|
440
|
-
Object.class_eval do
|
441
|
-
remove_const(:Dir)
|
442
|
-
remove_const(:File)
|
443
|
-
remove_const(:FileUtils)
|
444
|
-
end
|
445
|
-
|
446
|
-
File = FakeFS::File
|
447
|
-
FileUtils = FakeFS::FileUtils
|
448
|
-
Dir = FakeFS::Dir
|