roll 1.1.0 → 1.2.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/HISTORY +28 -4
- data/PACKAGE +6 -0
- data/PROFILE +22 -0
- data/README.rdoc +66 -59
- data/bin/roll +7 -1
- data/lib/oll.rb +1 -1
- data/lib/roll.rb +30 -9
- data/lib/roll/command.rb +40 -177
- data/lib/roll/commands/env.rb +24 -0
- data/lib/roll/commands/help.rb +30 -0
- data/lib/roll/commands/in.rb +26 -0
- data/lib/roll/commands/index.rb +20 -0
- data/lib/roll/commands/list.rb +33 -0
- data/lib/roll/commands/out.rb +22 -0
- data/lib/roll/commands/path.rb +50 -0
- data/lib/roll/commands/sync.rb +29 -0
- data/lib/roll/commands/use.rb +25 -0
- data/lib/roll/commands/verify.rb +22 -0
- data/lib/roll/config.rb +8 -3
- data/lib/roll/environment.rb +84 -42
- data/lib/roll/kernel.rb +9 -2
- data/lib/roll/library.rb +360 -21
- data/lib/roll/metadata.rb +282 -51
- data/lib/roll/original.rb +3 -3
- data/lib/roll/version.rb +6 -7
- data/script/setup +14 -18
- data/script/setup.old +1344 -0
- data/test/{unitcases/version_case.rb → version_case.rb} +1 -1
- metadata +30 -47
- data/TODO +0 -4
- data/lib/roll/errors.rb +0 -13
- data/lib/roll/ledger.rb +0 -299
- data/lib/roll/locals.rb +0 -96
- data/meta/active +0 -1
- data/meta/authors +0 -1
- data/meta/contact +0 -1
- data/meta/created +0 -1
- data/meta/description +0 -5
- data/meta/homepage +0 -1
- data/meta/maintainer +0 -1
- data/meta/name +0 -1
- data/meta/repository +0 -1
- data/meta/ruby +0 -2
- data/meta/suite +0 -1
- data/meta/summary +0 -1
- data/meta/version +0 -1
- data/script/test +0 -23
- data/test/benchmarks/vsgems.rb +0 -11
- data/test/benchmarks/vsgems_bm.rb +0 -17
- data/test/demonstrations/01_library.rdoc +0 -33
- data/test/demonstrations/04_version.rdoc +0 -56
- data/test/fixtures/env.list +0 -1
- data/test/fixtures/inspect.rb +0 -12
- data/test/fixtures/tryme/1.0/lib/tryme.rb +0 -1
- data/test/fixtures/tryme/1.0/meta/homepage +0 -1
- data/test/fixtures/tryme/1.0/meta/name +0 -1
- data/test/fixtures/tryme/1.0/meta/version +0 -1
- data/test/fixtures/tryme/1.1/lib/tryme.rb +0 -1
- data/test/fixtures/tryme/1.1/meta/homepage +0 -1
- data/test/fixtures/tryme/1.1/meta/name +0 -1
- data/test/fixtures/tryme/1.1/meta/version +0 -1
- data/test/unit/version_test.rb +0 -71
data/lib/roll/kernel.rb
CHANGED
@@ -1,7 +1,14 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# Rubinius standard
|
2
|
+
RUBY_IGNORE_CALLERS = [] unless defined? RUBY_IGNORE_CALLERS
|
3
|
+
RUBY_IGNORE_CALLERS << %r{roll/kernel\.rb$}
|
4
|
+
RUBY_IGNORE_CALLERS << %r{roll/original\.rb$}
|
3
5
|
|
4
6
|
module ::Kernel
|
7
|
+
alias_method :roll_original_require, :require
|
8
|
+
alias_method :roll_original_load, :load
|
9
|
+
|
10
|
+
#alias_method :gem_original_require, :require
|
11
|
+
#alias_method :gem_original_load, :load
|
5
12
|
|
6
13
|
# In which library is the current file participating?
|
7
14
|
def __LIBRARY__
|
data/lib/roll/library.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
|
-
#require 'rbconfig'
|
2
1
|
require 'roll/version'
|
3
2
|
require 'roll/metadata'
|
4
|
-
require 'roll/
|
3
|
+
require 'roll/environment'
|
5
4
|
|
6
5
|
module Roll
|
7
6
|
|
@@ -13,7 +12,6 @@ module Roll
|
|
13
12
|
#DLEXT = '.' + ::Config::CONFIG['DLEXT']
|
14
13
|
|
15
14
|
#
|
16
|
-
#SUFFIXES = ['', '.rb', '.rbw', '.so', '.bundle', '.dll', '.sl', '.jar']
|
17
15
|
SUFFIXES = ['', '.rb', '.rbw', '.so', '.bundle', '.dll', '.sl', '.jar']
|
18
16
|
|
19
17
|
#
|
@@ -71,9 +69,10 @@ module Roll
|
|
71
69
|
end
|
72
70
|
|
73
71
|
#
|
74
|
-
def initialize(location, name=nil)
|
72
|
+
def initialize(location, name=nil, options={})
|
75
73
|
@location = location
|
76
74
|
@name = name
|
75
|
+
@options = options
|
77
76
|
end
|
78
77
|
|
79
78
|
#
|
@@ -81,6 +80,11 @@ module Roll
|
|
81
80
|
@location
|
82
81
|
end
|
83
82
|
|
83
|
+
# Access to metadata.
|
84
|
+
def metadata
|
85
|
+
@metadata ||= Metadata.new(location, name, @options)
|
86
|
+
end
|
87
|
+
|
84
88
|
#
|
85
89
|
def name
|
86
90
|
@name ||= metadata.name
|
@@ -93,7 +97,7 @@ module Roll
|
|
93
97
|
|
94
98
|
#
|
95
99
|
def active?
|
96
|
-
|
100
|
+
true #@active ||= metadata.active
|
97
101
|
end
|
98
102
|
|
99
103
|
#
|
@@ -111,7 +115,7 @@ module Roll
|
|
111
115
|
@released ||= metadata.released
|
112
116
|
end
|
113
117
|
|
114
|
-
#
|
118
|
+
# TODO
|
115
119
|
def verify
|
116
120
|
requires.each do |(name, constraint)|
|
117
121
|
Library.open(name, constraint)
|
@@ -133,15 +137,16 @@ module Roll
|
|
133
137
|
# Standard loadpath search.
|
134
138
|
#
|
135
139
|
def find(file, suffix=true)
|
140
|
+
lp = loadpath
|
136
141
|
if suffix
|
137
142
|
SUFFIXES.each do |ext|
|
138
|
-
|
143
|
+
lp.each do |lpath|
|
139
144
|
f = File.join(location, lpath, file + ext)
|
140
145
|
return f if File.file?(f)
|
141
146
|
end
|
142
147
|
end
|
143
148
|
else
|
144
|
-
|
149
|
+
lp.each do |lpath|
|
145
150
|
f = File.join(location, lpath, file)
|
146
151
|
return f if File.file?(f)
|
147
152
|
end
|
@@ -153,12 +158,12 @@ module Roll
|
|
153
158
|
# of the file is returned.
|
154
159
|
#
|
155
160
|
# Unlike #find, this also matches within the library directory
|
156
|
-
# itself, eg. <tt>lib/foo/*</tt>. It is used by #
|
157
|
-
#
|
161
|
+
# itself, eg. <tt>lib/foo/*</tt>. It is used by #acquire.
|
158
162
|
def include?(file, suffix=true)
|
163
|
+
lp = loadpath
|
159
164
|
if suffix
|
160
165
|
SUFFIXES.each do |ext|
|
161
|
-
|
166
|
+
lp.each do |lpath|
|
162
167
|
f = File.join(location, lpath, name, file + ext)
|
163
168
|
return f if File.file?(f)
|
164
169
|
f = File.join(location, lpath, file + ext)
|
@@ -166,7 +171,7 @@ module Roll
|
|
166
171
|
end
|
167
172
|
end
|
168
173
|
else
|
169
|
-
|
174
|
+
lp.each do |lpath|
|
170
175
|
f = File.join(location, lpath, name, file)
|
171
176
|
return f if File.file?(f)
|
172
177
|
f = File.join(location, lpath, file)
|
@@ -201,7 +206,7 @@ module Roll
|
|
201
206
|
#Library.load_monitor[file] << caller if $LOAD_MONITOR
|
202
207
|
Library.load_stack << self
|
203
208
|
begin
|
204
|
-
success =
|
209
|
+
success = roll_original_require(file)
|
205
210
|
#rescue LoadError => load_error
|
206
211
|
# raise clean_backtrace(load_error)
|
207
212
|
ensure
|
@@ -225,7 +230,7 @@ module Roll
|
|
225
230
|
#Library.load_monitor[file] << caller if $LOAD_MONITOR
|
226
231
|
Library.load_stack << self
|
227
232
|
begin
|
228
|
-
success =
|
233
|
+
success = roll_original_load(file, wrap)
|
229
234
|
#rescue LoadError => load_error
|
230
235
|
# raise clean_backtrace(load_error)
|
231
236
|
ensure
|
@@ -236,7 +241,7 @@ module Roll
|
|
236
241
|
|
237
242
|
# Inspection.
|
238
243
|
def inspect
|
239
|
-
if
|
244
|
+
if version
|
240
245
|
%[#<Library #{name}/#{@version} @location="#{location}">]
|
241
246
|
else
|
242
247
|
%[#<Library #{name} @location="#{location}">]
|
@@ -278,7 +283,7 @@ module Roll
|
|
278
283
|
# This is alwasy the <tt>etc/</tt> directory.
|
279
284
|
def confdir ; File.join(location, 'etc') ; end
|
280
285
|
|
281
|
-
# Is there a <tt>etc/</tt> location?
|
286
|
+
# Is there a <tt>etc/</tt> location?
|
282
287
|
def confdir? ; File.exist?(confdir) ; end
|
283
288
|
|
284
289
|
# Location of library shared data directory.
|
@@ -288,11 +293,6 @@ module Roll
|
|
288
293
|
# Is there a <tt>data/</tt> location?
|
289
294
|
def datadir? ; File.exist?(datadir) ; end
|
290
295
|
|
291
|
-
# Access to secondary metadata.
|
292
|
-
def metadata
|
293
|
-
@metadata ||= Metadata.new(location)
|
294
|
-
end
|
295
|
-
|
296
296
|
private
|
297
297
|
|
298
298
|
#
|
@@ -312,6 +312,345 @@ module Roll
|
|
312
312
|
end
|
313
313
|
end
|
314
314
|
|
315
|
+
# Ledger augments the Library metaclass.
|
316
|
+
class << self
|
317
|
+
# Instance of Ledger class.
|
318
|
+
def ledger
|
319
|
+
@ledger ||= Ledger.new
|
320
|
+
end
|
321
|
+
|
322
|
+
# Current environment
|
323
|
+
def environment
|
324
|
+
ledger.environment
|
325
|
+
end
|
326
|
+
|
327
|
+
# List of library names.
|
328
|
+
def list
|
329
|
+
ledger.names
|
330
|
+
end
|
331
|
+
|
332
|
+
#
|
333
|
+
def require(path)
|
334
|
+
ledger.require(path)
|
335
|
+
end
|
336
|
+
|
337
|
+
#
|
338
|
+
def load(path, wrap=nil)
|
339
|
+
ledger.load(path, wrap)
|
340
|
+
end
|
341
|
+
|
342
|
+
#
|
343
|
+
def acquire(path, opts={})
|
344
|
+
ledger.acquire(path, opts)
|
345
|
+
end
|
346
|
+
|
347
|
+
#
|
348
|
+
def load_stack
|
349
|
+
ledger.load_stack
|
350
|
+
end
|
351
|
+
|
352
|
+
## NOTE: Not used yet.
|
353
|
+
#def load_monitor
|
354
|
+
# ledger.load_monitor
|
355
|
+
#end
|
356
|
+
end
|
357
|
+
end
|
358
|
+
|
359
|
+
# = Ledger class
|
360
|
+
#
|
361
|
+
class Ledger
|
362
|
+
|
363
|
+
include Enumerable
|
364
|
+
|
365
|
+
#
|
366
|
+
def initialize
|
367
|
+
@index = Hash.new{|h,k| h[k] = []}
|
368
|
+
|
369
|
+
@environment = Environment.new
|
370
|
+
|
371
|
+
@environment.each do |name, paths|
|
372
|
+
paths.each do |path|
|
373
|
+
unless File.directory?(path)
|
374
|
+
warn "invalid path for #{name} -- #{path}"
|
375
|
+
next
|
376
|
+
end
|
377
|
+
lib = Library.new(path, name)
|
378
|
+
@index[name] << lib if lib.active?
|
379
|
+
end
|
380
|
+
end
|
381
|
+
|
382
|
+
@load_stack = []
|
383
|
+
#@load_monitor = Hash.new{ |h,k| h[k]=[] }
|
384
|
+
end
|
385
|
+
|
386
|
+
#
|
387
|
+
def enironment
|
388
|
+
@environment
|
389
|
+
end
|
390
|
+
|
391
|
+
#
|
392
|
+
def [](name)
|
393
|
+
@index[name]
|
394
|
+
end
|
395
|
+
|
396
|
+
#
|
397
|
+
def []=(name, value)
|
398
|
+
@index[name] = value
|
399
|
+
end
|
400
|
+
|
401
|
+
#
|
402
|
+
def include?(name)
|
403
|
+
@index.include?(name)
|
404
|
+
end
|
405
|
+
|
406
|
+
#
|
407
|
+
def names
|
408
|
+
@index.keys
|
409
|
+
end
|
410
|
+
|
411
|
+
#
|
412
|
+
def each(&block)
|
413
|
+
@index.each(&block)
|
414
|
+
end
|
415
|
+
|
416
|
+
#
|
417
|
+
def size
|
418
|
+
@index.size
|
419
|
+
end
|
420
|
+
|
421
|
+
#
|
422
|
+
def load_stack
|
423
|
+
@load_stack
|
424
|
+
end
|
425
|
+
|
426
|
+
## NOTE: Not used yet.
|
427
|
+
#def load_monitor
|
428
|
+
# @load_monitor
|
429
|
+
#end
|
430
|
+
|
431
|
+
#--
|
432
|
+
# The BIG QUESTION: Should Ruby's underlying require
|
433
|
+
# be tried first then fallback to Rolls. Or vice-versa?
|
434
|
+
#
|
435
|
+
# begin
|
436
|
+
# original_require(path)
|
437
|
+
# rescue LoadError => load_error
|
438
|
+
# lib, file = *match(path)
|
439
|
+
# if lib && file
|
440
|
+
# constrain(lib)
|
441
|
+
# lib.require_absolute(file)
|
442
|
+
# else
|
443
|
+
# raise clean_backtrace(load_error)
|
444
|
+
# end
|
445
|
+
# end
|
446
|
+
#++
|
447
|
+
|
448
|
+
#
|
449
|
+
def require(path)
|
450
|
+
#return if $".include?(path)
|
451
|
+
#return if $".include?(path+'.rb')
|
452
|
+
|
453
|
+
lib, file = *match(path)
|
454
|
+
if lib && file
|
455
|
+
constrain(lib)
|
456
|
+
lib.require_absolute(file)
|
457
|
+
else
|
458
|
+
begin
|
459
|
+
roll_original_require(path)
|
460
|
+
rescue LoadError => load_error
|
461
|
+
raise clean_backtrace(load_error)
|
462
|
+
end
|
463
|
+
end
|
464
|
+
|
465
|
+
end
|
466
|
+
|
467
|
+
#
|
468
|
+
def load(path, wrap=nil)
|
469
|
+
lib, file = *match(path, false)
|
470
|
+
if lib && file
|
471
|
+
constrain(lib)
|
472
|
+
lib.load_absolute(file, wrap)
|
473
|
+
else
|
474
|
+
begin
|
475
|
+
roll_original_load(path, wrap)
|
476
|
+
rescue LoadError => load_error
|
477
|
+
raise clean_backtrace(load_error)
|
478
|
+
end
|
479
|
+
end
|
480
|
+
end
|
481
|
+
|
482
|
+
# Acquire is pure Roll-style loading. First it
|
483
|
+
# looks for a specific library via ':'. If ':' is
|
484
|
+
# not present it then tries the current library.
|
485
|
+
# Failing that it fallsback to Ruby itself.
|
486
|
+
#
|
487
|
+
# acquire('facets:string/margin')
|
488
|
+
#
|
489
|
+
# To "load" the library, rather than "require" it set
|
490
|
+
# the +:load+ option to true.
|
491
|
+
#
|
492
|
+
# acquire('facets:string/margin', :load=>true)
|
493
|
+
#
|
494
|
+
def acquire(file, opts={})
|
495
|
+
if file.index(':') # a specific library
|
496
|
+
name, file = file.split(':')
|
497
|
+
lib = Library.open(name)
|
498
|
+
else # try the current library
|
499
|
+
cur = load_stack.last
|
500
|
+
if cur && cur.include?(file)
|
501
|
+
lib = cur
|
502
|
+
elsif !file.index('/') # is this a library name?
|
503
|
+
if cur = Library.instance(file)
|
504
|
+
lib = cur
|
505
|
+
file = lib.default # default file to load
|
506
|
+
end
|
507
|
+
end
|
508
|
+
end
|
509
|
+
if opts[:load]
|
510
|
+
lib ? lib.load(file) : roll_original_load(file)
|
511
|
+
else
|
512
|
+
lib ? lib.require(file) : roll_original_require(file)
|
513
|
+
end
|
514
|
+
end
|
515
|
+
|
516
|
+
#
|
517
|
+
def constrain(lib)
|
518
|
+
cmp = self[lib.name]
|
519
|
+
if Array === cmp
|
520
|
+
self[lib.name] = lib
|
521
|
+
else
|
522
|
+
if lib.version != cmp.version
|
523
|
+
raise VersionError
|
524
|
+
end
|
525
|
+
end
|
526
|
+
end
|
527
|
+
|
528
|
+
private
|
529
|
+
|
530
|
+
# Find require matches.
|
531
|
+
def match(path, suffix=true)
|
532
|
+
path = path.to_s
|
533
|
+
|
534
|
+
# Ruby appears to have a special exception for enumerator.
|
535
|
+
return nil if path == 'enumerator'
|
536
|
+
|
537
|
+
# absolute path
|
538
|
+
return nil if /^\// =~ path
|
539
|
+
|
540
|
+
if path.index(':') # a specified library
|
541
|
+
name, path = path.split(':')
|
542
|
+
lib = Library.open(name)
|
543
|
+
if lib.active?
|
544
|
+
#file = lib.find(File.join(name,path), suffix)
|
545
|
+
file = lib.include?(path, suffix)
|
546
|
+
return lib, file
|
547
|
+
end
|
548
|
+
end
|
549
|
+
|
550
|
+
matches = []
|
551
|
+
|
552
|
+
# try the load stack first
|
553
|
+
load_stack.reverse_each do |lib|
|
554
|
+
if file = lib.find(path, suffix)
|
555
|
+
return [lib, file] unless $VERBOSE
|
556
|
+
matches << [lib, file]
|
557
|
+
end
|
558
|
+
end
|
559
|
+
|
560
|
+
# if the head of the path is the library
|
561
|
+
name, *_ = path.split(/\/|\\/)
|
562
|
+
lib = Library[name]
|
563
|
+
if lib && lib.active?
|
564
|
+
if file = lib.find(path, suffix)
|
565
|
+
return [lib, file] unless $VERBOSE
|
566
|
+
matches << [lib, file]
|
567
|
+
end
|
568
|
+
end
|
569
|
+
|
570
|
+
# standard ruby locations
|
571
|
+
return nil if $LOAD_PATH.find do |lp|
|
572
|
+
if suffix
|
573
|
+
Library::SUFFIXES.find do |s|
|
574
|
+
File.exist?(File.join(lp, path + s))
|
575
|
+
end
|
576
|
+
else
|
577
|
+
File.exist?(File.join(lp, path))
|
578
|
+
end
|
579
|
+
end
|
580
|
+
|
581
|
+
|
582
|
+
# TODO: Perhaps the selected and unselected should be kept in separate lists?
|
583
|
+
unselected, selected = *@index.partition{ |name, libs| Array === libs }
|
584
|
+
|
585
|
+
# broad search pre-selected libraries
|
586
|
+
selected.each do |(name, lib)|
|
587
|
+
if file = lib.find(path, suffix)
|
588
|
+
#matches << [lib, file]
|
589
|
+
#return matches.first unless $VERBOSE
|
590
|
+
return [lib, file] unless $VERBOSE
|
591
|
+
matches << [lib, file]
|
592
|
+
end
|
593
|
+
end
|
594
|
+
|
595
|
+
# finally try a broad search on unselected libraries
|
596
|
+
unselected.each do |(name, libs)|
|
597
|
+
pos = []
|
598
|
+
libs.each do |lib|
|
599
|
+
if file = lib.find(path, suffix)
|
600
|
+
pos << [lib, file]
|
601
|
+
end
|
602
|
+
end
|
603
|
+
unless pos.empty?
|
604
|
+
latest = pos.sort{ |a,b| b[0].version <=> a[0].version }.first
|
605
|
+
return latest unless $VERBOSE
|
606
|
+
matches << latest
|
607
|
+
#return matches.first unless $VERBOSE
|
608
|
+
end
|
609
|
+
end
|
610
|
+
|
611
|
+
matches.uniq!
|
612
|
+
|
613
|
+
if matches.size > 1
|
614
|
+
warn_multiples(path, matches)
|
615
|
+
end
|
616
|
+
|
617
|
+
matches.first
|
618
|
+
end
|
619
|
+
|
620
|
+
#
|
621
|
+
def warn_multiples(path, matches)
|
622
|
+
warn "multiple matches for same request -- #{path}"
|
623
|
+
matches.each do |lib, file|
|
624
|
+
warn " #{file}"
|
625
|
+
end
|
626
|
+
end
|
627
|
+
|
628
|
+
#
|
629
|
+
def warn(message)
|
630
|
+
$stderr.puts("roll: #{message}") if $DEBUG || $VERBOSE
|
631
|
+
end
|
632
|
+
|
633
|
+
#
|
634
|
+
def clean_backtrace(error)
|
635
|
+
if $DEBUG
|
636
|
+
error
|
637
|
+
else
|
638
|
+
bt = error.backtrace
|
639
|
+
bt = bt.reject{ |e| /roll/ =~ e }
|
640
|
+
error.set_backtrace(bt)
|
641
|
+
error
|
642
|
+
end
|
643
|
+
end
|
644
|
+
|
645
|
+
end#class Ledger
|
646
|
+
|
647
|
+
# VersionError is raised when a requested version cannot be found.
|
648
|
+
class VersionError < ::RangeError # :nodoc:
|
649
|
+
end
|
650
|
+
|
651
|
+
# VersionConflict is raised when selecting another version
|
652
|
+
# of a library when a previous version has already been selected.
|
653
|
+
class VersionConflict < ::LoadError # :nodoc:
|
315
654
|
end
|
316
655
|
|
317
656
|
end
|