tap 0.7.9 → 0.8.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 (149) hide show
  1. data/History +28 -0
  2. data/MIT-LICENSE +1 -1
  3. data/README +71 -43
  4. data/Rakefile +81 -64
  5. data/Tutorial +235 -0
  6. data/bin/tap +80 -44
  7. data/lib/tap.rb +41 -12
  8. data/lib/tap/app.rb +243 -246
  9. data/lib/tap/file_task.rb +357 -118
  10. data/lib/tap/generator.rb +88 -29
  11. data/lib/tap/generator/generators/config/config_generator.rb +4 -2
  12. data/lib/tap/generator/generators/config/templates/config.erb +1 -2
  13. data/lib/tap/generator/generators/file_task/file_task_generator.rb +3 -18
  14. data/lib/tap/generator/generators/file_task/templates/task.erb +22 -15
  15. data/lib/tap/generator/generators/file_task/templates/test.erb +13 -2
  16. data/{test/test/inference_methods/test_assert_files_exist/input/input_1.txt → lib/tap/generator/generators/generator/USAGE} +0 -0
  17. data/lib/tap/generator/generators/generator/generator_generator.rb +21 -0
  18. data/lib/tap/generator/generators/generator/templates/generator.erb +23 -0
  19. data/lib/tap/generator/generators/generator/templates/usage.erb +1 -0
  20. data/{test/test/inference_methods/test_assert_files_exist/input/input_2.txt → lib/tap/generator/generators/package/USAGE} +0 -0
  21. data/lib/tap/generator/generators/package/package_generator.rb +38 -0
  22. data/lib/tap/generator/generators/package/templates/package.erb +186 -0
  23. data/lib/tap/generator/generators/root/root_generator.rb +14 -9
  24. data/lib/tap/generator/generators/root/templates/Rakefile +20 -14
  25. data/{test/test/inference_methods/test_infer_glob/expected/file.yml → lib/tap/generator/generators/root/templates/ReadMe.txt} +0 -0
  26. data/lib/tap/generator/generators/root/templates/tap.yml +82 -0
  27. data/lib/tap/generator/generators/root/templates/test/tap_test_helper.rb +0 -1
  28. data/lib/tap/generator/generators/root/templates/test/tap_test_suite.rb +2 -1
  29. data/{test/test/inference_methods/test_infer_glob/expected/file_1.txt → lib/tap/generator/generators/script/USAGE} +0 -0
  30. data/lib/tap/generator/generators/script/script_generator.rb +17 -0
  31. data/lib/tap/generator/generators/script/templates/script.erb +42 -0
  32. data/lib/tap/generator/generators/task/task_generator.rb +1 -1
  33. data/lib/tap/generator/generators/task/templates/task.erb +24 -16
  34. data/lib/tap/generator/generators/task/templates/test.erb +13 -17
  35. data/lib/tap/generator/generators/workflow/templates/task.erb +10 -10
  36. data/lib/tap/generator/generators/workflow/templates/test.erb +1 -1
  37. data/lib/tap/generator/generators/workflow/workflow_generator.rb +3 -18
  38. data/lib/tap/root.rb +108 -146
  39. data/lib/tap/script.rb +362 -0
  40. data/lib/tap/script/console.rb +28 -0
  41. data/lib/tap/script/destroy.rb +13 -1
  42. data/lib/tap/script/generate.rb +13 -1
  43. data/lib/tap/script/run.rb +100 -57
  44. data/lib/tap/support/batch_queue.rb +0 -3
  45. data/lib/tap/support/logger.rb +6 -3
  46. data/lib/tap/support/rake.rb +54 -0
  47. data/lib/tap/support/task_configuration.rb +169 -0
  48. data/lib/tap/support/tdoc.rb +198 -0
  49. data/lib/tap/support/tdoc/config_attr.rb +338 -0
  50. data/lib/tap/support/tdoc/tdoc_html_generator.rb +38 -0
  51. data/lib/tap/support/tdoc/tdoc_html_template.rb +42 -0
  52. data/lib/tap/support/versions.rb +33 -1
  53. data/lib/tap/task.rb +339 -227
  54. data/lib/tap/test.rb +86 -128
  55. data/lib/tap/test/env_vars.rb +16 -5
  56. data/lib/tap/test/file_methods.rb +373 -0
  57. data/lib/tap/test/subset_methods.rb +299 -180
  58. data/lib/tap/version.rb +2 -1
  59. data/lib/tap/workflow.rb +2 -0
  60. data/test/app/lib/app_test_task.rb +1 -0
  61. data/test/app_test.rb +327 -83
  62. data/test/check/binding_eval.rb +23 -0
  63. data/test/check/define_method_check.rb +22 -0
  64. data/test/check/dependencies_check.rb +175 -0
  65. data/test/check/inheritance_check.rb +22 -0
  66. data/test/file_task_test.rb +524 -291
  67. data/test/{test/inference_methods/test_infer_glob/expected/file_2.txt → root/glob/one.txt} +0 -0
  68. data/test/root/glob/two.txt +0 -0
  69. data/test/root_test.rb +330 -262
  70. data/test/script_test.rb +194 -0
  71. data/test/support/audit_test.rb +5 -2
  72. data/test/support/combinator_test.rb +10 -10
  73. data/test/support/rake_test.rb +35 -0
  74. data/test/support/task_configuration_test.rb +272 -0
  75. data/test/support/tdoc_test.rb +363 -0
  76. data/test/support/templater_test.rb +2 -2
  77. data/test/support/versions_test.rb +32 -0
  78. data/test/tap_test_helper.rb +39 -0
  79. data/test/task_base_test.rb +115 -0
  80. data/test/task_class_test.rb +56 -4
  81. data/test/task_execute_test.rb +29 -0
  82. data/test/task_test.rb +89 -70
  83. data/test/test/env_vars_test.rb +48 -0
  84. data/test/test/{inference_methods → file_methods}/test_assert_expected/expected/file.txt +0 -0
  85. data/test/test/{inference_methods → file_methods}/test_assert_expected/expected/folder/file.txt +0 -0
  86. data/test/test/{inference_methods → file_methods}/test_assert_expected/input/file.txt +0 -0
  87. data/test/test/{inference_methods → file_methods}/test_assert_expected/input/folder/file.txt +0 -0
  88. data/test/test/file_methods/test_assert_files_exist/input/input_1.txt +0 -0
  89. data/test/test/file_methods/test_assert_files_exist/input/input_2.txt +0 -0
  90. data/test/test/file_methods/test_assert_output_files_equal/expected/one.txt +1 -0
  91. data/test/test/file_methods/test_assert_output_files_equal/expected/two.txt +1 -0
  92. data/test/test/file_methods/test_assert_output_files_equal/input/one.txt +1 -0
  93. data/test/test/file_methods/test_assert_output_files_equal/input/two.txt +1 -0
  94. data/test/test/{inference_methods → file_methods}/test_file_compare/expected/output_1.txt +0 -0
  95. data/test/test/{inference_methods → file_methods}/test_file_compare/expected/output_2.txt +0 -0
  96. data/test/test/{inference_methods → file_methods}/test_file_compare/input/input_1.txt +0 -0
  97. data/test/test/{inference_methods → file_methods}/test_file_compare/input/input_2.txt +0 -0
  98. data/test/test/file_methods/test_infer_glob/expected/file.yml +0 -0
  99. data/test/test/file_methods/test_infer_glob/expected/file_1.txt +0 -0
  100. data/test/test/file_methods/test_infer_glob/expected/file_2.txt +0 -0
  101. data/test/test/file_methods/test_method_glob/expected/file.yml +0 -0
  102. data/test/test/file_methods/test_method_glob/expected/file_1.txt +0 -0
  103. data/test/test/file_methods/test_method_glob/expected/file_2.txt +0 -0
  104. data/test/test/{inference_methods → file_methods}/test_yml_compare/expected/output_1.yml +0 -0
  105. data/test/test/{inference_methods → file_methods}/test_yml_compare/expected/output_2.yml +0 -0
  106. data/test/test/{inference_methods → file_methods}/test_yml_compare/input/input_1.yml +0 -0
  107. data/test/test/{inference_methods → file_methods}/test_yml_compare/input/input_2.yml +0 -0
  108. data/test/test/file_methods_test.rb +204 -0
  109. data/test/test/subset_methods_test.rb +93 -33
  110. data/test/test/test_assert_expected_result_files/expected/task/name/a.txt +1 -0
  111. data/test/test/test_assert_expected_result_files/expected/task/name/b.txt +1 -0
  112. data/test/test/test_assert_expected_result_files/input/a.txt +1 -0
  113. data/test/test/test_assert_expected_result_files/input/b.txt +1 -0
  114. data/test/test/test_file_task_test/expected/one.txt +1 -0
  115. data/test/test/test_file_task_test/expected/two.txt +1 -0
  116. data/test/test/test_file_task_test/input/one.txt +1 -0
  117. data/test/test/test_file_task_test/input/two.txt +1 -0
  118. data/test/test_test.rb +143 -3
  119. data/test/workflow_test.rb +2 -0
  120. data/vendor/rails_generator.rb +56 -0
  121. data/vendor/rails_generator/base.rb +263 -0
  122. data/vendor/rails_generator/commands.rb +581 -0
  123. data/vendor/rails_generator/generated_attribute.rb +42 -0
  124. data/vendor/rails_generator/lookup.rb +209 -0
  125. data/vendor/rails_generator/manifest.rb +53 -0
  126. data/vendor/rails_generator/options.rb +143 -0
  127. data/vendor/rails_generator/scripts.rb +83 -0
  128. data/vendor/rails_generator/scripts/destroy.rb +7 -0
  129. data/vendor/rails_generator/scripts/generate.rb +7 -0
  130. data/vendor/rails_generator/scripts/update.rb +12 -0
  131. data/vendor/rails_generator/simple_logger.rb +46 -0
  132. data/vendor/rails_generator/spec.rb +44 -0
  133. metadata +180 -196
  134. data/lib/tap/generator/generators/root/templates/app.yml +0 -19
  135. data/lib/tap/generator/generators/root/templates/config/process_tap_request.yml +0 -4
  136. data/lib/tap/generator/generators/root/templates/lib/process_tap_request.rb +0 -26
  137. data/lib/tap/generator/generators/root/templates/public/images/nav.jpg +0 -0
  138. data/lib/tap/generator/generators/root/templates/public/stylesheets/color.css +0 -57
  139. data/lib/tap/generator/generators/root/templates/public/stylesheets/layout.css +0 -108
  140. data/lib/tap/generator/generators/root/templates/public/stylesheets/normalize.css +0 -40
  141. data/lib/tap/generator/generators/root/templates/public/stylesheets/typography.css +0 -21
  142. data/lib/tap/generator/generators/root/templates/server/config/environment.rb +0 -60
  143. data/lib/tap/generator/generators/root/templates/server/lib/tasks/clear_database_prerequisites.rake +0 -5
  144. data/lib/tap/generator/generators/root/templates/server/test/test_helper.rb +0 -53
  145. data/lib/tap/script/server.rb +0 -12
  146. data/lib/tap/support/rap.rb +0 -38
  147. data/lib/tap/test/inference_methods.rb +0 -298
  148. data/test/task/config/task_with_config.yml +0 -1
  149. data/test/test/inference_methods_test.rb +0 -311
@@ -12,23 +12,28 @@ module Tap::Generator::Generators
12
12
  record do |m|
13
13
  # directories
14
14
  m.directory "lib"
15
- m.directory "config"
15
+ #m.directory "config"
16
16
  m.directory "test"
17
- m.directory "public"
18
- m.directory "public/images"
19
- m.directory "public/stylesheets"
20
- m.directory "gemspecs"
21
- m.directory "server/config"
22
- m.directory "server/test"
23
- m.directory "server/lib/tasks"
17
+
18
+ # remove these -- they will be created from
19
+ # a server generator in the future
20
+ #m.directory "server/config"
21
+ #m.directory "server/test"
22
+ #m.directory "server/lib/tasks"
24
23
 
25
24
  # files
26
25
  template_dir = File.dirname(__FILE__) + "/templates"
27
26
  Dir.glob(template_dir + "/**/*").each do |fname|
28
27
  next if File.directory?(fname)
28
+
29
+ # skip server files for now... later
30
+ # the files will simply be removed
31
+ next if fname =~ /server/
32
+ next if fname =~ /config/
33
+ next if fname =~ /process_tap_request/
29
34
 
30
35
  fname = Tap::Root.relative_filepath(template_dir, fname)
31
- m.file fname, fname
36
+ m.template fname, fname
32
37
  end
33
38
  end
34
39
  end
@@ -9,17 +9,23 @@ task :default => :test
9
9
 
10
10
  desc 'Run tests.'
11
11
  Rake::TestTask.new(:test) do |t|
12
- t.libs << 'lib'
13
- t.pattern = File.join('test', ENV['subset'] || '', ENV['pattern'] || '**/*_test.rb')
14
- t.verbose = true
12
+ t.pattern = 'test/**/*_test.rb'
13
+ t.verbose = true
14
+ t.warning = true
15
15
  end
16
16
 
17
17
  desc 'Generate documentation.'
18
- Rake::RDocTask.new(:rdoc) do |rdoc|
19
- rdoc.rdoc_dir = 'rdoc'
20
- rdoc.title = 'Local' # should be changed
18
+ Rake::RDocTask.new(:rdoc) do |rdoc|
19
+ # options to specify TDoc
20
+ require 'tap/support/tdoc'
21
+ rdoc.template = 'tap/support/tdoc/tdoc_html_template'
22
+ rdoc.options << '--fmt' << 'tdoc'
23
+
24
+ rdoc.rdoc_dir = 'rdoc'
25
+ rdoc.title = '<%= file_name %>'
26
+ rdoc.template = 'tap/support/tdoc/tdoc_html_template'
21
27
  rdoc.options << '--line-numbers' << '--inline-source'
22
- rdoc.rdoc_files.include('README')
28
+ rdoc.rdoc_files.include('ReadMe.txt')
23
29
  rdoc.rdoc_files.include('lib/**/*.rb')
24
30
  end
25
31
 
@@ -27,20 +33,20 @@ end
27
33
  # Gem specification
28
34
  #
29
35
  spec = Gem::Specification.new do |s|
30
- #s.name = "gemname"
36
+ s.name = "<%= file_name %>"
31
37
  s.version = "0.0.1"
32
- #s.author = "Your Name Here"
38
+ s.author = "Your Name Here"
33
39
  #s.email = "your.email@pubfactory.edu"
34
40
  #s.homepage = "http://rubyforge.org/projects/gemname/"
35
41
  s.platform = Gem::Platform::RUBY
36
- #s.summary = "Description"
37
- s.files = Dir.glob("{test,lib,docs}/**/*")
42
+ s.summary = "Add Description"
43
+ s.files = Dir.glob("{test,lib}/**/*") + ["Rakefile", "ReadMe.txt"]
38
44
  s.require_path = "lib"
39
- s.test_file = "test/tap_test_suite.rb" # should be changed
45
+ s.test_file = "test/tap_test_suite.rb"
40
46
 
41
47
  s.has_rdoc = true
42
- s.extra_rdoc_files = ["README"]
43
- s.add_dependency("tap", ">= 0.1.0")
48
+ s.extra_rdoc_files = ["ReadMe.txt"]
49
+ s.add_dependency("tap", ">= <%= Tap::VERSION %>")
44
50
  end
45
51
 
46
52
  Rake::GemPackageTask.new(spec) do |pkg|
@@ -0,0 +1,82 @@
1
+ ######################################################
2
+ # App Configurations:
3
+ #
4
+ # These are configurations that directly affect the
5
+ # application, including the directory structure
6
+ # options, and logging.
7
+ #
8
+ ######################################################
9
+
10
+ # You can set an alternate root, but this is
11
+ # an odd and perhaps unwise thing to do
12
+ #root:
13
+
14
+ # Uncomment to specify aliases for directories relative to root.
15
+ # Access using: app['lib'] # => root/alt_lib
16
+ # By default: app['lib'] # => root/lib
17
+ #directories:
18
+ #lib: alt_lib
19
+ #...
20
+
21
+ # Uncomment to specify aliases for absolute paths
22
+ # Access using: app['log'] # => /path/to/logs
23
+ #absolute_paths:
24
+ #log: /path/to/logs
25
+ #...
26
+
27
+ # Uncomment to specify options.
28
+ # Access using: app.options.debug # => true
29
+ #options:
30
+ #debug: true # full error output, increased logging
31
+ #quiet: true # supresses logging
32
+ #... # you can add your own options
33
+
34
+ # Specify logging options here.
35
+ #logger:
36
+ #device: # STDOUT by default
37
+ #level: 1 # [DEBUG, INFO, WARN, ERROR, FATAL, ANY]
38
+ #datetime_format: %H:%M:%S # Hour:Minute:Second
39
+
40
+ # Map task names to task classes here. The example causes
41
+ # app.task('some/task_name') to intialize a Tap::FileTask
42
+ # with that name. Any number of mappings can be specified.
43
+ #map:
44
+ # some/task_name: Tap::FileTask
45
+ # CapsAreOk: Tap::Task
46
+
47
+
48
+ ######################################################
49
+ # Script Configurations:
50
+ #
51
+ # These are configurations that affect the execution
52
+ # environment for Tap and are NOT passed to the
53
+ # application itself.
54
+ #
55
+ ######################################################
56
+
57
+ # Designate load paths here for automatic loading and
58
+ # reloading of tasks through the active_support
59
+ # Dependencies module. The default is 'lib'. Paths
60
+ # are resolved to the aliases setup above,
61
+ # 'lib' => app['lib']
62
+ #load_paths:
63
+ # - 'lib'
64
+
65
+ # Designate script paths for discovering and executing
66
+ # commands. The default is 'script'. Paths are resolved
67
+ # to the aliases setup above, 'script' => app['script']
68
+ #script_paths:
69
+ # - 'script'
70
+
71
+ # Specify gems that contain load_paths and script_paths
72
+ # that you likewise want to be automatically loaded.
73
+ # Specify versions directly.
74
+ #gems:
75
+ # - gem_name
76
+ # - gem_with_version > 1.0.0
77
+
78
+ # Specify code to execute before and after Tap executes
79
+ #before: |
80
+ # puts "beginning..."
81
+ #after: |
82
+ # puts "done!"
@@ -1,3 +1,2 @@
1
- require 'rubygems'
2
1
  require 'tap'
3
2
  require 'tap/test'
@@ -1,4 +1,5 @@
1
1
  $:.unshift File.join(File.dirname(__FILE__), '../lib')
2
2
 
3
- ENV["ALL"] = true # runs all subsets (see gemdev)
3
+ # runs all subsets (see Tap::Test::SubsetMethods)
4
+ ENV["ALL"] = true
4
5
  Dir.glob("./**/*_test.rb").each {|test| require test}
@@ -0,0 +1,17 @@
1
+ module Tap::Generator::Generators
2
+ class ScriptGenerator < Rails::Generator::NamedBase # :nodoc:
3
+ def initialize(*args)
4
+ super(*args)
5
+ @destination_root = Tap::App.instance[:root]
6
+ @app = Tap::App.instance
7
+ end
8
+
9
+ def manifest
10
+ record do |m|
11
+ script_path = @app.relative_filepath(:root, @app[:script])
12
+ m.directory class_path.empty? ? script_path : File.join(script_path, class_path)
13
+ m.template "script.erb", File.join(script_path, class_name.underscore + ".rb")
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,42 @@
1
+ # = Usage
2
+ # tap <%= file_name %> {options} OTHER_ARGS...
3
+ #
4
+ # = Description
5
+ # Some informative description...
6
+ #
7
+ # = Information
8
+ #
9
+ # Developer:: <your name>
10
+ # Homepage:: <your homepage>
11
+ # Copyright (c):: <%= Time.now.strftime("%Y") %>, <copyright holders>
12
+ # License:: MIT-LICENSE (http://www.opensource.org/licenses/mit-license.php) <or some other license...>
13
+ #
14
+ require 'tap/script'
15
+
16
+ app = Tap::App.instance
17
+
18
+ #
19
+ # handle options
20
+ #
21
+
22
+ opts = [
23
+ ['--help', '-h', GetoptLong::NO_ARGUMENT, "Print this help."],
24
+ ['--debug', nil, GetoptLong::NO_ARGUMENT, "Specifes debug mode."]]
25
+
26
+ Tap::Script.handle_options(*opts) do |opt, value|
27
+ case opt
28
+ when '--help'
29
+ puts Tap::Script.usage(__FILE__, "Usage", "Description", "Information", :keep_headers => false)
30
+ puts
31
+ puts Tap::Script.usage_options(opts)
32
+ exit
33
+
34
+ when '--debug'
35
+ app.options.debug = true
36
+
37
+ end
38
+ end
39
+
40
+ #
41
+ # add your script code here
42
+ #
@@ -10,7 +10,7 @@ module Tap::Generator::Generators
10
10
  record do |m|
11
11
  lib_path = @app.relative_filepath(:root, @app[:lib])
12
12
  m.directory File.join(lib_path, class_path)
13
- m.template "task.erb", File.join(lib_path, class_name.underscore + ".rb")
13
+ m.template "task.erb", File.join(lib_path, class_name.underscore + ".rb"), :class_nesting => class_nesting
14
14
 
15
15
  test_path = @app.relative_filepath(:root, @app[:test])
16
16
  m.directory File.join(test_path, class_path)
@@ -1,21 +1,29 @@
1
- # == Documentation
1
+ # == Description
2
+ # Replace with a description. The default task simply
3
+ # demonstrates the use of a config and logging.
4
+ # === Usage
5
+ # Replace with usage instructions
2
6
  #
3
- # === Command Line Usage
4
- # Replace with your command line usage instructions
5
- #
6
- class <%= class_name %> < Tap::Task
7
-
7
+ class <%= class_name_without_nesting %> < Tap::Task
8
+ # uncomment to:
9
+ # - pass all inputs to process at once
10
+ # - define a task that takes no inputs
11
+
12
+ #do_not_iterate
13
+
14
+ # use config to set task configurations
15
+ # configs have accessors by default
16
+
17
+ config :label, 'input' # a label for output
18
+
8
19
  def process(input)
9
- # The process logic goes here.
10
-
11
- # You can access configurations as symbols within the config hash
12
- message = "#{config[:greeting]} #{input}!"
13
-
14
- # Use log to record information
15
- log :message, message
16
-
17
- # The return of process is the task output
18
- message
20
+ # the process logic goes here.
21
+
22
+ # use log to record information
23
+ log label, input
24
+
25
+ # the return of process is the task output
26
+ "#{label}: #{input} was processed"
19
27
  end
20
28
 
21
29
  end
@@ -1,28 +1,24 @@
1
1
  require File.join(File.dirname(__FILE__), '<%= '../' * class_nesting_depth %>tap_test_helper.rb')
2
2
  require '<%= class_path.empty? ? file_name : File.join(class_path, file_name) %>'
3
3
 
4
- class <%= class_name %>Test < Test::Unit::TestCase
4
+ class <%= class_name_without_nesting %>Test < Test::Unit::TestCase
5
5
  acts_as_tap_test
6
6
 
7
- def test_greeting
8
- t = <%= class_name %>.new nil, :greeting => 'hello'
7
+ def test_<%= file_name %>
8
+ t = <%= class_name %>.new nil, :label => 'key'
9
9
 
10
+ # specify application options
10
11
  with_options(:quiet => true) do
11
- t.execute("from me", "to you")
12
-
13
- assert_equal({:greeting => 'hello'}, t.config)
14
- assert_outputs(t => ["hello from me!", "hello to you!"])
15
12
 
16
- # check the audit trail for each input
17
- assert_audits(t.results,
18
- 0 => [[nil, 'from me'], [t, 'hello from me!']],
19
- 1 => [[nil, 'to you'], [t, 'hello to you!']])
20
-
21
- # an alternate way of checking audits
22
- check_audit(t.results[1]) do
23
- 'to you'._from nil
24
- 'hello to you!'._from t
25
- end
13
+ # run the task with some inputs
14
+ app.run(t, "one", "two")
15
+
16
+ # check the configuration and outputs
17
+ assert_equal({:label => 'key'}, t.config)
18
+ assert_outputs(t => [
19
+ "key: one was processed",
20
+ "key: two was processed"])
21
+
26
22
  end
27
23
  end
28
24
 
@@ -1,16 +1,16 @@
1
- # == Documentation
1
+ # == Description
2
2
  #
3
- # === Command Line Usage
3
+ # === Usage
4
4
  # Replace with your command line usage instructions
5
5
  #
6
- class <%= class_name %> < Tap::Workflow
7
- protected
6
+ class <%= class_name_without_nesting %> < Tap::Workflow
7
+ protected
8
8
 
9
- def workflow
10
- # Define the workflow entry and exit points,
11
- # as well as the workflow logic.
12
- self.entry_point = Task.new
9
+ def workflow
10
+ # Define the workflow entry and exit points,
11
+ # as well as the workflow logic.
12
+ self.entry_point = Task.new
13
13
 
14
- # app.sequence(entry_point, 'another/task')
15
- end
14
+ # app.sequence(entry_point, 'another/task')
15
+ end
16
16
  end
@@ -1,7 +1,7 @@
1
1
  require File.join(File.dirname(__FILE__), '<%= '../' * class_nesting_depth %>tap_test_helper.rb')
2
2
  require '<%= class_path.empty? ? file_name : File.join(class_path, file_name) %>'
3
3
 
4
- class <%= class_name %>Test < Test::Unit::TestCase
4
+ class <%= class_name_without_nesting %>Test < Test::Unit::TestCase
5
5
  acts_as_tap_test
6
6
 
7
7
  end
@@ -1,21 +1,6 @@
1
- module Tap::Generator::Generators
2
- class WorkflowGenerator < Rails::Generator::NamedBase # :nodoc:
3
- def initialize(*args)
4
- super(*args)
5
- @destination_root = Tap::App.instance[:root]
6
- @app = Tap::App.instance
7
- end
1
+ require 'tap/generator/generators/task/task_generator'
8
2
 
9
- def manifest
10
- record do |m|
11
- lib_path = @app.relative_filepath(:root, @app[:lib])
12
- m.directory File.join(lib_path, class_path)
13
- m.template "task.erb", File.join(lib_path, class_name.underscore + ".rb")
14
-
15
- test_path = @app.relative_filepath(:root, @app[:test])
16
- m.directory File.join(test_path, class_path)
17
- m.template "test.erb", File.join(test_path, class_name.underscore + "_test.rb")
18
- end
19
- end
3
+ module Tap::Generator::Generators
4
+ class WorkflowGenerator < TaskGenerator # :nodoc:
20
5
  end
21
6
  end
data/lib/tap/root.rb CHANGED
@@ -1,60 +1,62 @@
1
- require 'fileutils'
2
1
  require 'tap/support/versions'
3
2
 
4
- # string.rb is required for camelizing and underscoring strings
5
- # requiring just this file rather than the full gem results in
6
- # noticably faster startup
7
- require 'active_support/core_ext/string'
8
-
9
3
  module Tap
10
4
 
11
- # Most applications that utilize files allow the definition of a root directory,
12
- # allowing you to place the application directory wherever you like. Root takes
13
- # this concept further, allowing you to define subdirectories, as well as manipulate
14
- # files and filepaths within these directories. For example:
5
+ # Root allows you to define a root directory and alias subdirectories, so that
6
+ # you can conceptualize what filepaths you need without predefining the full
7
+ # filepaths. Root also simplifies operations on filepaths.
15
8
  #
16
- # root = Root.new 'root_dir', :input => 'in', :output => 'out'
9
+ # # define a root directory with aliased subdirectories
10
+ # r = Root.new '/root_dir', :input => 'in', :output => 'out'
17
11
  #
18
12
  # # work with directories
19
- # root[:in] # => 'root_dir/in'
20
- # root[:out] # => 'root_dir/out'
21
- # root[:implicit] # => 'root_dir/implicit'
13
+ # r[:in] # => '/root_dir/in'
14
+ # r[:out] # => '/root_dir/out'
15
+ # r[:implicit] # => '/root_dir/implicit'
22
16
  #
23
17
  # # work with filepaths
24
- # fp = root.filepath(:in, 'path/to/file.txt') # => 'root_dir/in/path/to/file.txt'
25
- # root.relative_filepath(:in, fp) # => 'path/to/file.txt'
26
- # root.translate(fp, :in, :out) # => 'root_dir/out/path/to/file.txt'
18
+ # fp = r.filepath(:in, 'path/to/file.txt') # => '/root_dir/in/path/to/file.txt'
19
+ # r.relative_filepath(:in, fp) # => 'path/to/file.txt'
20
+ # r.translate(fp, :in, :out) # => '/root_dir/out/path/to/file.txt'
27
21
  #
28
22
  # # version filepaths
29
- # root.version('path/to/config.yml', 1.0) # => 'path/to/config-1.0.yml'
30
- # root.increment('path/to/config-1.0.yml', 0.1) # => 'path/to/config-1.1.yml'
31
- # root.deversion('path/to/config-1.1.yml') # => ['path/to/config.yml', "1.1"]
32
- #
33
- # # work with modules...
34
- # mp = root.module_filepath(:lib, 'Some::Module') # => 'root_dir/lib/some/module.rb'
35
- #
36
- # # loading them...
37
- # Object.const_defined?(:Some) # => false
38
- # root.lookup_module('Some::Module') # => Some::Module
39
- # Some.const_defined?(:Module) # => true
23
+ # r.version('path/to/config.yml', 1.0) # => 'path/to/config-1.0.yml'
24
+ # r.increment('path/to/config-1.0.yml', 0.1) # => 'path/to/config-1.1.yml'
25
+ # r.deversion('path/to/config-1.1.yml') # => ['path/to/config.yml', "1.1"]
26
+ #
27
+ # # absolute paths can also be aliased
28
+ # r[:abs, true] = "/absolute/path"
29
+ # r.filepath(:abs, "to", "file.txt") # => '/absolute/path/to/file.txt'
40
30
  #
41
- # # and unloading them!
42
- # root.unload_modules # => ["Some::Module"]
43
- # Object.const_defined?(:Some) # => false
31
+ # By default, Roots are initialized to the present working directory (Dir.pwd).
32
+ # As in the ':implicit' example, whenever Root needs to resolve an alias that is
33
+ # not explicitly set, Root infers a path relative to the root directory.
44
34
  #
45
- # === Notes
35
+ # === Implementation Notes
36
+ #
37
+ # Internally Root stores expanded paths for both subdirectories and absolute paths in a
38
+ # hash, 'paths', for quick lookup using the da (directory alias) keys. Expanding paths
39
+ # ensures they remain constant even when the present working directory (Dir.pwd) changes.
40
+ #
41
+ # Root keeps a separate hash mapping aliases to the subdirectory paths, 'directories'.
42
+ # These relative filepaths allow reassignment of the expanded paths if and when the
43
+ # root directory changes. By contrast, there is no separate data structure storing the
44
+ # absolute paths. An absolute path can be distinguished from a subdirectory path by
45
+ # aliases present in 'paths' but not 'directories'.
46
+ #
47
+ # These features may be important to note when subclassing Root:
48
+ # - root and all filepaths in 'paths' are expanded
49
+ # - directory aliases and subdirectory paths are stored in 'directories'
50
+ # - absolute paths are present in 'paths' but not in 'directories'
46
51
  #
47
- # Root internally stores paths for both relative directories and absolute paths in a
48
- # hash for quick lookup using the dir keys. Root keeps a separate hash for the
49
- # original directories used to create the paths, but this is not necessary for
50
- # absolute paths. An absolute path can be distinguished from a directory by having
51
- # an entry in paths but not directories.
52
52
  class Root
53
53
  class << self
54
54
  include Support::Versions
55
55
 
56
- # Returns the filepath of path relative to dir. If strict=true (the default) then
57
- # relative_filepath raises an error if the path is not relative to dir.
56
+ # Returns the filepath of path relative to dir. Both dir and path are
57
+ # expanded before the relative filepath is determined. If strict=true
58
+ # (the default), then relative_filepath raises an error if the path is
59
+ # not relative to dir. Otherwise, the expanded path will be returned.
58
60
  #
59
61
  # Root.relative_filepath('dir', "dir/path/to/file.txt") # => "path/to/file.txt"
60
62
  #
@@ -64,7 +66,7 @@ module Tap
64
66
 
65
67
  unless expanded[0...dir.length] == dir
66
68
  raise "\n#{expanded}\nis not relative to:\n#{dir}" if strict
67
- return path
69
+ return expanded
68
70
  end
69
71
 
70
72
  # use dir.length + 1 to remove a leading '/'. If dir.length + 1 >= expanded.length
@@ -80,8 +82,8 @@ module Tap
80
82
  end.flatten.uniq
81
83
  end
82
84
 
83
- # Lists all unique versions of path matching the glob version patterns. If no patterns
84
- # are specified, then all versions of path will be returned.
85
+ # Lists all unique versions of path matching the glob version patterns.
86
+ # If no patterns are specified, then all versions of path will be returned.
85
87
  def vglob(path, *vpatterns)
86
88
  vpatterns << "*" if vpatterns.empty?
87
89
  vpatterns.collect do |vpattern|
@@ -92,30 +94,6 @@ module Tap
92
94
  results
93
95
  end.flatten.uniq
94
96
  end
95
-
96
-
97
-
98
- #def package(target, *filepaths)
99
- # options = filepaths.pop if filepaths.last.kind_of?(Hash)
100
- #end
101
-
102
- # glob for dirs, remove if empty. removes dir if empty on complete
103
- # OR
104
- # remove files older than a certain date
105
- # remove all files
106
- #
107
- #def cleanup(dir)
108
- #end
109
-
110
- # iotask?
111
- def parse_by_line(path, options={}, &block)
112
- str = read(path, options.merge(:as => :txt))
113
- lines = str.split(/\r?\n/)
114
- lines.each do |line|
115
- # don't yield empty lines because they split to [] (ie [nil, nil] for the block inputs)
116
- yield(line.split(/#/, 2)) unless line.empty?
117
- end
118
- end
119
97
  end
120
98
 
121
99
  include Support::Versions
@@ -123,7 +101,7 @@ module Tap
123
101
 
124
102
  # Creates a new Root with the given root, directories, and absolute
125
103
  # paths. By default root is the current working directory and no
126
- # directories or absolute paths are specified.
104
+ # directories or absolute paths are specified.
127
105
  def initialize(root=Dir.pwd, directories={}, absolute_paths={})
128
106
  assign_paths(root, directories, absolute_paths)
129
107
  end
@@ -133,44 +111,46 @@ module Tap
133
111
  assign_paths(path, directories, absolute_paths)
134
112
  end
135
113
 
136
- # Sets the directories to those provided. 'root' and :root are reserved directory
137
- # keys and cannot be set using this method (use root= instead).
114
+ # Sets the directories to those provided. 'root' and :root are reserved
115
+ # directory keys and cannot be set using this method (use root= instead).
138
116
  def directories=(dirs)
139
117
  assign_paths(root, dirs, absolute_paths)
140
118
  end
141
119
 
142
- # Sets the absolute paths to those provided. 'root' and :root are reserved directory
143
- # keys and cannot be set using this method (use root= instead).
120
+ # Sets the absolute paths to those provided. 'root' and :root are reserved
121
+ # directory keys and cannot be set using this method (use root= instead).
144
122
  def absolute_paths=(paths)
145
123
  assign_paths(root, directories, paths)
146
124
  end
147
125
 
148
- # Returns the absolute paths registered with the Root.
126
+ # Returns the absolute paths registered with self.
149
127
  def absolute_paths
150
128
  abs_paths = {}
151
- paths.each do |dir, path|
152
- abs_paths[dir] = path unless directories.include?(dir) || dir.to_s == 'root'
129
+ paths.each do |da, path|
130
+ abs_paths[da] = path unless directories.include?(da) || da.to_s == 'root'
153
131
  end
154
132
  abs_paths
155
133
  end
156
134
 
157
- # Sets the path to the specified directory, relative to the root directory.
135
+ # Sets a directory alias (da) for the path relative to the root directory.
158
136
  # The root directory cannot be set with this method (use root= instead).
159
- # Absolute filepaths can be set by specifying the absolute parameter.
137
+ # Absolute filepaths can be set using the second syntax.
160
138
  #
161
- # root[:dir] = 'path/to/dir'
162
- # root[:root] # => 'root_dir'
163
- # root[:dir] # => 'root_dir/path/to/dir'
139
+ # r = Root.new '/root_dir'
140
+ # r[:dir] = 'path/to/dir'
141
+ # r[:dir] # => '/root_dir/path/to/dir'
164
142
  #
165
- # root[:abs, true] = '/abs/path/to/dir'
166
- # root[:abs] # => '/abs/path/to/dir'
143
+ # r[:abs, true] = '/abs/path/to/dir'
144
+ # r[:abs] # => '/abs/path/to/dir'
167
145
  #
168
- # Note - the syntax for setting an absolute filepath requires an odd use []=.
146
+ #--
147
+ # The syntax for setting an absolute filepath requires an odd use []=.
169
148
  # In fact the method recieves the arguments (:dir, true, '/abs/path/to/dir')
170
149
  # rather than (:dir, '/abs/path/to/dir', true), meaning that internally path
171
150
  # and absolute are switched when setting an absolute filepath.
172
- def []=(dir, path, absolute=false)
173
- raise ArgumentError, "The directory key '#{dir}' is reserved." if dir.to_s == 'root'
151
+ #++
152
+ def []=(da, path, absolute=false)
153
+ raise ArgumentError, "The directory key '#{da}' is reserved." if da.to_s == 'root'
174
154
 
175
155
  # switch the paths if absolute was provided
176
156
  unless absolute == false
@@ -181,94 +161,76 @@ module Tap
181
161
 
182
162
  case
183
163
  when path.nil?
184
- @directories.delete(dir)
185
- @paths.delete(dir)
164
+ @directories.delete(da)
165
+ @paths.delete(da)
186
166
  when absolute
187
- @directories.delete(dir)
188
- @paths[dir] = path
167
+ @directories.delete(da)
168
+ @paths[da] = File.expand_path(path)
189
169
  else
190
- @directories[dir] = path
191
- @paths[dir] = File.join(root, path)
170
+ @directories[da] = path
171
+ @paths[da] = File.expand_path(File.join(root, path))
192
172
  end
193
173
  end
194
174
 
195
- # Returns the path to the specified directory. If the path has not been set,
196
- # then the path is inferred to be 'root/dir'.
197
- def [](dir)
198
- self.paths[dir] || File.join(root, dir.to_s)
175
+ # Returns the expanded path for the specified alias. If the alias
176
+ # has not been set, then the path is inferred to be 'root/da'.
177
+ #
178
+ # r = Root.new '/root_dir'
179
+ # r[:dir] = 'path/to/dir'
180
+ # r[:dir] # => '/root_dir/path/to/dir'
181
+ #
182
+ # r[:unset] = nil
183
+ # r[:unset] # => '/root_dir/unset'
184
+ #
185
+ def [](da)
186
+ self.paths[da] || File.expand_path(File.join(root, da.to_s))
199
187
  end
200
188
 
201
- # Constructs filepaths relative to the path of the specfied directory.
202
- def filepath(dir, *filename)
203
- File.join(self[dir], *filename)
189
+ # Constructs expanded filepaths relative to the path of the specified alias.
190
+ def filepath(da, *filename)
191
+ File.expand_path(File.join(self[da], *filename))
204
192
  end
205
193
 
206
- # Retrieves filepath relative to the path of the specified directory.
207
- def relative_filepath(dir, filepath, strict=true)
208
- Root.relative_filepath(self[dir], filepath, strict)
194
+ # Retrieves the filepath relative to the path of the specified alias.
195
+ def relative_filepath(da, filepath, strict=true)
196
+ Root.relative_filepath(self[da], filepath, strict)
209
197
  end
210
198
 
211
- # Generates a target filepath translated from the input directory to the output directory.
199
+ # Generates a target filepath translated from the aliased input dir to
200
+ # the aliased output dir. Raises an error if the filepath is not relative
201
+ # to the aliased input dir.
212
202
  #
213
- # translate("/input/dir/path/to/input.txt") # => "/output/dir/path/to/input.txt"
214
- def translate(filepath, input_dir, output_dir)
215
- filepath(output_dir, relative_filepath(input_dir, filepath))
203
+ # fp = r.filepath(:in, 'path/to/file.txt') # => '/root_dir/in/path/to/file.txt'
204
+ # r.translate(fp, :in, :out) # => '/root_dir/out/path/to/file.txt'
205
+ def translate(filepath, input_da, output_da)
206
+ filepath(output_da, relative_filepath(input_da, filepath))
216
207
  end
217
208
 
218
- # Lists all files in the specified dir matching the input patterns. Patterns should be valid inputs
219
- # for +Dir.glob+. If no patterns are specified, lists all files/folders matching '**/*'.
220
- def glob(dir, *patterns)
209
+ # Lists all files in the aliased dir matching the input patterns. Patterns
210
+ # should be valid inputs for +Dir.glob+. If no patterns are specified, lists
211
+ # all files/folders matching '**/*'.
212
+ def glob(da, *patterns)
221
213
  patterns << "**/*" if patterns.empty?
222
- patterns.collect! {|pattern| filepath(dir, pattern)}
214
+ patterns.collect! {|pattern| filepath(da, pattern)}
223
215
  Root.glob(*patterns)
224
216
  end
225
217
 
226
- # Lists all versions of filename in the specified dir matching the version patterns.
218
+ # Lists all versions of filename in the aliased dir matching the version patterns.
227
219
  # If no patterns are specified, then all versions of filename will be returned.
228
- def vglob(dir, filename, *vpatterns)
229
- Root.vglob(filepath(dir, filename), *vpatterns)
230
- end
231
-
232
- # Opens the file specfied by dir and filename, then passes the open file to the input block
233
- def open(dir, filename, mode_string="r", &block)
234
- File.open(filepath(dir, filename), mode_string, &block)
235
- end
236
-
237
- # Reads the specififed file
238
- def read(dir, filename)
239
- File.read( filepath(dir, filename) )
240
- end
241
-
242
- #
243
- def parse_by_line(dir, filename, options={}, &block)
244
- Root.parse_by_line( filepath(dir, filename), options, &block)
245
- end
246
-
247
- # The timestamp of the most recently modified file under dir. Returns nil
248
- # if none of the listed files are relative to dir.
249
- def mtime(dir, *filenames)
250
- filenames.collect do |fname|
251
- fname = relative_filepath(dir, fname, false)
252
- path = filepath(dir, fname)
253
-
254
- File.exists?(path) ? File.mtime(path) : nil
255
- end.compact.max
256
- end
257
-
258
- # Makes all the directories specified in paths. Parent directories are created as needed.
259
- def mkpaths
260
- paths.values.each { |dir| FileUtils.mkdir_p(dir) }
220
+ def vglob(da, filename, *vpatterns)
221
+ Root.vglob(filepath(da, filename), *vpatterns)
261
222
  end
262
223
 
263
224
  private
264
225
 
226
+ # reassigns all paths with the input root, directories, and absolute_paths
265
227
  def assign_paths(root, directories, absolute_paths)
266
- @root = root
228
+ @root = File.expand_path(root)
267
229
  @directories = {}
268
- @paths = {'root' => root, :root => root}
230
+ @paths = {'root' => @root, :root => @root}
269
231
 
270
- directories.each_pair {|dir, path| self[dir] = path }
271
- absolute_paths.each_pair {|dir, path| self[dir, true] = path }
232
+ directories.each_pair {|da, path| self[da] = path }
233
+ absolute_paths.each_pair {|da, path| self[da, true] = path }
272
234
  end
273
235
 
274
236
  end