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,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