roll 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
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