bahuvrihi-tap 0.11.2 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. data/bin/rap +2 -3
  2. data/bin/tap +1 -1
  3. data/cmd/console.rb +2 -2
  4. data/cmd/manifest.rb +2 -2
  5. data/cmd/run.rb +7 -9
  6. data/cmd/server.rb +5 -5
  7. data/doc/Class Reference +17 -20
  8. data/doc/Tutorial +5 -7
  9. data/lib/tap.rb +2 -0
  10. data/lib/tap/app.rb +21 -31
  11. data/lib/tap/constants.rb +2 -2
  12. data/lib/tap/declarations.rb +85 -97
  13. data/lib/tap/declarations/declaration_task.rb +58 -0
  14. data/lib/tap/declarations/description.rb +24 -0
  15. data/lib/tap/env.rb +20 -16
  16. data/lib/tap/exe.rb +2 -2
  17. data/lib/tap/file_task.rb +224 -410
  18. data/lib/tap/generator/arguments.rb +9 -0
  19. data/lib/tap/generator/base.rb +105 -28
  20. data/lib/tap/generator/destroy.rb +29 -12
  21. data/lib/tap/generator/generate.rb +55 -39
  22. data/lib/tap/generator/generators/command/templates/command.erb +3 -3
  23. data/lib/tap/generator/generators/config/config_generator.rb +34 -3
  24. data/lib/tap/generator/generators/root/root_generator.rb +6 -9
  25. data/lib/tap/generator/generators/root/templates/Rakefile +4 -4
  26. data/lib/tap/generator/generators/task/templates/test.erb +1 -1
  27. data/lib/tap/root.rb +211 -156
  28. data/lib/tap/support/aggregator.rb +6 -9
  29. data/lib/tap/support/audit.rb +278 -357
  30. data/lib/tap/support/constant_manifest.rb +24 -21
  31. data/lib/tap/support/dependency.rb +1 -1
  32. data/lib/tap/support/executable.rb +26 -48
  33. data/lib/tap/support/join.rb +44 -19
  34. data/lib/tap/support/joins/sync_merge.rb +3 -5
  35. data/lib/tap/support/parser.rb +1 -1
  36. data/lib/tap/task.rb +195 -150
  37. data/lib/tap/tasks/dump.rb +2 -2
  38. data/lib/tap/test/extensions.rb +11 -13
  39. data/lib/tap/test/file_test.rb +71 -129
  40. data/lib/tap/test/file_test_class.rb +4 -1
  41. data/lib/tap/test/tap_test.rb +26 -154
  42. metadata +15 -22
  43. data/lib/tap/patches/optparse/summarize.rb +0 -62
  44. data/lib/tap/support/assignments.rb +0 -173
  45. data/lib/tap/support/class_configuration.rb +0 -182
  46. data/lib/tap/support/configurable.rb +0 -113
  47. data/lib/tap/support/configurable_class.rb +0 -271
  48. data/lib/tap/support/configuration.rb +0 -170
  49. data/lib/tap/support/instance_configuration.rb +0 -173
  50. data/lib/tap/support/lazydoc.rb +0 -386
  51. data/lib/tap/support/lazydoc/attributes.rb +0 -48
  52. data/lib/tap/support/lazydoc/comment.rb +0 -503
  53. data/lib/tap/support/lazydoc/config.rb +0 -17
  54. data/lib/tap/support/lazydoc/definition.rb +0 -36
  55. data/lib/tap/support/lazydoc/document.rb +0 -152
  56. data/lib/tap/support/lazydoc/method.rb +0 -24
  57. data/lib/tap/support/tdoc.rb +0 -409
  58. data/lib/tap/support/tdoc/tdoc_html_generator.rb +0 -38
  59. data/lib/tap/support/tdoc/tdoc_html_template.rb +0 -42
  60. data/lib/tap/support/validation.rb +0 -479
@@ -1,6 +1,7 @@
1
1
  require 'tap/root'
2
2
 
3
3
  module Tap::Generator::Generators
4
+ autoload(:ConfigGenerator, 'tap/generator/generators/config/config_generator')
4
5
 
5
6
  # :startdoc: Tap::Generator::Generators::RootGenerator::generator a basic tap directory structure
6
7
  #
@@ -46,16 +47,12 @@ module Tap::Generator::Generators
46
47
  m.template r[target], source, :project_name => project_name
47
48
  end
48
49
 
49
- m.file(r['tap.yml']) do |file|
50
- Tap::App.configurations.inspect(:doc, file) do |templater|
51
- next unless templater.receiver == Tap::Root
52
-
53
- templater.configurations.each do |(key, config)|
54
- config.default = nil if key.to_s == 'root'
55
- end
56
- end
57
- Tap::Env.configurations.inspect(:doc, file)
50
+ ConfigGenerator.new(:doc => true).dump(m, r['tap'], Tap::App.configurations) do |configs|
51
+ configs.each do |(key, config)|
52
+ config.default = nil if key.to_s == 'root'
53
+ end
58
54
  end if config_file
59
55
  end
56
+
60
57
  end
61
58
  end
@@ -62,12 +62,12 @@ Rake::RDocTask.new(:rdoc) do |rdoc|
62
62
  rdoc.rdoc_files.include( spec.extra_rdoc_files )
63
63
  rdoc.rdoc_files.include( spec.files.select {|file| file =~ /^lib.*\.rb$/} )
64
64
 
65
- # Using Tdoc to template your Rdoc will result in configurations being
65
+ # Using CDoc to template your RDoc will result in configurations being
66
66
  # listed with documentation in a subsection following attributes. Not
67
67
  # necessary, but nice.
68
- require 'tap/support/tdoc'
69
- rdoc.template = 'tap/support/tdoc/tdoc_html_template'
70
- rdoc.options << '--fmt' << 'tdoc'
68
+ require 'cdoc'
69
+ rdoc.template = 'cdoc/cdoc_html_template'
70
+ rdoc.options << '--fmt' << 'cdoc'
71
71
  end
72
72
 
73
73
  #
@@ -14,6 +14,6 @@ class <%= const.name %>Test < Test::Unit::TestCase
14
14
  # a more complex test
15
15
  task.execute("moon")
16
16
  assert_equal ["goodnight moon"], app.results(task)
17
- assert_audit_equal ExpAudit[[nil, "moon"], [task, "goodnight moon"]], app._results(task)[0]
17
+ assert_audit_equal [[nil, "moon"], [task, "goodnight moon"]], app._results(task)[0]
18
18
  end
19
19
  end
@@ -1,59 +1,62 @@
1
+ require 'rubygems'
2
+ require 'configurable'
1
3
  require 'tap/support/versions'
2
- require 'tap/support/configurable'
3
4
  autoload(:FileUtils, 'fileutils')
4
5
 
5
6
  module Tap
6
7
 
7
- # Root allows you to define a root directory and alias subdirectories, so that
8
- # you can conceptualize what filepaths you need without predefining the full
9
- # filepaths. Root also simplifies operations on filepaths.
8
+ # Root allows you to define a root directory and alias relative paths, so
9
+ # that you can conceptualize what filepaths you need without predefining the
10
+ # full filepaths. Root also simplifies operations on filepaths.
10
11
  #
11
- # # define a root directory with aliased subdirectories
12
- # r = Root.new '/root_dir', :input => 'in', :output => 'out'
12
+ # # define a root directory with aliased relative paths
13
+ # r = Root.new '/root_dir', :input => 'in', :output => 'out'
13
14
  #
14
- # # work with directories
15
- # r[:input] # => '/root_dir/in'
16
- # r[:output] # => '/root_dir/out'
17
- # r['implicit'] # => '/root_dir/implicit'
15
+ # # work with aliases
16
+ # r[:input] # => '/root_dir/in'
17
+ # r[:output] # => '/root_dir/out'
18
+ # r['implicit'] # => '/root_dir/implicit'
18
19
  #
19
- # # expanded paths are returned unchanged
20
- # r[File.expand_path('expanded')] # => File.expand_path('expanded')
20
+ # # expanded paths are returned unchanged
21
+ # r[File.expand_path('expanded')] # => File.expand_path('expanded')
21
22
  #
22
- # # work with filepaths
23
- # fp = r.filepath(:input, 'path/to/file.txt') # => '/root_dir/in/path/to/file.txt'
24
- # r.relative_filepath(:input, fp) # => 'path/to/file.txt'
25
- # r.translate(fp, :input, :output) # => '/root_dir/out/path/to/file.txt'
23
+ # # work with filepaths
24
+ # fp = r.filepath(:input, 'path/to/file.txt') # => '/root_dir/in/path/to/file.txt'
25
+ # r.relative_filepath(:input, fp) # => 'path/to/file.txt'
26
+ # r.translate(fp, :input, :output) # => '/root_dir/out/path/to/file.txt'
26
27
  #
27
- # # version filepaths
28
- # r.version('path/to/config.yml', 1.0) # => 'path/to/config-1.0.yml'
29
- # r.increment('path/to/config-1.0.yml', 0.1) # => 'path/to/config-1.1.yml'
30
- # r.deversion('path/to/config-1.1.yml') # => ['path/to/config.yml', "1.1"]
28
+ # # version filepaths
29
+ # r.version('path/to/config.yml', 1.0) # => 'path/to/config-1.0.yml'
30
+ # r.increment('path/to/config-1.0.yml', 0.1) # => 'path/to/config-1.1.yml'
31
+ # r.deversion('path/to/config-1.1.yml') # => ['path/to/config.yml', "1.1"]
31
32
  #
32
- # # absolute paths can also be aliased
33
- # r[:abs, true] = "/absolute/path"
34
- # r.filepath(:abs, "to", "file.txt") # => '/absolute/path/to/file.txt'
33
+ # # absolute paths can also be aliased
34
+ # r[:abs, true] = "/absolute/path"
35
+ # r.filepath(:abs, "to", "file.txt") # => '/absolute/path/to/file.txt'
35
36
  #
36
- # By default, Roots are initialized to the present working directory (Dir.pwd).
37
- # As in the 'implicit' example, Root infers a path relative to the root directory
38
- # whenever it needs to resolve an alias that is not explicitly set. The only
39
- # exceptions to this are fully expanded paths. These are returned unchanged.
37
+ # By default, Roots are initialized to the present working directory
38
+ # (Dir.pwd). As in the 'implicit' example, Root infers a path relative to
39
+ # the root directory whenever it needs to resolve an alias that is not
40
+ # explicitly set. The only exceptions to this are fully expanded paths.
41
+ # These are returned unchanged.
40
42
  #
43
+ #--
41
44
  # === Implementation Notes
42
45
  #
43
- # Internally Root stores expanded paths all aliased paths in the 'paths' hash.
44
- # Expanding paths ensures they remain constant even when the present working
46
+ # Internally Root expands and stores all aliased paths in the 'paths' hash.
47
+ # Expanding paths ensures they remain constant even when the present working
45
48
  # directory (Dir.pwd) changes.
46
49
  #
47
- # Root keeps a separate 'directories' hash mapping aliases to their subdirectory paths.
48
- # This hash allow reassignment if and when the root directory changes. By contrast,
49
- # there is no separate data structure storing the absolute paths. An absolute path
50
- # thus has an alias in 'paths' but not 'directories', whereas subdirectory paths
51
- # have aliases in both.
50
+ # Root keeps a separate 'relative_paths' hash mapping aliases to their
51
+ # relative paths. This hash allow reassignment if and when the root directory
52
+ # changes. By contrast, there is no separate data structure storing the
53
+ # absolute paths. An absolute path thus has an alias in 'paths' but not
54
+ # 'relative_paths', whereas relative paths have aliases in both.
52
55
  #
53
56
  # These features may be important to note when subclassing Root:
54
57
  # - root and all filepaths in 'paths' are expanded
55
- # - subdirectory paths are stored in 'directories'
56
- # - absolute paths are present in 'paths' but not in 'directories'
58
+ # - relative paths are stored in 'relative_paths'
59
+ # - absolute paths are present in 'paths' but not in 'relative_paths'
57
60
  #
58
61
  class Root
59
62
  # Regexp to match a windows-style root filepath.
@@ -77,12 +80,12 @@ module Tap
77
80
  # use dir.length + 1 to remove a leading '/'. If dir.length + 1 >= expanded.length
78
81
  # as in: relative_filepath('/path', '/path') then the first arg returns nil, and an
79
82
  # empty string is returned
80
- expanded_path[( expanded_dir.chomp("/").length + 1)..-1] || ""
83
+ expanded_path[(expanded_dir.chomp("/").length + 1)..-1] || ""
81
84
  end
82
85
 
83
- # Generates a target filepath translated from the source_dir to
84
- # the target_dir. Raises an error if the filepath is not relative
85
- # to the source_dir.
86
+ # Generates a target filepath translated from the source_dir to the
87
+ # target_dir. Raises an error if the filepath is not relative to the
88
+ # source_dir.
86
89
  #
87
90
  # Root.translate("/path/to/file.txt", "/path", "/another/path") # => '/another/path/to/file.txt'
88
91
  #
@@ -92,6 +95,16 @@ module Tap
92
95
  end
93
96
  File.join(target_dir, relative_path)
94
97
  end
98
+
99
+ # Returns the path, exchanging the extension with extname. Extname may
100
+ # optionally omit the leading period.
101
+ #
102
+ # Root.exchange('path/to/file.txt', '.html') # => 'path/to/file.html'
103
+ # Root.exchange('path/to/file.txt', 'rb') # => 'path/to/file.rb'
104
+ #
105
+ def exchange(path, extname)
106
+ "#{path.chomp(File.extname(path))}#{extname[0] == ?. ? '' : '.'}#{extname}"
107
+ end
95
108
 
96
109
  # Lists all unique paths matching the input glob patterns.
97
110
  def glob(*patterns)
@@ -100,8 +113,8 @@ module Tap
100
113
  end.flatten.uniq
101
114
  end
102
115
 
103
- # Lists all unique versions of path matching the glob version patterns.
104
- # If no patterns are specified, then all versions of path will be returned.
116
+ # Lists all unique versions of path matching the glob version patterns. If
117
+ # no patterns are specified, then all versions of path will be returned.
105
118
  def vglob(path, *vpatterns)
106
119
  vpatterns << "*" if vpatterns.empty?
107
120
  vpatterns.collect do |vpattern|
@@ -113,8 +126,8 @@ module Tap
113
126
  end.flatten.uniq
114
127
  end
115
128
 
116
- # Path suffix glob. Globs along the base paths for
117
- # paths that match the specified suffix pattern.
129
+ # Path suffix glob. Globs along the base paths for paths that match the
130
+ # specified suffix pattern.
118
131
  def sglob(suffix_pattern, *base_paths)
119
132
  base_paths.collect do |base|
120
133
  base = File.expand_path(base)
@@ -122,9 +135,9 @@ module Tap
122
135
  end.flatten.uniq
123
136
  end
124
137
 
125
- # Like Dir.chdir but makes the directory, if necessary, when
126
- # mkdir is specified. chdir raises an error for non-existant
127
- # directories, as well as non-directory inputs.
138
+ # Like Dir.chdir but makes the directory, if necessary, when mkdir is
139
+ # specified. chdir raises an error for non-existant directories, as well
140
+ # as non-directory inputs.
128
141
  def chdir(dir, mkdir=false, &block)
129
142
  dir = File.expand_path(dir)
130
143
 
@@ -139,8 +152,20 @@ module Tap
139
152
  Dir.chdir(dir, &block)
140
153
  end
141
154
 
142
- # The path root type indicating windows, *nix, or some unknown
143
- # style of filepaths (:win, :nix, :unknown).
155
+ # Prepares the input path by making the parent directory for path. If a
156
+ # block is given, a file is created at path and passed to it; in this
157
+ # way files with non-existant parent directories are readily made.
158
+ #
159
+ # Returns path.
160
+ def prepare(path, &block)
161
+ dirname = File.dirname(path)
162
+ FileUtils.mkdir_p(dirname) unless File.exists?(dirname)
163
+ File.open(path, "w", &block) if block_given?
164
+ path
165
+ end
166
+
167
+ # The path root type indicating windows, *nix, or some unknown style of
168
+ # filepaths (:win, :nix, :unknown).
144
169
  def path_root_type
145
170
  @path_root_type ||= case
146
171
  when RUBY_PLATFORM =~ /mswin/ && File.expand_path(".") =~ WIN_ROOT_PATTERN then :win
@@ -149,25 +174,24 @@ module Tap
149
174
  end
150
175
  end
151
176
 
152
- # Returns true if the input path appears to be an expanded path,
153
- # based on Root.path_root_type.
177
+ # Returns true if the input path appears to be an expanded path, based on
178
+ # Root.path_root_type.
154
179
  #
155
- # If root_type == :win returns true if the path matches
156
- # WIN_ROOT_PATTERN.
180
+ # If root_type == :win returns true if the path matches WIN_ROOT_PATTERN.
157
181
  #
158
- # Root.expanded_path?('C:/path') # => true
159
- # Root.expanded_path?('c:/path') # => true
160
- # Root.expanded_path?('D:/path') # => true
161
- # Root.expanded_path?('path') # => false
182
+ # Root.expanded?('C:/path') # => true
183
+ # Root.expanded?('c:/path') # => true
184
+ # Root.expanded?('D:/path') # => true
185
+ # Root.expanded?('path') # => false
162
186
  #
163
- # If root_type == :nix, then expanded? returns true if
164
- # the path begins with '/'.
187
+ # If root_type == :nix, then expanded? returns true if the path begins
188
+ # with '/'.
165
189
  #
166
- # Root.expanded_path?('/path') # => true
167
- # Root.expanded_path?('path') # => false
190
+ # Root.expanded?('/path') # => true
191
+ # Root.expanded?('path') # => false
168
192
  #
169
- # Otherwise expanded_path? always returns nil.
170
- def expanded_path?(path, root_type=path_root_type)
193
+ # Otherwise expanded? always returns nil.
194
+ def expanded?(path, root_type=path_root_type)
171
195
  case root_type
172
196
  when :win
173
197
  path =~ WIN_ROOT_PATTERN ? true : false
@@ -178,6 +202,17 @@ module Tap
178
202
  end
179
203
  end
180
204
 
205
+ # Trivial indicates when a path does not have content to load. Returns
206
+ # true if the file at path is empty, non-existant, a directory, or nil.
207
+ def trivial?(path)
208
+ path == nil || !File.file?(path) || File.size(path) == 0
209
+ end
210
+
211
+ # Empty returns true when dir is an existing directory that has no files.
212
+ def empty?(dir)
213
+ File.directory?(dir) && (Dir.entries(dir) - ['.', '..']).empty?
214
+ end
215
+
181
216
  # Minimizes a set of paths to the set of shortest basepaths that unqiuely
182
217
  # identify the paths. The path extension and versions are removed from
183
218
  # the basepath if possible. For example:
@@ -267,8 +302,9 @@ module Tap
267
302
  end
268
303
  end
269
304
 
270
- # Returns true if the mini_path matches path. Matching logic
271
- # reverses that of minimize:
305
+ # Returns true if the mini_path matches path. Matching logic reverses
306
+ # that of minimize:
307
+ #
272
308
  # * a match occurs when path ends with mini_path
273
309
  # * if mini_path doesn't specify an extension, then mini_path
274
310
  # must only match path up to the path extension
@@ -324,11 +360,12 @@ module Tap
324
360
  # windows '\' Root.split('C:\path\to\file') # => ["C:", "path", "to", "file"]
325
361
  # *nix '/' Root.split('/path/to/file') # => ["", "path", "to", "file"]
326
362
  #
327
- # The path is always expanded relative to the expand_dir; so '.' and '..' are
328
- # resolved. However, unless expand_path == true, only the segments relative
329
- # to the expand_dir are returned.
363
+ # The path is always expanded relative to the expand_dir; so '.' and
364
+ # '..' are resolved. However, unless expand_path == true, only the
365
+ # segments relative to the expand_dir are returned.
330
366
  #
331
- # On windows (note that expanding paths allows the use of slashes or backslashes):
367
+ # On windows (note that expanding paths allows the use of slashes or
368
+ # backslashes):
332
369
  #
333
370
  # Dir.pwd # => 'C:/'
334
371
  # Root.split('path\to\..\.\to\file') # => ["C:", "path", "to", "file"]
@@ -365,6 +402,7 @@ module Tap
365
402
  #
366
403
  # "./path"
367
404
  # "//path"
405
+ #
368
406
  def min_join(dir, path) # :nodoc:
369
407
  case dir
370
408
  when "." then path
@@ -407,89 +445,97 @@ module Tap
407
445
  end
408
446
 
409
447
  end
410
-
448
+
449
+ include Configurable
411
450
  include Support::Versions
412
- include Support::Configurable
413
-
451
+
414
452
  # The root directory.
415
453
  config_attr(:root, '.', :writer => false)
416
454
 
417
- # A hash of (alias, relative path) pairs for aliased subdirectories.
418
- config_attr(:directories, {}, :writer => false)
455
+ # A hash of (alias, relative path) pairs for aliased paths relative
456
+ # to root.
457
+ config_attr(:relative_paths, {}, :writer => false)
419
458
 
420
459
  # A hash of (alias, relative path) pairs for aliased absolute paths.
421
460
  config_attr(:absolute_paths, {}, :reader => false, :writer => false)
422
461
 
423
- # A hash of (alias, expanded path) pairs for aliased subdirectories and absolute paths.
462
+ # A hash of (alias, expanded path) pairs for expanded relative and
463
+ # absolute paths.
424
464
  attr_reader :paths
425
465
 
426
466
  # The filesystem root, inferred from self.root
427
467
  # (ex '/' on *nix or something like 'C:/' on Windows).
428
468
  attr_reader :path_root
429
469
 
430
- # Creates a new Root with the given root directory, aliased directories
470
+ # Creates a new Root with the given root directory, aliased relative paths
431
471
  # and absolute paths. By default root is the present working directory
432
- # and no aliased directories or absolute paths are specified.
433
- def initialize(root=Dir.pwd, directories={}, absolute_paths={})
434
- assign_paths(root, directories, absolute_paths)
435
- @config = self.class.configurations.instance_config(self)
472
+ # and no aliased relative or absolute paths are specified.
473
+ def initialize(root=Dir.pwd, relative_paths={}, absolute_paths={})
474
+ assign_paths(root, relative_paths, absolute_paths)
475
+ @config = DelegateHash.new(self.class.configurations, {}, self)
436
476
  end
437
477
 
438
478
  # Sets the root directory. All paths are reassigned accordingly.
439
479
  def root=(path)
440
- assign_paths(path, directories, absolute_paths)
480
+ assign_paths(path, relative_paths, absolute_paths)
441
481
  end
442
482
 
443
- # Sets the directories to those provided. 'root' and :root are reserved
444
- # and cannot be set using this method (use root= instead).
483
+ # Sets the relative_paths to those provided. 'root' and :root are reserved
484
+ # aliases and cannot be set using this method (use root= instead).
485
+ #
486
+ # r = Tap::Root.new
487
+ # r['alt'] # => File.join(r.root, 'alt')
488
+ # r.relative_paths = {'alt' => 'dir'}
489
+ # r['alt'] # => File.join(r.root, 'dir')
445
490
  #
446
- # r['alt'] # => File.join(r.root, 'alt')
447
- # r.directories = {'alt' => 'dir'}
448
- # r['alt'] # => File.join(r.root, 'dir')
449
- def directories=(dirs)
450
- assign_paths(root, dirs, absolute_paths)
491
+ def relative_paths=(paths)
492
+ assign_paths(root, paths, absolute_paths)
451
493
  end
452
494
 
453
495
  # Sets the absolute paths to those provided. 'root' and :root are reserved
454
- # directory keys and cannot be set using this method (use root= instead).
496
+ # aliases and cannot be set using this method (use root= instead).
497
+ #
498
+ # r = Tap::Root.new
499
+ # r['abs'] # => File.join(r.root, 'abs')
500
+ # r.absolute_paths = {'abs' => '/path/to/dir'}
501
+ # r['abs'] # => '/path/to/dir'
455
502
  #
456
- # r['abs'] # => File.join(r.root, 'abs')
457
- # r.absolute_paths = {'abs' => '/path/to/dir'}
458
- # r['abs'] # => '/path/to/dir'
459
503
  def absolute_paths=(paths)
460
- assign_paths(root, directories, paths)
504
+ assign_paths(root, relative_paths, paths)
461
505
  end
462
506
 
463
507
  # Returns the absolute paths registered with self.
464
508
  def absolute_paths
465
509
  abs_paths = {}
466
- paths.each do |da, path|
467
- abs_paths[da] = path unless directories.include?(da) || da.to_s == 'root'
510
+ paths.each do |als, path|
511
+ unless relative_paths.include?(als) || als.to_s == 'root'
512
+ abs_paths[als] = path
513
+ end
468
514
  end
469
515
  abs_paths
470
516
  end
471
517
 
472
- # Sets an alias for the subdirectory relative to the root directory.
473
- # The aliases 'root' and :root cannot be set with this method
474
- # (use root= instead). Absolute filepaths can be set using the
475
- # second syntax.
518
+ # Sets an alias for the path relative to the root directory. The aliases
519
+ # 'root' and :root cannot be set with this method (use root= instead).
520
+ # Absolute filepaths can be set using the second syntax.
476
521
  #
477
- # r = Root.new '/root_dir'
478
- # r[:dir] = 'path/to/dir'
479
- # r[:dir] # => '/root_dir/path/to/dir'
522
+ # r = Root.new '/root_dir'
523
+ # r[:dir] = 'path/to/dir'
524
+ # r[:dir] # => '/root_dir/path/to/dir'
480
525
  #
481
- # r[:abs, true] = '/abs/path/to/dir'
482
- # r[:abs] # => '/abs/path/to/dir'
526
+ # r[:abs, true] = '/abs/path/to/dir'
527
+ # r[:abs] # => '/abs/path/to/dir'
483
528
  #
484
529
  #--
485
- # Implementation Notes:
530
+ # Implementation Note:
531
+ #
486
532
  # The syntax for setting an absolute filepath requires an odd use []=.
487
533
  # In fact the method recieves the arguments (:dir, true, '/abs/path/to/dir')
488
534
  # rather than (:dir, '/abs/path/to/dir', true), meaning that internally path
489
535
  # and absolute are switched when setting an absolute filepath.
490
- #++
491
- def []=(dir, path, absolute=false)
492
- raise ArgumentError, "The directory key '#{dir}' is reserved." if dir.to_s == 'root'
536
+ #
537
+ def []=(als, path, absolute=false)
538
+ raise ArgumentError, "the alias #{als.inspect} is reserved" if als.to_s == 'root'
493
539
 
494
540
  # switch the paths if absolute was provided
495
541
  unless absolute == false
@@ -500,84 +546,93 @@ module Tap
500
546
 
501
547
  case
502
548
  when path.nil?
503
- @directories.delete(dir)
504
- @paths.delete(dir)
549
+ @relative_paths.delete(als)
550
+ @paths.delete(als)
505
551
  when absolute
506
- @directories.delete(dir)
507
- @paths[dir] = File.expand_path(path)
552
+ @relative_paths.delete(als)
553
+ @paths[als] = File.expand_path(path)
508
554
  else
509
- @directories[dir] = path
510
- @paths[dir] = File.expand_path(File.join(root, path))
555
+ @relative_paths[als] = path
556
+ @paths[als] = File.expand_path(File.join(root, path))
511
557
  end
512
558
  end
513
559
 
514
- # Returns the expanded path for the specified alias. If the alias
515
- # has not been set, then the path is inferred to be 'root/dir' unless
516
- # the path is relative to path_root. These paths are returned
517
- # directly.
560
+ # Returns the expanded path for the specified alias. If the alias has not
561
+ # been set, then the path is inferred to be 'root/als'. Expanded paths
562
+ # are returned directly.
518
563
  #
519
- # r = Root.new '/root_dir', :dir => 'path/to/dir'
520
- # r[:dir] # => '/root_dir/path/to/dir'
564
+ # r = Root.new '/root_dir', :dir => 'path/to/dir'
565
+ # r[:dir] # => '/root_dir/path/to/dir'
521
566
  #
522
- # r.path_root # => '/'
523
- # r['relative/path'] # => '/root_dir/relative/path'
524
- # r['/expanded/path'] # => '/expanded/path'
567
+ # r.path_root # => '/'
568
+ # r['relative/path'] # => '/root_dir/relative/path'
569
+ # r['/expanded/path'] # => '/expanded/path'
525
570
  #
526
- def [](dir)
527
- path = self.paths[dir]
571
+ def [](als)
572
+ path = self.paths[als]
528
573
  return path unless path == nil
529
574
 
530
- dir = dir.to_s
531
- Root.expanded_path?(dir) ? dir : File.expand_path(File.join(root, dir))
575
+ als = als.to_s
576
+ Root.expanded?(als) ? als : File.expand_path(File.join(root, als))
532
577
  end
533
578
 
534
- # Constructs expanded filepaths relative to the path of the specified alias.
535
- def filepath(dir, *filename)
536
- # TODO - consider filename.compact so nils will not raise errors
537
- File.expand_path(File.join(self[dir], *filename))
579
+ # Resolves the specified alias, joins the paths together, and expands the
580
+ # resulting filepath. Analagous to File#expand_path(File#join).
581
+ def filepath(als, *paths)
582
+ File.expand_path(File.join(self[als], *paths))
538
583
  end
539
584
 
540
585
  # Retrieves the filepath relative to the path of the specified alias.
541
- def relative_filepath(dir, filepath)
542
- Root.relative_filepath(self[dir], filepath)
586
+ def relative_filepath(als, path)
587
+ Root.relative_filepath(self[als], path)
543
588
  end
544
589
 
545
- # Generates a target filepath translated from the aliased source_dir to
546
- # the aliased target_dir. Raises an error if the filepath is not relative
547
- # to the aliased source_dir.
590
+ # Generates a filepath translated from the aliased source dir to the
591
+ # aliased target dir. Raises an error if the filepath is not relative
592
+ # to the source dir.
548
593
  #
549
- # fp = r.filepath(:in, 'path/to/file.txt') # => '/root_dir/in/path/to/file.txt'
550
- # r.translate(fp, :in, :out) # => '/root_dir/out/path/to/file.txt'
551
- def translate(filepath, source_dir, target_dir)
552
- Root.translate(filepath, self[source_dir], self[target_dir])
594
+ # r = Tap::Root.new '/root_dir'
595
+ # path = r.filepath(:in, 'path/to/file.txt') # => '/root_dir/in/path/to/file.txt'
596
+ # r.translate(path, :in, :out) # => '/root_dir/out/path/to/file.txt'
597
+ #
598
+ def translate(path, source_als, target_als)
599
+ Root.translate(path, self[source_als], self[target_als])
553
600
  end
554
601
 
555
- # Lists all files in the aliased dir matching the input patterns. Patterns
556
- # should be valid inputs for +Dir.glob+. If no patterns are specified, lists
557
- # all files/folders matching '**/*'.
558
- def glob(dir, *patterns)
602
+ # Lists all files along the aliased path matching the input patterns.
603
+ # Patterns should join with the aliased path make valid globs for
604
+ # Dir.glob. If no patterns are specified, glob returns all paths
605
+ # matching 'als/**/*'.
606
+ def glob(als, *patterns)
559
607
  patterns << "**/*" if patterns.empty?
560
- patterns.collect! {|pattern| filepath(dir, pattern)}
608
+ patterns.collect! {|pattern| filepath(als, pattern)}
561
609
  Root.glob(*patterns)
562
610
  end
563
611
 
564
- # Lists all versions of filename in the aliased dir matching the version patterns.
565
- # If no patterns are specified, then all versions of filename will be returned.
566
- def vglob(dir, filename, *vpatterns)
567
- Root.vglob(filepath(dir, filename), *vpatterns)
612
+ # Lists all versions of path in the aliased dir matching the version
613
+ # patterns. If no patterns are specified, then all versions of path
614
+ # will be returned.
615
+ def vglob(als, path, *vpatterns)
616
+ Root.vglob(filepath(als, path), *vpatterns)
617
+ end
618
+
619
+ # Changes pwd to the specified directory using Root.chdir.
620
+ def chdir(als, mkdir=false, &block)
621
+ Root.chdir(self[als], mkdir, &block)
568
622
  end
569
623
 
570
- # chdirs to the specified directory using Root.chdir.
571
- def chdir(dir, mkdir=false, &block)
572
- Root.chdir(self[dir], mkdir, &block)
624
+ # Constructs a path from the inputs (using filepath) and prepares it using
625
+ # Root.prepare. Returns the path.
626
+ def prepare(als, *paths, &block)
627
+ Root.prepare(filepath(als, *paths), &block)
573
628
  end
574
629
 
575
630
  private
576
631
 
577
- # reassigns all paths with the input root, directories, and absolute_paths
578
- def assign_paths(root, directories, absolute_paths)
632
+ # reassigns all paths with the input root, relative_paths, and absolute_paths
633
+ def assign_paths(root, relative_paths, absolute_paths)
579
634
  @root = File.expand_path(root)
580
- @directories = {}
635
+ @relative_paths = {}
581
636
  @paths = {'root' => @root, :root => @root}
582
637
 
583
638
  @path_root = File.dirname(@root)
@@ -585,7 +640,7 @@ module Tap
585
640
  @path_root = parent
586
641
  end
587
642
 
588
- directories.each_pair {|dir, path| self[dir] = path }
643
+ relative_paths.each_pair {|dir, path| self[dir] = path }
589
644
  absolute_paths.each_pair {|dir, path| self[dir, true] = path }
590
645
  end
591
646