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,77 +1,282 @@
1
+ require 'yaml'
2
+
1
3
  module Roll
2
4
 
5
+ #= Library Metadata
3
6
  #--
4
7
  # TODO: Use POM? If available?
8
+ #
9
+ # TODO: Improve loading and parsing of metadata.
10
+ # We want this to be as fast and as lazy as possible.
5
11
  #--
6
12
  class Metadata
7
13
 
8
- #TODO: hide most methods
14
+ # New metadata object.
15
+ def initialize(location, name=nil, options={})
16
+ @location = location
17
+ @name = name
18
+ @version = options[:version]
19
+ @loadpath = options[:loadpath]
20
+ #load_metadata
21
+ end
9
22
 
23
+ # Location of library.
10
24
  attr :location
11
25
 
26
+ # Release date.
27
+ attr_accessor :date
28
+
29
+ # Alias for release date.
30
+ alias_method :released, :date
31
+
32
+ # In code name, e.g. "ActiveRecord"
33
+ attr_accessor :codename
34
+
35
+ # Local load paths.
36
+ def loadpath
37
+ @loadpath || (
38
+ load_metadata
39
+ @loadpath ||= ['lib']
40
+ )
41
+ end
42
+
12
43
  #
13
- def initialize(location)
14
- @location = location
15
- @cache = {}
44
+ def loadpath=(path)
45
+ case path
46
+ when nil
47
+ path = ['lib']
48
+ when String
49
+ path = path.strip.split(/[,;:\ \n\t]/).map{|s| s.strip}
50
+ end
51
+ @loadpath = path
16
52
  end
17
53
 
18
- # Get library name.
54
+ # Name of library.
19
55
  def name
20
- @cache[:name] ||= read('name')
56
+ @name || (
57
+ if @loaded
58
+ nil
59
+ else
60
+ load_metadata
61
+ @name
62
+ end
63
+ )
64
+ end
65
+
66
+ # Set name.
67
+ def name=(string)
68
+ @name = string if string
21
69
  end
22
70
 
23
- # Get library version.
24
- #--
25
- # TODO: handle VERSION file
26
- # TODO: handle YAML
27
- #++
71
+ # Version number.
72
+ #
73
+ # Technically, a library should not appear in a ledger list
74
+ # if it lacks a VERSION file. However, just in case this
75
+ # occurs (say by a hand edited environment) we fallback
76
+ # to a version of '0.0.0'.
28
77
  def version
29
- @cache[:version] ||= Version.new(read(:version))
78
+ @version || (
79
+ load_metadata
80
+ @version ||= Version.new('0.0.0')
81
+ )
30
82
  end
31
83
 
32
- # Get library active state.
33
- def active
34
- return @cache[:active] if @cache.key?(:active)
35
- @cache[:active] = (
36
- case read(:active).to_s.downcase
37
- when 'false', 'no'
38
- false
39
- else
40
- true
84
+ # Set version, converts string into Version number class.
85
+ def version=(string)
86
+ @version = Version.new(string) if string
87
+ end
88
+
89
+ # TODO: Improve. Is this even needed?
90
+ def requires
91
+ @requires ||= (
92
+ req = []
93
+ if file = require_file
94
+ data = YAML.load(File.new(file))
95
+ data.each do |name, list|
96
+ req.concat(list || [])
97
+ end
41
98
  end
99
+ req
42
100
  )
43
101
  end
44
102
 
45
- # Get library release date.
46
- #--
47
- # TODO: default date to what?
48
- #++
49
- def released
50
- @cache[:released] ||= read(:released) || "1900-01-01"
103
+ #
104
+ def require_file
105
+ @require_file ||= (
106
+ pattern = File.join(location, "{REQUIRE,.require}{,.yml,.yaml}")
107
+ Dir.glob(pattern, File::FNM_CASEFOLD).first
108
+ )
51
109
  end
52
110
 
53
- # Get library loadpath.
54
- def loadpath
55
- @cache[:loadpath] ||= (
56
- val = read(:loadpath).to_s.strip.split(/\s*\n/) # TODO: handle YAML
57
- val = ['lib'] if val.empty?
58
- val
111
+ # TODO: Deprecate active, if you don't want it exclude from environment.
112
+ # Is active, i.e. not omitted.
113
+ #def active ; true ; end
114
+ # Is active, i.e. not omitted.
115
+ #def active? ; true ; end
116
+
117
+ private
118
+
119
+ # Package file path.
120
+ def package_file
121
+ @package_file ||= (
122
+ paths = Dir.glob(File.join(location, "{,.}{package}{.yml,.yaml,}"), File::FNM_CASEFOLD)
123
+ paths.select{ |f| File.file?(f) }.first
124
+ )
125
+ end
126
+
127
+ # Version file path.
128
+ def version_file
129
+ @version_file ||= (
130
+ paths = Dir.glob(File.join(location, "{VERSION}{,.txt,.yml,.yaml}"), File::FNM_CASEFOLD)
131
+ paths.select{ |f| File.file?(f) }.first
59
132
  )
60
133
  end
61
134
 
62
135
  #
63
- def requires
64
- @cache[:requires] ||= (
65
- if entry = read(:requires)
66
- entry.strip.split("\n").map do |line|
67
- line.strip.split(/\s+/)
68
- end
136
+ def load_metadata
137
+ @loaded = true
138
+ load_package || load_fallback
139
+ end
140
+
141
+ #
142
+ def load_package
143
+ if package_file
144
+ data = YAML.load(File.new(package_file))
145
+ data = data.inject({}){|h,(k,v)| h[k.to_s] = v; h}
146
+ self.name = data['name']
147
+ self.version = data['vers'] || data['version']
148
+ self.loadpath = data['path'] || data['loadpath']
149
+ self.codename = data['code'] || data['codename']
150
+ true
151
+ else
152
+ false
153
+ end
154
+ end
155
+
156
+ # TODO: Instead of supporting gemspecs as is, create a tool
157
+ # that will add a .package file to each one.
158
+
159
+ #
160
+ #def load_gemspec
161
+ # return false unless File.basename(File.dirname(location)) == 'gems'
162
+ # specfile = File.join(location, '..', '..', 'specifications', File.basename(location) + '.gemspec')
163
+ # if File.exist?(specfile)
164
+ # fakegem = FakeGem.load(specfile)
165
+ # self.name = fakegem.name
166
+ # self.version = fakegem.version
167
+ # self.loadpath = fakegem.require_paths
168
+ # true
169
+ # else
170
+ # false
171
+ # end
172
+ #end
173
+
174
+ # THINK: Is this reliable enough?
175
+ def load_fallback
176
+ load_location
177
+ load_version unless @version
178
+ if not @version
179
+ self.version = '0.0.0'
180
+ end
181
+ @name
182
+ end
183
+
184
+ #
185
+ def load_location
186
+ fname = File.basename(location)
187
+ if /\-\d/ =~ fname
188
+ i = fname.rindex('-')
189
+ name, vers = fname[0...i], fname[i+1..-1]
190
+ self.name = name
191
+ self.version = vers
192
+ else
193
+ self.name = fname
194
+ end
195
+ end
196
+
197
+ # Try to determine name from lib/*.rb file.
198
+ # Ideally this would work, but there are too many projects that do not
199
+ # follow best practices, so currently THIS IS NOT USED.
200
+ def load_loadpath
201
+ #libs = loadpath.map{ |lp| Dir.glob(File.join(lp,'*.rb')) }.flatten
202
+ libs = Dir.glob(File.join(location, 'lib', '*.rb'))
203
+ if !libs.empty?
204
+ self.name = File.basename(libs.first).chomp('.rb')
205
+ true
206
+ else
207
+ false
208
+ end
209
+ end
210
+
211
+ # Load VERSION file, if it exists.
212
+ def load_version
213
+ if version_file
214
+ ext = File.extname(version_file)
215
+ if ext == '.yml' or ext == '.yaml'
216
+ data = YAML.load(File.new(version_file))
217
+ parse_version_hash(data)
69
218
  else
70
- []
219
+ text = File.read(version_file).strip
220
+ if text[0..3] == '---' or text.index('major:')
221
+ data = YAML.load(text)
222
+ parse_version_hash(data)
223
+ else
224
+ parse_version_string(text)
225
+ end
71
226
  end
72
- )
227
+ true if @version
228
+ else
229
+ false
230
+ end
231
+ end
232
+
233
+ # Parse hash-based VERSION file.
234
+ def parse_version_hash(data)
235
+ data = data.inject({}){ |h,(k,v)| h[k.to_sym] = v; h }
236
+ self.name = data[:name] if data[:name]
237
+ self.date = data[:date] if data[:date]
238
+ # jeweler
239
+ if data[:major]
240
+ self.version = data.values_at(:major, :minor, :patch, :build).compact.join('.')
241
+ else
242
+ vers = data[:vers] || data[:version]
243
+ self.version = (Array === vers ? vers.join('.') : vers)
244
+ end
245
+ self.codename = data.values_at(:code, :codename).compact.first
246
+ end
247
+
248
+ # Parse string-based VERSION file.
249
+ def parse_version_string(text)
250
+ text = text.strip
251
+ # name
252
+ if md = /^(\w+)(\-\d|\ )/.match(text)
253
+ self.name = md[1]
254
+ end
255
+ # version
256
+ if md = /(\d+\.)+(\w+\.)?(\d+)/.match(text)
257
+ self.version = md[0]
258
+ end
259
+ # date
260
+ # TODO: convert to date/time
261
+ if md = /\d\d\d\d-\d\d-\d\d/.match(text)
262
+ self.date = md[0]
263
+ end
73
264
  end
74
265
 
266
+ =begin
267
+ ## Get library active state.
268
+ #def active
269
+ # return @cache[:active] if @cache.key?(:active)
270
+ # @cache[:active] = (
271
+ # case read(:active).to_s.downcase
272
+ # when 'false', 'no'
273
+ # false
274
+ # else
275
+ # true
276
+ # end
277
+ # )
278
+ #end
279
+
75
280
  #
76
281
  def method_missing(name, *args)
77
282
  if @cache.key?(name)
@@ -80,11 +285,11 @@ module Roll
80
285
  @cache[name] = read(name)
81
286
  end
82
287
  end
288
+ =end
83
289
 
84
- private
85
-
86
- #
87
- def read(name)
290
+ =begin
291
+ # Retrieve entry from meta directory.
292
+ def meta(name)
88
293
  file = Dir[File.join(location, "{meta,.meta}", name.to_s)].first
89
294
  if file
90
295
  text = File.read(file)
@@ -98,14 +303,40 @@ module Roll
98
303
  nil
99
304
  end
100
305
  end
306
+ =end
101
307
 
102
- #
103
- def require_yaml
104
- @require_yaml ||=(
105
- require 'yaml'
106
- true
107
- )
308
+ # Ecapsulate the fake parsing of a gemspec.
309
+ module FakeGem
310
+ module Gem #:nodoc:
311
+ class Specification #:nodoc:
312
+ attr :fake_options
313
+ def initialize(&block)
314
+ @fake_options = {}
315
+ yield(self)
316
+ end
317
+ def method_missing(sym, *args)
318
+ name = sym.to_s
319
+ case name
320
+ when /=$/
321
+ @fake_options[name.chomp('=')] = args.first
322
+ else
323
+ @fake_options[name]
324
+ end
325
+ end
326
+ end
327
+ class Requirement
328
+ def initialize(*a)
329
+ end
330
+ end
331
+ end
332
+ #
333
+ def self.load(file)
334
+ text = File.read(file)
335
+ fake_spec = eval(text, binding)
336
+ fake_spec
337
+ end
108
338
  end
339
+
109
340
  end
110
341
 
111
342
  end
@@ -2,9 +2,9 @@
2
2
  RUBY_IGNORE_CALLERS = [] unless defined? RUBY_IGNORE_CALLERS
3
3
  RUBY_IGNORE_CALLERS << %r{roll/kernel\.rb$}
4
4
  RUBY_IGNORE_CALLERS << %r{roll/original\.rb$}
5
-
5
+
6
6
  module ::Kernel
7
- alias_method :original_require, :require
8
- alias_method :original_load, :load
7
+ alias_method :roll_original_require, :require
8
+ alias_method :roll_original_load, :load
9
9
  end
10
10
 
@@ -1,11 +1,9 @@
1
1
  module Roll
2
2
 
3
- # = Version
3
+ # = Version Number
4
4
  #
5
- # VersionNumber is a simplified form of a Tuple class
6
- # desgined specifically for dealing with version numbers.
7
- #
8
- class Version #< Tuple
5
+ # Essentially a tuple (immutable array).
6
+ class Version
9
7
 
10
8
  #include Enumerable
11
9
  include Comparable
@@ -48,6 +46,7 @@ module Roll
48
46
 
49
47
  private
50
48
 
49
+ # TODO: deal with string portions of version number
51
50
  def initialize(*args)
52
51
  args = args.join('.').split(/\W+/)
53
52
  @tuple = args.collect { |i| i.to_i }
@@ -72,7 +71,7 @@ module Roll
72
71
  def <=>(other)
73
72
  #other = other.to_t
74
73
  [@tuple.size, other.size].max.times do |i|
75
- c = @tuple[i] <=> other[i]
74
+ c = (@tuple[i] || 0) <=> (other[i] || 0)
76
75
  return c if c != 0
77
76
  end
78
77
  0
@@ -99,7 +98,7 @@ module Roll
99
98
 
100
99
  # Teeny is third number in the version series.
101
100
 
102
- def teeny ; @tuple[2] || 0 ; end
101
+ def patch ; @tuple[2] || 0 ; end
103
102
 
104
103
  # Delegate to the array.
105
104
 
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  #
3
- # Setup.rb, 2010-02-07 08:33:15
3
+ # Setup.rb, 2010-06-01 10:27:20
4
4
  #
5
5
  # This is a stand-alone bundle of the setup.rb application.
6
6
  # You can place it in your projects script/ directory, or
@@ -29,7 +29,8 @@ end
29
29
  module Setup
30
30
  META_EXTENSION_DIR = '.setup'
31
31
  FILETYPES = %w( bin lib ext data etc man doc )
32
- INSTALL_RECORD = 'SetupReceipt' #'.cache/setup/installedfiles'
32
+ INSTALL_RECORD = 'SetupReceipt'
33
+ CONFIG_FILE = 'SetupConfig'
33
34
  end
34
35
  module Setup
35
36
  class Project
@@ -109,7 +110,6 @@ module Setup
109
110
  configuration.compile? && project.compiles?
110
111
  end
111
112
  def all
112
- config
113
113
  if compile?
114
114
  make
115
115
  end
@@ -123,23 +123,18 @@ module Setup
123
123
  end
124
124
  end
125
125
  def config
126
- log_header('Configure')
127
- if configuration.save_config
128
- io.puts "Configuration saved." unless quiet?
129
- else
130
- io.puts "Configuration current." unless quiet?
131
- end
126
+ log_header('Custom Configuration')
127
+ configuration.save_config
128
+ io.puts "Edit #{CONFIG_FILE} to customize configuration." unless quiet?
132
129
  puts configuration if trace? && !quiet?
133
130
  compiler.configure if compile? #compiler.compiles?
134
131
  end
135
132
  def make
136
- abort "must run 'setup config' first" unless configuration.exist?
137
133
  log_header('Compile')
138
134
  compiler.compile
139
135
  end
140
136
  alias_method :setup, :make
141
137
  def install
142
- abort "must run 'setup config' first" unless configuration.exist?
143
138
  log_header('Install')
144
139
  installer.install
145
140
  end
@@ -331,7 +326,6 @@ require 'shellwords'
331
326
  module Setup
332
327
  class Configuration
333
328
  RBCONFIG = ::Config::CONFIG
334
- CONFIG_FILE = 'SetupConfig' # '.cache/setup/config'
335
329
  META_CONFIG_FILE = META_EXTENSION_DIR + '/configuration.rb'
336
330
  def self.options
337
331
  @@options ||= []
@@ -393,9 +387,9 @@ module Setup
393
387
  initialize_metaconfig
394
388
  initialize_defaults
395
389
  initialize_environment
396
- initialize_configfile
390
+ initialize_configfile unless values[:reset]
397
391
  values.each{ |k,v| __send__("#{k}=", v) }
398
- yeild(self) if block_given?
392
+ yield(self) if block_given?
399
393
  end
400
394
  def initialize_metaconfig
401
395
  if File.exist?(META_CONFIG_FILE)
@@ -407,7 +401,7 @@ module Setup
407
401
  self.type = 'site'
408
402
  self.no_ri = true
409
403
  self.no_test = true
410
- self.no_doc = false
404
+ self.no_doc = true
411
405
  self.no_ext = false
412
406
  end
413
407
  def initialize_environment
@@ -418,7 +412,7 @@ module Setup
418
412
  end
419
413
  end
420
414
  def initialize_configfile
421
- if File.exist?(CONFIG_FILE)
415
+ if exist?
422
416
  erb = ERB.new(File.read(CONFIG_FILE))
423
417
  txt = erb.result(binding)
424
418
  dat = YAML.load(txt)
@@ -436,6 +430,7 @@ module Setup
436
430
  end
437
431
  end
438
432
  end
433
+ attr_accessor :reset
439
434
  def base_bindir
440
435
  @base_bindir ||= subprefix('bindir')
441
436
  end
@@ -924,7 +919,7 @@ module Setup
924
919
  return unless config.doc?
925
920
  return unless directory?('doc')
926
921
  return unless project.name
927
- dir = File.join(config.docdir, "ruby-{project.name}")
922
+ dir = File.join(config.docdir, "ruby-#{project.name}")
928
923
  report_transfer('doc', dir)
929
924
  files = files('doc')
930
925
  install_files('doc', files, dir, 0644)
@@ -1287,7 +1282,8 @@ module Setup
1287
1282
  end
1288
1283
  end
1289
1284
  else
1290
- opts = shortcut ? ["-#{shortcut}", "--#{optname} #{type.to_s.upcase}", desc] : ["--#{optname} #{type.to_s.upcase}", desc]
1285
+ opts = shortcut ? ["-#{shortcut}", "--#{optname} #{type.to_s.upcase}", desc] :
1286
+ ["--#{optname} #{type.to_s.upcase}", desc]
1291
1287
  parser.on(*opts) do |val|
1292
1288
  configuration.__send__("#{name}=", val)
1293
1289
  end