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
@@ -0,0 +1,24 @@
1
+ module Roll
2
+
3
+ # Show environment.
4
+ class CommandEnv < Command
5
+
6
+ #
7
+ def setup
8
+ op.banner = "Usage: roll env [NAME]"
9
+ op.separator "Show current environment."
10
+ end
11
+
12
+ #
13
+ def call
14
+ env = Roll.env(*args)
15
+ puts env.name + ':'
16
+ env.lookup.each do |(path, depth)|
17
+ puts "- #{path} #{depth}"
18
+ end
19
+ end
20
+
21
+ end
22
+
23
+ end
24
+
@@ -0,0 +1,30 @@
1
+ module Roll
2
+
3
+ #
4
+ class CommandHelp < Command
5
+
6
+ #
7
+ def setup
8
+ op.banner = "USAGE:\n roll <COMMAND> [--OPT1 --OPT2 ...]\n\n" +
9
+ "Use 'roll <COMMAND> --help' for command details."
10
+ op.separator " "
11
+ op.separator "COMMANDS:"
12
+ op.separator " in [DIR] " + (" " * 23) + "Roll directory into current environment."
13
+ op.separator " out [DIR] " + (" " * 23) + "Remove directory from current environment."
14
+ op.separator " env " + (" " * 23) + "Show current environment."
15
+ op.separator " index " + (" " * 23) + "Show current environment index."
16
+ op.separator " sync " + (" " * 23) + "Synchronize environment indexes."
17
+ op.separator " path " + (" " * 23) + "Output bin PATH list."
18
+ op.separator " verify " + (" " * 23) + "Verify project dependencies in current environment."
19
+ op.separator " "
20
+ op.separator "OPTIONS:"
21
+ end
22
+
23
+ #
24
+ def call
25
+ puts op
26
+ end
27
+
28
+ end
29
+
30
+ end
@@ -0,0 +1,26 @@
1
+ module Roll
2
+
3
+ #
4
+ class CommandIn < Command
5
+
6
+ #
7
+ def setup
8
+ op.banner = "Usage: roll in [PATH]"
9
+ op.separator "Insert path into current environment."
10
+ op.separator "Options:"
11
+ op.on("--depth", "-d INTEGER") do |int|
12
+ opts[:depth] = int
13
+ end
14
+ end
15
+
16
+ #
17
+ def call
18
+ path = File.expand_path(args.first || Dir.pwd)
19
+ depth = opts[:depth]
20
+ path, file = *Roll.in(path, depth)
21
+ puts "#{path}"
22
+ puts " '-> #{file}"
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,20 @@
1
+ module Roll
2
+
3
+ #
4
+ class CommandIndex < Command
5
+
6
+ #
7
+ def setup
8
+ op.banner = "Usage: roll index [NAME]"
9
+ op.separator "Show current environment index."
10
+ end
11
+
12
+ # Show/Change current environment.
13
+ #
14
+ def call
15
+ puts Roll.index(*args)
16
+ end
17
+
18
+ end
19
+
20
+ end
@@ -0,0 +1,33 @@
1
+ module Roll
2
+
3
+ # List available environments.
4
+ class CommandList < Command
5
+
6
+ #
7
+ def setup
8
+ op.banner = "Usage: roll list"
9
+ op.separator "List current environments."
10
+ end
11
+
12
+ #
13
+ def call
14
+ curr = Roll.env.name
15
+ envs = Roll.list.sort #(*args)
16
+ if envs.empty?
17
+ puts "No environments."
18
+ else
19
+ puts
20
+ envs.each do |env|
21
+ if curr == env
22
+ puts "=> #{env}"
23
+ else
24
+ puts " #{env}"
25
+ end
26
+ end
27
+ puts
28
+ end
29
+ end
30
+
31
+ end
32
+
33
+ end
@@ -0,0 +1,22 @@
1
+ module Roll
2
+
3
+ #
4
+ class CommandOut < Command
5
+
6
+ #
7
+ def setup
8
+ op.banner = "Usage: roll out [PATH]"
9
+ op.separator "Remove path from current environment."
10
+ end
11
+
12
+ #
13
+ def call
14
+ path = File.expand_path(args.first || Dir.pwd)
15
+ path, file = *Roll.out(path)
16
+ puts "#{file}"
17
+ puts " '-> #{path} -> [x]"
18
+ end
19
+
20
+ end
21
+
22
+ end
@@ -0,0 +1,50 @@
1
+ module Roll
2
+
3
+ # This script builds a list of all roll-ready bin locations
4
+ # and writes that list as an environment setting shell script.
5
+ # On Linux a call to this to you .bashrc file. Eg.
6
+ #
7
+ # if [ -f ~/.rollrc ]; then
8
+ # . roll
9
+ # fi
10
+ #
11
+ # Currently this only supports bash.
12
+ #
13
+ # TODO: It would be better to "install" executables
14
+ # to an appropriate bin dir, using links (soft if possible).
15
+ # There could go in ~/.bin or .config/roll/<ledger>.bin/
16
+ #
17
+ class CommandPath < Command
18
+
19
+ #
20
+ def setup
21
+ op.banner = "Usage: roll path"
22
+ op.separator "Generate executable PATH list."
23
+ end
24
+
25
+ #
26
+ def call
27
+ case RUBY_PLATFORM
28
+ when /mswin/, /wince/
29
+ div = ';'
30
+ else
31
+ div = ':'
32
+ end
33
+ env_path = ENV['PATH'].split(/[#{div}]/)
34
+ # Go thru each roll lib and make sure bin path is in path.
35
+ binpaths = []
36
+ Library.list.each do |name|
37
+ lib = Library[name]
38
+ if lib.bindir?
39
+ binpaths << lib.bindir
40
+ end
41
+ end
42
+ #pathenv = (["$PATH"] + binpaths).join(div)
43
+ pathenv = binpaths.join(div)
44
+ #puts %{export PATH="#{pathenv}"}
45
+ puts pathenv
46
+ end
47
+
48
+ end
49
+
50
+ end
@@ -0,0 +1,29 @@
1
+ module Roll
2
+
3
+ #
4
+ class CommandSync < Command
5
+
6
+ #
7
+ def setup
8
+ op.banner = "Usage: roll sync [NAME]"
9
+ op.separator "Synchronize ledger(s) to their respective environment(s)."
10
+ end
11
+
12
+ # Synchronize ledgers.
13
+ #
14
+ def call
15
+ name = args.first
16
+ list = name ? [name] : Environment.list
17
+ list.each do |name|
18
+ result = Roll.sync(name)
19
+ if result
20
+ puts " saved #{name}"
21
+ else
22
+ puts " current #{name}"
23
+ end
24
+ end
25
+ end
26
+
27
+ end
28
+
29
+ end
@@ -0,0 +1,25 @@
1
+ module Roll
2
+
3
+ # Show/Change current environment.
4
+ class CommandUse < Command
5
+
6
+ #
7
+ def setup
8
+ op.banner = "Usage: roll use <NAME>"
9
+ op.separator "Set current environment. Set name to 'system' to use RUBYENV."
10
+ #op.on("--clear", "-c") do
11
+ # args.unshift 'system'
12
+ #end
13
+ end
14
+
15
+ #
16
+ def call
17
+ name = args.first
18
+ file = Roll.use(name)
19
+ puts "Roll environment is now '#{File.read(file).strip}'."
20
+ end
21
+
22
+ end
23
+
24
+ end
25
+
@@ -0,0 +1,22 @@
1
+ module Roll
2
+
3
+ #
4
+ class CommandVerify < Command
5
+
6
+ #
7
+ def setup
8
+ op.banner = "Usage: roll verify"
9
+ op.separator "Verify dependencies in current environment."
10
+ end
11
+
12
+ #
13
+ def call
14
+ list = Roll.verify
15
+ list.each do |(name, constraint)|
16
+ puts "#{name} #{constraint}"
17
+ end
18
+ end
19
+
20
+ end
21
+
22
+ end
@@ -2,6 +2,9 @@ require 'rbconfig'
2
2
 
3
3
  module ::Config
4
4
 
5
+ # TODO: use "XDG-lite" rather than XDG.
6
+
7
+ #
5
8
  HOME = File.expand_path('~') # ENV['HOME']
6
9
 
7
10
  # Location of user's personal config directory.
@@ -11,11 +14,12 @@ module ::Config
11
14
  CONFIG_DIRS = (
12
15
  dirs = ENV['XDG_CONFIG_DIRS'].to_s.split(/[:;]/)
13
16
  if dirs.empty?
14
- dirs = File.join(Config::CONFIG['sysconfdir'], 'xdg')
17
+ dirs = [File.join(Config::CONFIG['sysconfdir'], 'xdg')]
15
18
  end
16
19
  dirs.collect{ |d| File.expand_path(d) }
17
20
  )
18
21
 
22
+ #
19
23
  WIN_PATTERNS = [
20
24
  /bccwin/i,
21
25
  /cygwin/i,
@@ -41,16 +45,18 @@ module ::Config
41
45
  # versioned data directories.
42
46
  #++
43
47
 
48
+ #
44
49
  def self.datadir(name, versionless=false)
45
50
  if lib = Roll::Library.instance(name)
46
51
  lib.datadir(versionless)
52
+ elsif defined?(super)
53
+ super(name)
47
54
  else
48
55
  File.join(CONFIG['datadir'], name)
49
56
  end
50
57
  end
51
58
 
52
59
  # Return the path to the configuration directory.
53
-
54
60
  def self.confdir(name)
55
61
  if lib = Roll::Library.instance(name)
56
62
  lib.confdir
@@ -60,7 +66,6 @@ module ::Config
60
66
  end
61
67
 
62
68
  # Lookup configuration file.
63
-
64
69
  def self.find_config(*glob)
65
70
  flag = 0
66
71
  flag = (flag | glob.pop) while Fixnum === glob.last
@@ -1,7 +1,8 @@
1
+ #require File.dirname(__FILE__) + '/config.rb'
2
+ require 'roll/config'
3
+
1
4
  require 'yaml'
2
5
  require 'fileutils'
3
- #require 'roll/xdg'
4
- require 'roll/config'
5
6
 
6
7
  module Roll
7
8
 
@@ -16,20 +17,48 @@ module Roll
16
17
  #--
17
18
  # Perhaps combine all enrtries instead?
18
19
  #++
19
- DIRS = ::Config.find_config('roll')
20
+ DIRS = ::Config.find_config('roll', 'environments')
21
+
22
+ #
23
+ HOME_ENV_DIR = File.join(::Config::CONFIG_HOME, 'roll', 'environments')
24
+
25
+ # File that stores the name of the current environment.
26
+ CURRENT_FILE = File.join(::Config::CONFIG_HOME, 'roll', 'current')
20
27
 
21
28
  # Current environment name.
22
29
  def self.current
23
- ENV['RUBYENV'] || DEFAULT
30
+ @current ||= (
31
+ if File.exist?(CURRENT_FILE)
32
+ env = File.read(CURRENT_FILE).strip
33
+ else
34
+ env = ENV['RUBYENV'] || DEFAULT
35
+ end
36
+ #warn "#{env} is not a valid environment" unless list.include?(env)
37
+ env
38
+ )
24
39
  end
25
40
 
26
41
  # List of available environments.
27
42
  def self.list
28
- Dir[File.join(DIR, '*')].map do |file|
43
+ Dir[File.join('{'+DIRS.join(',')+'}', '*')].map do |file|
29
44
  File.basename(file)
30
45
  end
31
46
  end
32
47
 
48
+ # Change environment to given +name+.
49
+ #
50
+ # TODO: should only last a long as the shell session,
51
+ # not change it perminently.
52
+ #
53
+ def self.save(name)
54
+ if name == 'system'
55
+ FileUtils.rm(CURRENT_FILE)
56
+ else
57
+ File.open(CURRENT_FILE,'w'){|f| f << name.to_s}
58
+ end
59
+ CURRENT_FILE
60
+ end
61
+
33
62
  # Environment name.
34
63
  attr :name
35
64
 
@@ -59,7 +88,9 @@ module Roll
59
88
  end
60
89
 
61
90
  #
62
- def each(&block) ; index.each(&block) ; end
91
+ def each(&block)
92
+ index.each(&block)
93
+ end
63
94
 
64
95
  #
65
96
  def size ; index.size ; end
@@ -73,7 +104,6 @@ module Roll
73
104
  str
74
105
  end
75
106
 
76
-
77
107
  # Index tracks the name and location of each library
78
108
  # in an environment.
79
109
  #--
@@ -96,7 +126,7 @@ module Roll
96
126
 
97
127
  # Environment file (full-path).
98
128
  def file
99
- @file ||= ::Config.find_config('roll', name, 'index').first
129
+ @file ||= ::Config.find_config('roll', 'environments', name, 'index').first
100
130
  end
101
131
 
102
132
  # Load the environment file.
@@ -133,14 +163,14 @@ module Roll
133
163
 
134
164
  #
135
165
  def to_s
136
- out = ""
166
+ out = []
137
167
  max = @table.map{ |name, paths| name.size }.max
138
168
  @table.map do |name, paths|
139
169
  paths.each do |path|
140
- out << "%-#{max}s %s\n" % [name, path]
170
+ out << "%-#{max}s %s" % [name, path]
141
171
  end
142
172
  end
143
- out
173
+ out.sort.join("\n")
144
174
  end
145
175
 
146
176
  # Save environment file.
@@ -152,7 +182,7 @@ module Roll
152
182
  # out << "%-#{max}s %s\n" % [name, path]
153
183
  # end
154
184
  #end
155
- file = File.join(::Config::CONFIG_HOME, 'roll', name, 'index')
185
+ file = File.join(HOME_ENV_DIR, name, 'index')
156
186
  if File.exist?(file)
157
187
  data = File.read(file)
158
188
  if out != data
@@ -173,23 +203,22 @@ module Roll
173
203
  @file = file
174
204
  end
175
205
 
176
- =begin
177
- # Get library version.
178
- # TODO: handle VERSION file
179
- def load_version(path)
180
- file = Dir[File.join(path, '{,.}meta', 'version')].first
181
- if file
182
- File.read(file).strip # TODO: handle YAML ?
183
- end
184
- end
185
- =end
186
-
206
+ # Get library version.
207
+ # TODO: handle VERSION file
208
+ #def load_version(path)
209
+ # file = Dir[File.join(path, '{,.}meta', 'version')].first
210
+ # if file
211
+ # File.read(file).strip # TODO: handle YAML ?
212
+ # end
213
+ #end
187
214
  end
188
215
 
189
216
  # The Lookup class provides a table of paths which
190
217
  # make it easy to quickly populate and refresh the
191
218
  # environment index.
192
-
219
+ #
220
+ # TODO: Provide a way to specifically exclude a location.
221
+ # Probaby recognize a path with a '-' prefix.
193
222
  class Lookup
194
223
  include Enumerable
195
224
 
@@ -209,7 +238,7 @@ module Roll
209
238
 
210
239
  #
211
240
  def file
212
- @file ||= ::Config.find_config('roll', name, 'lookup').first
241
+ @file ||= ::Config.find_config('roll', 'environments', name, 'lookup').first
213
242
  end
214
243
 
215
244
  #
@@ -256,10 +285,10 @@ module Roll
256
285
 
257
286
  #
258
287
  def save
259
- file = File.join(::Config::CONFIG_HOME, 'roll', name, 'lookup')
288
+ file = File.join(HOME_ENV_DIR, name, 'lookup')
260
289
  out = @table.map do |(path, depth)|
261
290
  "#{path} #{depth}"
262
- end
291
+ end.sort
263
292
  dir = File.dirname(file)
264
293
  FileUtils.mkdir_p(dir) unless File.exist?(dir)
265
294
  File.open(file, 'w') do |f|
@@ -270,18 +299,21 @@ module Roll
270
299
 
271
300
  # Generate index from lookup list.
272
301
  def index
273
- set = Hash.new{ |h,k| h[k] = [] }
302
+ set = Hash.new{|h,k| h[k]=[]}
274
303
  locate.each do |path|
275
- name = load_name(path)
304
+ name = libname(path)
305
+ next if name == 'roll' # NEVER INCLUDE ROLL ITSELF!!!
276
306
  #vers = load_version(path)
277
307
  if name #&& vers
278
308
  set[name] << path
309
+ else
310
+ warn "omitting: #{path}"
279
311
  end
280
312
  end
281
313
  set
282
314
  end
283
315
 
284
- #
316
+ # Locate projects.
285
317
  def locate
286
318
  locs = []
287
319
  each do |dir, depth|
@@ -290,25 +322,35 @@ module Roll
290
322
  locs.flatten
291
323
  end
292
324
 
293
- # Search a given directory for projects upto a given depth.
294
- # Projects directories are determined by containing a
295
- # 'meta' or '.meta' directory.
325
+ # Search a given directory for projects upto a given depth. Projects
326
+ # directories are determined by containing a lib/*.rb file.
296
327
  def find_projects(dir, depth=3)
297
328
  depth = Integer(depth || 3)
298
329
  depth = (0...depth).map{ |i| (["*"] * i).join('/') }.join(',')
299
- glob = File.join(dir, "{#{depth}}", "{.meta,meta}")
300
- meta_locations = Dir[glob]
301
- meta_locations.map{ |d| d.chomp('/meta').chomp('/.meta') }
330
+ find = File.join(dir, "{#{depth}}", "lib/*.rb")
331
+ locals = Dir.glob(find)
332
+ locals.map{|d| File.dirname(File.dirname(d)) }.uniq
302
333
  end
303
334
 
304
- # Get library name.
305
- def load_name(path)
306
- file = Dir[File.join(path, '{,.}meta', 'name')].first
307
- if file
308
- File.read(file).strip # TODO: handle YAML
309
- end
335
+ #
336
+ def metadata(path)
337
+ @metadata ||= {}
338
+ @metadata[path] ||= Metadata.new(path)
310
339
  end
311
340
 
341
+ #
342
+ def libname(path)
343
+ metadata(path).name
344
+ end
345
+
346
+ ## Get library name.
347
+ #def load_name(path)
348
+ # file = Dir[File.join(path, '{,.}meta', 'name')].first
349
+ # if file
350
+ # File.read(file).strip # TODO: handle YAML
351
+ # end
352
+ #end
353
+
312
354
  end#class Lookup
313
355
 
314
356
  end#class Environment