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.
Files changed (62) hide show
  1. data/HISTORY +28 -4
  2. data/PACKAGE +6 -0
  3. data/PROFILE +22 -0
  4. data/README.rdoc +66 -59
  5. data/bin/roll +7 -1
  6. data/lib/oll.rb +1 -1
  7. data/lib/roll.rb +30 -9
  8. data/lib/roll/command.rb +40 -177
  9. data/lib/roll/commands/env.rb +24 -0
  10. data/lib/roll/commands/help.rb +30 -0
  11. data/lib/roll/commands/in.rb +26 -0
  12. data/lib/roll/commands/index.rb +20 -0
  13. data/lib/roll/commands/list.rb +33 -0
  14. data/lib/roll/commands/out.rb +22 -0
  15. data/lib/roll/commands/path.rb +50 -0
  16. data/lib/roll/commands/sync.rb +29 -0
  17. data/lib/roll/commands/use.rb +25 -0
  18. data/lib/roll/commands/verify.rb +22 -0
  19. data/lib/roll/config.rb +8 -3
  20. data/lib/roll/environment.rb +84 -42
  21. data/lib/roll/kernel.rb +9 -2
  22. data/lib/roll/library.rb +360 -21
  23. data/lib/roll/metadata.rb +282 -51
  24. data/lib/roll/original.rb +3 -3
  25. data/lib/roll/version.rb +6 -7
  26. data/script/setup +14 -18
  27. data/script/setup.old +1344 -0
  28. data/test/{unitcases/version_case.rb → version_case.rb} +1 -1
  29. metadata +30 -47
  30. data/TODO +0 -4
  31. data/lib/roll/errors.rb +0 -13
  32. data/lib/roll/ledger.rb +0 -299
  33. data/lib/roll/locals.rb +0 -96
  34. data/meta/active +0 -1
  35. data/meta/authors +0 -1
  36. data/meta/contact +0 -1
  37. data/meta/created +0 -1
  38. data/meta/description +0 -5
  39. data/meta/homepage +0 -1
  40. data/meta/maintainer +0 -1
  41. data/meta/name +0 -1
  42. data/meta/repository +0 -1
  43. data/meta/ruby +0 -2
  44. data/meta/suite +0 -1
  45. data/meta/summary +0 -1
  46. data/meta/version +0 -1
  47. data/script/test +0 -23
  48. data/test/benchmarks/vsgems.rb +0 -11
  49. data/test/benchmarks/vsgems_bm.rb +0 -17
  50. data/test/demonstrations/01_library.rdoc +0 -33
  51. data/test/demonstrations/04_version.rdoc +0 -56
  52. data/test/fixtures/env.list +0 -1
  53. data/test/fixtures/inspect.rb +0 -12
  54. data/test/fixtures/tryme/1.0/lib/tryme.rb +0 -1
  55. data/test/fixtures/tryme/1.0/meta/homepage +0 -1
  56. data/test/fixtures/tryme/1.0/meta/name +0 -1
  57. data/test/fixtures/tryme/1.0/meta/version +0 -1
  58. data/test/fixtures/tryme/1.1/lib/tryme.rb +0 -1
  59. data/test/fixtures/tryme/1.1/meta/homepage +0 -1
  60. data/test/fixtures/tryme/1.1/meta/name +0 -1
  61. data/test/fixtures/tryme/1.1/meta/version +0 -1
  62. data/test/unit/version_test.rb +0 -71
@@ -1,7 +1,14 @@
1
- require 'roll/original'
2
- require 'roll/ledger'
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__
@@ -1,7 +1,6 @@
1
- #require 'rbconfig'
2
1
  require 'roll/version'
3
2
  require 'roll/metadata'
4
- require 'roll/errors'
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
- @active ||= metadata.active
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
- loadpath.each do |lpath|
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
- loadpath.each do |lpath|
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 #aquire.
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
- loadpath.each do |lpath|
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
- loadpath.each do |lpath|
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 = original_require(file)
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 = original_load(file, wrap)
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 @version
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?metadata.name
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