necktie 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (214) hide show
  1. data/README.rdoc +174 -0
  2. data/bin/necktie +2 -1
  3. data/lib/necktie/files.rb +29 -0
  4. data/lib/necktie/rake.rb +127 -0
  5. data/lib/necktie/services.rb +11 -7
  6. data/lib/necktie.rb +4 -54
  7. data/necktie.gemspec +3 -3
  8. data/vendor/rake/CHANGES +477 -0
  9. data/vendor/rake/MIT-LICENSE +21 -0
  10. data/vendor/rake/README.rdoc +194 -0
  11. data/vendor/rake/Rakefile +421 -0
  12. data/vendor/rake/TODO +20 -0
  13. data/vendor/rake/bin/rake +31 -0
  14. data/vendor/rake/doc/command_line_usage.rdoc +102 -0
  15. data/vendor/rake/doc/example/Rakefile1 +38 -0
  16. data/vendor/rake/doc/example/Rakefile2 +35 -0
  17. data/vendor/rake/doc/example/a.c +6 -0
  18. data/vendor/rake/doc/example/b.c +6 -0
  19. data/vendor/rake/doc/example/main.c +11 -0
  20. data/vendor/rake/doc/glossary.rdoc +51 -0
  21. data/vendor/rake/doc/jamis.rb +591 -0
  22. data/vendor/rake/doc/proto_rake.rdoc +127 -0
  23. data/vendor/rake/doc/rake.1.gz +0 -0
  24. data/vendor/rake/doc/rakefile.rdoc +566 -0
  25. data/vendor/rake/doc/rational.rdoc +151 -0
  26. data/vendor/rake/doc/release_notes/rake-0.4.14.rdoc +23 -0
  27. data/vendor/rake/doc/release_notes/rake-0.4.15.rdoc +35 -0
  28. data/vendor/rake/doc/release_notes/rake-0.5.0.rdoc +53 -0
  29. data/vendor/rake/doc/release_notes/rake-0.5.3.rdoc +78 -0
  30. data/vendor/rake/doc/release_notes/rake-0.5.4.rdoc +46 -0
  31. data/vendor/rake/doc/release_notes/rake-0.6.0.rdoc +141 -0
  32. data/vendor/rake/doc/release_notes/rake-0.7.0.rdoc +119 -0
  33. data/vendor/rake/doc/release_notes/rake-0.7.1.rdoc +59 -0
  34. data/vendor/rake/doc/release_notes/rake-0.7.2.rdoc +121 -0
  35. data/vendor/rake/doc/release_notes/rake-0.7.3.rdoc +47 -0
  36. data/vendor/rake/doc/release_notes/rake-0.8.0.rdoc +114 -0
  37. data/vendor/rake/doc/release_notes/rake-0.8.2.rdoc +165 -0
  38. data/vendor/rake/doc/release_notes/rake-0.8.3.rdoc +112 -0
  39. data/vendor/rake/doc/release_notes/rake-0.8.4.rdoc +147 -0
  40. data/vendor/rake/doc/release_notes/rake-0.8.5.rdoc +53 -0
  41. data/vendor/rake/doc/release_notes/rake-0.8.6.rdoc +55 -0
  42. data/vendor/rake/doc/release_notes/rake-0.8.7.rdoc +55 -0
  43. data/vendor/rake/install.rb +88 -0
  44. data/vendor/rake/lib/rake/alt_system.rb +108 -0
  45. data/vendor/rake/lib/rake/application.rb +579 -0
  46. data/vendor/rake/lib/rake/classic_namespace.rb +9 -0
  47. data/vendor/rake/lib/rake/clean.rb +35 -0
  48. data/vendor/rake/lib/rake/cloneable.rb +25 -0
  49. data/vendor/rake/lib/rake/contrib/compositepublisher.rb +24 -0
  50. data/vendor/rake/lib/rake/contrib/ftptools.rb +153 -0
  51. data/vendor/rake/lib/rake/contrib/publisher.rb +75 -0
  52. data/vendor/rake/lib/rake/contrib/rubyforgepublisher.rb +18 -0
  53. data/vendor/rake/lib/rake/contrib/sshpublisher.rb +47 -0
  54. data/vendor/rake/lib/rake/contrib/sys.rb +209 -0
  55. data/vendor/rake/lib/rake/default_loader.rb +10 -0
  56. data/vendor/rake/lib/rake/dsl.rb +136 -0
  57. data/vendor/rake/lib/rake/early_time.rb +18 -0
  58. data/vendor/rake/lib/rake/environment.rb +40 -0
  59. data/vendor/rake/lib/rake/ext/module.rb +60 -0
  60. data/vendor/rake/lib/rake/ext/string.rb +165 -0
  61. data/vendor/rake/lib/rake/ext/time.rb +14 -0
  62. data/vendor/rake/lib/rake/file_creation_task.rb +24 -0
  63. data/vendor/rake/lib/rake/file_list.rb +395 -0
  64. data/vendor/rake/lib/rake/file_task.rb +47 -0
  65. data/vendor/rake/lib/rake/file_utils.rb +108 -0
  66. data/vendor/rake/lib/rake/gempackagetask.rb +97 -0
  67. data/vendor/rake/lib/rake/invocation_chain.rb +51 -0
  68. data/vendor/rake/lib/rake/invocation_exception_mixin.rb +16 -0
  69. data/vendor/rake/lib/rake/lib/project.rake +24 -0
  70. data/vendor/rake/lib/rake/loaders/makefile.rb +44 -0
  71. data/vendor/rake/lib/rake/multi_task.rb +16 -0
  72. data/vendor/rake/lib/rake/name_space.rb +25 -0
  73. data/vendor/rake/lib/rake/packagetask.rb +184 -0
  74. data/vendor/rake/lib/rake/psuedo_status.rb +24 -0
  75. data/vendor/rake/lib/rake/rake_file_utils.rb +133 -0
  76. data/vendor/rake/lib/rake/rake_module.rb +25 -0
  77. data/vendor/rake/lib/rake/rake_test_loader.rb +15 -0
  78. data/vendor/rake/lib/rake/rdoctask.rb +209 -0
  79. data/vendor/rake/lib/rake/ruby182_test_unit_fix.rb +25 -0
  80. data/vendor/rake/lib/rake/rule_recursion_overflow_error.rb +20 -0
  81. data/vendor/rake/lib/rake/runtest.rb +23 -0
  82. data/vendor/rake/lib/rake/task.rb +318 -0
  83. data/vendor/rake/lib/rake/task_argument_error.rb +7 -0
  84. data/vendor/rake/lib/rake/task_arguments.rb +78 -0
  85. data/vendor/rake/lib/rake/task_manager.rb +328 -0
  86. data/vendor/rake/lib/rake/tasklib.rb +24 -0
  87. data/vendor/rake/lib/rake/testtask.rb +175 -0
  88. data/vendor/rake/lib/rake/win32.rb +55 -0
  89. data/vendor/rake/lib/rake.rb +72 -0
  90. data/vendor/rake/rake.blurb +19 -0
  91. data/vendor/rake/rake.gemspec +214 -0
  92. data/vendor/rake/rakelib/extra.rake +8 -0
  93. data/vendor/rake/rakelib/publish.rake +22 -0
  94. data/vendor/rake/rakelib/rbx.rake +82 -0
  95. data/vendor/rake/rakelib/ruby19.rake +88 -0
  96. data/vendor/rake/rakelib/tags.rake +18 -0
  97. data/vendor/rake/test/capture_stdout.rb +26 -0
  98. data/vendor/rake/test/check_expansion.rb +5 -0
  99. data/vendor/rake/test/check_no_expansion.rb +5 -0
  100. data/vendor/rake/test/contrib/test_sys.rb +47 -0
  101. data/vendor/rake/test/data/chains/Rakefile +15 -0
  102. data/vendor/rake/test/data/comments/Rakefile +18 -0
  103. data/vendor/rake/test/data/default/Rakefile +19 -0
  104. data/vendor/rake/test/data/dryrun/Rakefile +22 -0
  105. data/vendor/rake/test/data/file_creation_task/Rakefile +33 -0
  106. data/vendor/rake/test/data/imports/Rakefile +19 -0
  107. data/vendor/rake/test/data/imports/deps.mf +1 -0
  108. data/vendor/rake/test/data/multidesc/Rakefile +17 -0
  109. data/vendor/rake/test/data/namespace/Rakefile +66 -0
  110. data/vendor/rake/test/data/nosearch/dummy +1 -0
  111. data/vendor/rake/test/data/rakelib/test1.rb +5 -0
  112. data/vendor/rake/test/data/rakelib/test2.rake +3 -0
  113. data/vendor/rake/test/data/rbext/rakefile.rb +3 -0
  114. data/vendor/rake/test/data/sample.mf +14 -0
  115. data/vendor/rake/test/data/statusreturn/Rakefile +8 -0
  116. data/vendor/rake/test/data/sys/sys1.rake +3 -0
  117. data/vendor/rake/test/data/unittest/Rakefile +1 -0
  118. data/vendor/rake/test/data/unittest/subdir/README +0 -0
  119. data/vendor/rake/test/data/verbose/Rakefile +34 -0
  120. data/vendor/rake/test/filecreation.rb +32 -0
  121. data/vendor/rake/test/functional/functional_test.rb +15 -0
  122. data/vendor/rake/test/functional/session_based_tests.rb +442 -0
  123. data/vendor/rake/test/in_environment.rb +32 -0
  124. data/vendor/rake/test/lib/application_test.rb +769 -0
  125. data/vendor/rake/test/lib/clean_test.rb +15 -0
  126. data/vendor/rake/test/lib/definitions_test.rb +85 -0
  127. data/vendor/rake/test/lib/dsl_test.rb +41 -0
  128. data/vendor/rake/test/lib/earlytime_test.rb +35 -0
  129. data/vendor/rake/test/lib/environment_test.rb +18 -0
  130. data/vendor/rake/test/lib/extension_test.rb +63 -0
  131. data/vendor/rake/test/lib/file_creation_task_test.rb +62 -0
  132. data/vendor/rake/test/lib/file_task_test.rb +143 -0
  133. data/vendor/rake/test/lib/filelist_test.rb +623 -0
  134. data/vendor/rake/test/lib/fileutils_test.rb +251 -0
  135. data/vendor/rake/test/lib/ftp_test.rb +59 -0
  136. data/vendor/rake/test/lib/invocation_chain_test.rb +81 -0
  137. data/vendor/rake/test/lib/makefile_loader_test.rb +26 -0
  138. data/vendor/rake/test/lib/multitask_test.rb +53 -0
  139. data/vendor/rake/test/lib/namespace_test.rb +55 -0
  140. data/vendor/rake/test/lib/package_task_test.rb +118 -0
  141. data/vendor/rake/test/lib/pathmap_test.rb +210 -0
  142. data/vendor/rake/test/lib/pseudo_status_test.rb +26 -0
  143. data/vendor/rake/test/lib/rake_test.rb +41 -0
  144. data/vendor/rake/test/lib/rdoc_task_test.rb +88 -0
  145. data/vendor/rake/test/lib/require_test.rb +35 -0
  146. data/vendor/rake/test/lib/rules_test.rb +349 -0
  147. data/vendor/rake/test/lib/task_arguments_test.rb +89 -0
  148. data/vendor/rake/test/lib/task_manager_test.rb +173 -0
  149. data/vendor/rake/test/lib/task_test.rb +376 -0
  150. data/vendor/rake/test/lib/tasklib_test.rb +12 -0
  151. data/vendor/rake/test/lib/test_task_test.rb +77 -0
  152. data/vendor/rake/test/lib/testtask_test.rb +49 -0
  153. data/vendor/rake/test/lib/top_level_functions_test.rb +86 -0
  154. data/vendor/rake/test/lib/win32_test.rb +72 -0
  155. data/vendor/rake/test/rake_test_setup.rb +24 -0
  156. data/vendor/rake/test/reqfile.rb +3 -0
  157. data/vendor/rake/test/reqfile2.rb +3 -0
  158. data/vendor/rake/test/reqfile3.rake +3 -0
  159. data/vendor/rake/test/shellcommand.rb +3 -0
  160. data/vendor/rake/test/test_helper.rb +13 -0
  161. metadata +212 -56
  162. /data/{rush → vendor/rush}/README.rdoc +0 -0
  163. /data/{rush → vendor/rush}/Rakefile +0 -0
  164. /data/{rush → vendor/rush}/VERSION +0 -0
  165. /data/{rush → vendor/rush}/bin/rush +0 -0
  166. /data/{rush → vendor/rush}/bin/rushd +0 -0
  167. /data/{rush → vendor/rush}/lib/rush/access.rb +0 -0
  168. /data/{rush → vendor/rush}/lib/rush/array_ext.rb +0 -0
  169. /data/{rush → vendor/rush}/lib/rush/box.rb +0 -0
  170. /data/{rush → vendor/rush}/lib/rush/commands.rb +0 -0
  171. /data/{rush → vendor/rush}/lib/rush/config.rb +0 -0
  172. /data/{rush → vendor/rush}/lib/rush/dir.rb +0 -0
  173. /data/{rush → vendor/rush}/lib/rush/embeddable_shell.rb +0 -0
  174. /data/{rush → vendor/rush}/lib/rush/entry.rb +0 -0
  175. /data/{rush → vendor/rush}/lib/rush/exceptions.rb +0 -0
  176. /data/{rush → vendor/rush}/lib/rush/file.rb +0 -0
  177. /data/{rush → vendor/rush}/lib/rush/find_by.rb +0 -0
  178. /data/{rush → vendor/rush}/lib/rush/fixnum_ext.rb +0 -0
  179. /data/{rush → vendor/rush}/lib/rush/head_tail.rb +0 -0
  180. /data/{rush → vendor/rush}/lib/rush/local.rb +0 -0
  181. /data/{rush → vendor/rush}/lib/rush/process.rb +0 -0
  182. /data/{rush → vendor/rush}/lib/rush/process_set.rb +0 -0
  183. /data/{rush → vendor/rush}/lib/rush/remote.rb +0 -0
  184. /data/{rush → vendor/rush}/lib/rush/search_results.rb +0 -0
  185. /data/{rush → vendor/rush}/lib/rush/server.rb +0 -0
  186. /data/{rush → vendor/rush}/lib/rush/shell.rb +0 -0
  187. /data/{rush → vendor/rush}/lib/rush/ssh_tunnel.rb +0 -0
  188. /data/{rush → vendor/rush}/lib/rush/string_ext.rb +0 -0
  189. /data/{rush → vendor/rush}/lib/rush.rb +0 -0
  190. /data/{rush → vendor/rush}/rush.gemspec +0 -0
  191. /data/{rush → vendor/rush}/spec/access_spec.rb +0 -0
  192. /data/{rush → vendor/rush}/spec/array_ext_spec.rb +0 -0
  193. /data/{rush → vendor/rush}/spec/base.rb +0 -0
  194. /data/{rush → vendor/rush}/spec/box_spec.rb +0 -0
  195. /data/{rush → vendor/rush}/spec/commands_spec.rb +0 -0
  196. /data/{rush → vendor/rush}/spec/config_spec.rb +0 -0
  197. /data/{rush → vendor/rush}/spec/dir_spec.rb +0 -0
  198. /data/{rush → vendor/rush}/spec/embeddable_shell_spec.rb +0 -0
  199. /data/{rush → vendor/rush}/spec/entry_spec.rb +0 -0
  200. /data/{rush → vendor/rush}/spec/file_spec.rb +0 -0
  201. /data/{rush → vendor/rush}/spec/find_by_spec.rb +0 -0
  202. /data/{rush → vendor/rush}/spec/fixnum_ext_spec.rb +0 -0
  203. /data/{rush → vendor/rush}/spec/local_spec.rb +0 -0
  204. /data/{rush → vendor/rush}/spec/process_set_spec.rb +0 -0
  205. /data/{rush → vendor/rush}/spec/process_spec.rb +0 -0
  206. /data/{rush → vendor/rush}/spec/remote_spec.rb +0 -0
  207. /data/{rush → vendor/rush}/spec/rush_spec.rb +0 -0
  208. /data/{rush → vendor/rush}/spec/search_results_spec.rb +0 -0
  209. /data/{rush → vendor/rush}/spec/shell_spec.rb +0 -0
  210. /data/{rush → vendor/rush}/spec/ssh_tunnel_spec.rb +0 -0
  211. /data/{rush → vendor/rush}/spec/string_ext_spec.rb +0 -0
  212. /data/{session → vendor/session}/lib/session-2.4.0.rb +0 -0
  213. /data/{session → vendor/session}/lib/session.rb +0 -0
  214. /data/{session → vendor/session}/test/session.rb +0 -0
@@ -0,0 +1,127 @@
1
+ = Original Prototype Rake
2
+
3
+ This is the original 100 line prototype rake program.
4
+
5
+ ---
6
+ #!/usr/bin/env ruby
7
+
8
+ require 'ftools'
9
+
10
+ class Task
11
+ TASKS = Hash.new
12
+
13
+ attr_reader :prerequisites
14
+
15
+ def initialize(task_name)
16
+ @name = task_name
17
+ @prerequisites = []
18
+ @actions = []
19
+ end
20
+
21
+ def enhance(deps=nil, &block)
22
+ @prerequisites |= deps if deps
23
+ @actions << block if block_given?
24
+ self
25
+ end
26
+
27
+ def name
28
+ @name.to_s
29
+ end
30
+
31
+ def invoke
32
+ @prerequisites.each { |n| Task[n].invoke }
33
+ execute if needed?
34
+ end
35
+
36
+ def execute
37
+ return if @triggered
38
+ @triggered = true
39
+ @actions.collect { |act| result = act.call(self) }.last
40
+ end
41
+
42
+ def needed?
43
+ true
44
+ end
45
+
46
+ def timestamp
47
+ Time.now
48
+ end
49
+
50
+ class << self
51
+ def [](task_name)
52
+ TASKS[intern(task_name)] or fail "Don't know how to rake #{task_name}"
53
+ end
54
+
55
+ def define_task(args, &block)
56
+ case args
57
+ when Hash
58
+ fail "Too Many Target Names: #{args.keys.join(' ')}" if args.size > 1
59
+ fail "No Task Name Given" if args.size < 1
60
+ task_name = args.keys[0]
61
+ deps = args[task_name]
62
+ else
63
+ task_name = args
64
+ deps = []
65
+ end
66
+ deps = deps.collect {|d| intern(d) }
67
+ get(task_name).enhance(deps, &block)
68
+ end
69
+
70
+ def get(task_name)
71
+ name = intern(task_name)
72
+ TASKS[name] ||= self.new(name)
73
+ end
74
+
75
+ def intern(task_name)
76
+ (Symbol === task_name) ? task_name : task_name.intern
77
+ end
78
+ end
79
+ end
80
+
81
+ class FileTask < Task
82
+ def needed?
83
+ return true unless File.exist?(name)
84
+ latest_prereq = @prerequisites.collect{|n| Task[n].timestamp}.max
85
+ return false if latest_prereq.nil?
86
+ timestamp < latest_prereq
87
+ end
88
+
89
+ def timestamp
90
+ File.new(name.to_s).mtime
91
+ end
92
+ end
93
+
94
+ def task(args, &block)
95
+ Task.define_task(args, &block)
96
+ end
97
+
98
+ def file(args, &block)
99
+ FileTask.define_task(args, &block)
100
+ end
101
+
102
+ def sys(cmd)
103
+ puts cmd
104
+ system(cmd) or fail "Command Failed: [#{cmd}]"
105
+ end
106
+
107
+ def rake
108
+ begin
109
+ here = Dir.pwd
110
+ while ! File.exist?("Rakefile")
111
+ Dir.chdir("..")
112
+ fail "No Rakefile found" if Dir.pwd == here
113
+ here = Dir.pwd
114
+ end
115
+ puts "(in #{Dir.pwd})"
116
+ load "./Rakefile"
117
+ ARGV.push("default") if ARGV.size == 0
118
+ ARGV.each { |task_name| Task[task_name].invoke }
119
+ rescue Exception => ex
120
+ puts "rake aborted ... #{ex.message}"
121
+ puts ex.backtrace.find {|str| str =~ /Rakefile/ } || ""
122
+ end
123
+ end
124
+
125
+ if __FILE__ == $0 then
126
+ rake
127
+ end
Binary file
@@ -0,0 +1,566 @@
1
+ = Rakefile Format (as of version 0.8.7)
2
+
3
+ First of all, there is no special format for a Rakefile. A Rakefile
4
+ contains executable Ruby code. Anything legal in a ruby script is
5
+ allowed in a Rakefile.
6
+
7
+ Now that we understand there is no special syntax in a Rakefile, there
8
+ are some conventions that are used in a Rakefile that are a little
9
+ unusual in a typical Ruby program. Since a Rakefile is tailored to
10
+ specifying tasks and actions, the idioms used in a Rakefile are
11
+ designed to support that.
12
+
13
+ So, what goes into a Rakefile?
14
+
15
+ == Tasks
16
+
17
+ Tasks are the main unit of work in a Rakefile. Tasks have a name
18
+ (usually given as a symbol or a string), a list of prerequisites (more
19
+ symbols or strings) and a list of actions (given as a block).
20
+
21
+ === Simple Tasks
22
+
23
+ A task is declared by using the +task+ method. +task+ takes a single
24
+ parameter that is the name of the task.
25
+
26
+ task :name
27
+
28
+ === Tasks with Prerequisites
29
+
30
+ Any prerequisites are given as a list (inclosed in square brackets)
31
+ following the name and an arrow (=>).
32
+
33
+ task :name => [:prereq1, :prereq2]
34
+
35
+ <b>NOTE:</b> Although this syntax looks a little funky, it is legal
36
+ Ruby. We are constructing a hash where the key is :name and the value
37
+ for that key is the list of prerequisites. It is equivalent to the
38
+ following ...
39
+
40
+ hash = Hash.new
41
+ hash[:name] = [:prereq1, :prereq2]
42
+ task(hash)
43
+
44
+ === Tasks with Actions
45
+
46
+ Actions are defined by passing a block to the +task+ method. Any Ruby
47
+ code can be placed in the block. The block may reference the task
48
+ object via the block paramter..
49
+
50
+ task :name => [:prereq1, :prereq2] do |t|
51
+ # actions (may reference t)
52
+ end
53
+
54
+ === Multiple Definitions
55
+
56
+ A task may be specified more than once. Each specification adds its
57
+ prerequisites and actions to the existing definition. This allows one
58
+ part of a rakefile to specify the actions and a different rakefile
59
+ (perhaps separately generated) to specify the dependencies.
60
+
61
+ For example, the following is equivalent to the single task
62
+ specification given above.
63
+
64
+ task :name
65
+ task :name => [:prereq1]
66
+ task :name => [:prereq2]
67
+ task :name do |t|
68
+ # actions
69
+ end
70
+
71
+ == File Tasks
72
+
73
+ Some tasks are designed to create a file from one or more other files.
74
+ Tasks that generate these files may be skipped if the file already
75
+ exists. File tasks are used to specify file creation tasks.
76
+
77
+ File tasks are declared using the +file+ method (instead of the +task+
78
+ method). In addition, file tasks are usually named with a string
79
+ rather than a symbol.
80
+
81
+ The following file task creates a executable program (named +prog+)
82
+ given two object files name <tt>a.o</tt> and <tt>b.o</tt>. The tasks
83
+ for creating <tt>a.o</tt> and <tt>b.o</tt> are not shown.
84
+
85
+ file "prog" => ["a.o", "b.o"] do |t|
86
+ sh "cc -o #{t.name} #{t.prerequisites.join(' ')}"
87
+ end
88
+
89
+ == Directory Tasks
90
+
91
+ It is common to need to create directories upon demand. The
92
+ +directory+ convenience method is a short-hand for creating a FileTask
93
+ that creates the directory. For example, the following declaration
94
+ ...
95
+
96
+ directory "testdata/examples/doc"
97
+
98
+ is equivalent to ...
99
+
100
+ file "testdata" do |t| mkdir t.name end
101
+ file "testdata/examples" do |t| mkdir t.name end
102
+ file "testdata/examples/doc" do |t| mkdir t.name end
103
+
104
+ The +directory+ method does not accept prerequisites or actions, but
105
+ both prerequisites and actions can be added later. For example ...
106
+
107
+ directory "testdata"
108
+ file "testdata" => ["otherdata"]
109
+ file "testdata" do
110
+ cp Dir["standard_data/*.data"], "testdata"
111
+ end
112
+
113
+ == Tasks with Parallel Prerequisites
114
+
115
+ Rake allows parallel execution of prerequisites using the following syntax:
116
+
117
+ multitask :copy_files => [:copy_src, :copy_doc, :copy_bin] do
118
+ puts "All Copies Complete"
119
+ end
120
+
121
+ In this example, +copy_files+ is a normal rake task. Its actions are
122
+ executed whereever all of its prerequisites are done. The big
123
+ difference is that the prerequisites (+copy_src+, +copy_bin+ and
124
+ +copy_doc+) are executed in parallel. Each of the prerequisites are
125
+ run in their own Ruby thread, possibly allowing faster overall runtime.
126
+
127
+ === Secondary Prerequisites
128
+
129
+ If any of the primary prerequites of a multitask have common secondary
130
+ prerequisites, all of the primary/parallel prerequisites will wait
131
+ until the common prerequisites have been run.
132
+
133
+ For example, if the <tt>copy_<em>xxx</em></tt> tasks have the
134
+ following prerequisites:
135
+
136
+ task :copy_src => [:prep_for_copy]
137
+ task :copy_bin => [:prep_for_copy]
138
+ task :copy_doc => [:prep_for_copy]
139
+
140
+ Then the +prep_for_copy+ task is run before starting all the copies in
141
+ parallel. Once +prep_for_copy+ is complete, +copy_src+, +copy_bin+,
142
+ and +copy_doc+ are all run in parallel. Note that +prep_for_copy+ is
143
+ run only once, even though it is referenced in multiple threads.
144
+
145
+ === Thread Safety
146
+
147
+ The Rake internal data structures are thread-safe with respect
148
+ to the multitask parallel execution, so there is no need for the user
149
+ to do extra synchronization for Rake's benefit. However, if there are
150
+ user data structures shared between the parallel prerequisites, the
151
+ user must do whatever is necessary to prevent race conditions.
152
+
153
+ == Tasks with Arguments
154
+
155
+ Prior to version 0.8.0, rake was only able to handle command line
156
+ arguments of the form NAME=VALUE that were passed into Rake via the
157
+ ENV hash. Many folks had asked for some kind of simple command line
158
+ arguments, perhaps using "--" to separate regular task names from
159
+ argument values on the command line. The problem is that there was no
160
+ easy way to associate positional arguments on the command line with
161
+ different tasks. Suppose both tasks :a and :b expect a command line
162
+ argument: does the first value go with :a? What if :b is run first?
163
+ Should it then get the first command line argument.
164
+
165
+ Rake 0.8.0 solves this problem by explicitly passing values directly
166
+ to the tasks that need them. For example, if I had a release task
167
+ that required a version number, I could say:
168
+
169
+ rake release[0.8.2]
170
+
171
+ And the string "0.8.2" will be passed to the :release task. Multiple
172
+ arguments can be passed by separating them with a comma, for example:
173
+
174
+ rake name[john,doe]
175
+
176
+ Just a few words of caution. The rake task name and its arguments
177
+ need to be a single command line argument to rake. This generally
178
+ means no spaces. If spaces are needed, then the entire rake +
179
+ argument string should be quoted. Something like this:
180
+
181
+ rake "name[billy bob, smith]"
182
+
183
+ (Quoting rules vary between operating systems and shells, so make sure
184
+ you consult the proper docs for your OS/shell).
185
+
186
+ === Tasks Arguments and the Environment
187
+
188
+ Task argument values can also be picked up from the environment. For
189
+ example, if the "release" task expected a parameter named
190
+ "release_version", then either
191
+
192
+ rake release[0.8.2]
193
+
194
+ or
195
+
196
+ RELEASE_VERSION rake release
197
+
198
+ will work. Environment variable names must either match the task
199
+ parameter exactly, or match an all uppcase version of the task
200
+ parameter.
201
+
202
+ === Tasks that Expect Parameters
203
+
204
+ Parameters are only given to tasks that are setup to expect them. In
205
+ order to handle named parameters, the task declaration syntax for
206
+ tasks has been extended slightly.
207
+
208
+ For example, a task that needs a first name and last name might be
209
+ declared as:
210
+
211
+ task :name, [:first_name, :last_name]
212
+
213
+ The first argument is still the name of the task (:name in this case).
214
+ The next to argumements are the names of the parameters expected by
215
+ :name in an array (:first_name and :last_name in the example).
216
+
217
+ To access the values of the paramters, the block defining the task
218
+ behaviour can now accept a second parameter:
219
+
220
+ task :name, [:first_name, :last_name] do |t, args|
221
+ puts "First name is #{args.first_name}"
222
+ puts "Last name is #{args.last_name}"
223
+ end
224
+
225
+ The first argument of the block "t" is always bound to the current
226
+ task object. The second argument "args" is an open-struct like object
227
+ that allows access to the task arguments. Extra command line
228
+ arguments to a task are ignored. Missing command line arguments are
229
+ picked up from matching environment variables. If there are no
230
+ matching environment variables, they are given the nil value.
231
+
232
+ If you wish to specify default values for the arguments, you can use
233
+ the with_defaults method in the task body. Here is the above example
234
+ where we specify default values for the first and last names:
235
+
236
+ task :name, [:first_name, :last_name] do |t, args|
237
+ args.with_defaults(:first_name => "John", :last_name => "Dough")
238
+ puts "First name is #{args.first_name}"
239
+ puts "Last name is #{args.last_name}"
240
+ end
241
+
242
+ === Tasks that Expect Parameters and Have Prerequisites
243
+
244
+ Tasks that use parameters have a slightly different format for
245
+ prerequisites. Use the arrow notation to indicate the prerequisites
246
+ for tasks with arguments. For example:
247
+
248
+ task :name, [:first_name, :last_name] => [:pre_name] do |t, args|
249
+ args.with_defaults(:first_name => "John", :last_name => "Dough")
250
+ puts "First name is #{args.first_name}"
251
+ puts "Last name is #{args.last_name}"
252
+ end
253
+
254
+ === Deprecated Task Parameters Format
255
+
256
+ There is an older format for declaring task parameters that omitted
257
+ the task argument array and used the :needs keyword to introduce the
258
+ dependencies. That format is still supported for compatibility, but
259
+ is not recommended for use. The older format may be dropped in future
260
+ versions of rake.
261
+
262
+ == Accessing Task Programatically
263
+
264
+ Sometimes it is useful to manipulate tasks programatically in a
265
+ Rakefile. To find a task object, use the <tt>:[]</tt> operator on the
266
+ <tt>Rake::Task</tt>.
267
+
268
+ === Programmatic Task Example
269
+
270
+ For example, the following Rakefile defines two tasks. The :doit task
271
+ simply prints a simple "DONE" message. The :dont class will lookup
272
+ the doit class and remove (clear) all of its prerequisites and
273
+ actions.
274
+
275
+ task :doit do
276
+ puts "DONE"
277
+ end
278
+
279
+ task :dont do
280
+ Rake::Task[:doit].clear
281
+ end
282
+
283
+ Running this example:
284
+
285
+ $ rake doit
286
+ (in /Users/jim/working/git/rake/x)
287
+ DONE
288
+ $ rake dont doit
289
+ (in /Users/jim/working/git/rake/x)
290
+ $
291
+
292
+ The ability to programmatically manipulate tasks gives rake very
293
+ powerful meta-programming capabilities w.r.t. task execution, but
294
+ should be used with cation.
295
+
296
+ == Rules
297
+
298
+ When a file is named as a prerequisite, but does not have a file task
299
+ defined for it, Rake will attempt to synthesize a task by looking at a
300
+ list of rules supplied in the Rakefile.
301
+
302
+ Suppose we were trying to invoke task "mycode.o", but no task is
303
+ defined for it. But the rakefile has a rule that look like this ...
304
+
305
+ rule '.o' => ['.c'] do |t|
306
+ sh "cc #{t.source} -c -o #{t.name}"
307
+ end
308
+
309
+ This rule will synthesize any task that ends in ".o". It has a
310
+ prerequisite a source file with an extension of ".c" must exist. If
311
+ Rake is able to find a file named "mycode.c", it will automatically
312
+ create a task that builds "mycode.o" from "mycode.c".
313
+
314
+ If the file "mycode.c" does not exist, rake will attempt
315
+ to recursively synthesize a rule for it.
316
+
317
+ When a task is synthesized from a rule, the +source+ attribute of the
318
+ task is set to the matching source file. This allows us to write
319
+ rules with actions that reference the source file.
320
+
321
+ === Advanced Rules
322
+
323
+ Any regular expression may be used as the rule pattern. Additionally,
324
+ a proc may be used to calculate the name of the source file. This
325
+ allows for complex patterns and sources.
326
+
327
+ The following rule is equivalent to the example above.
328
+
329
+ rule( /\.o$/ => [
330
+ proc {|task_name| task_name.sub(/\.[^.]+$/, '.c') }
331
+ ]) do |t|
332
+ sh "cc #{t.source} -c -o #{t.name}"
333
+ end
334
+
335
+ <b>NOTE:</b> Because of a _quirk_ in Ruby syntax, parenthesis are
336
+ required on *rule* when the first argument is a regular expression.
337
+
338
+ The following rule might be used for Java files ...
339
+
340
+ rule '.java' => [
341
+ proc { |tn| tn.sub(/\.class$/, '.java').sub(/^classes\//, 'src/') }
342
+ ] do |t|
343
+ java_compile(t.source, t.name)
344
+ end
345
+
346
+ <b>NOTE:</b> +java_compile+ is a hypothetical method that invokes the
347
+ java compiler.
348
+
349
+ == Importing Dependencies
350
+
351
+ Any ruby file (including other rakefiles) can be included with a
352
+ standard Ruby +require+ command. The rules and declarations in the
353
+ required file are just added to the definitions already accumulated.
354
+
355
+ Because the files are loaded _before_ the rake targets are evaluated,
356
+ the loaded files must be "ready to go" when the rake command is
357
+ invoked. This make generated dependency files difficult to use. By
358
+ the time rake gets around to updating the dependencies file, it is too
359
+ late to load it.
360
+
361
+ The +import+ command addresses this by specifying a file to be loaded
362
+ _after_ the main rakefile is loaded, but _before_ any targets on the
363
+ command line are specified. In addition, if the file name matches an
364
+ explicit task, that task is invoked before loading the file. This
365
+ allows dependency files to be generated and used in a single rake
366
+ command invocation.
367
+
368
+ === Example:
369
+
370
+ require 'rake/loaders/makefile'
371
+
372
+ file ".depends.mf" => [SRC_LIST] do |t|
373
+ sh "makedepend -f- -- #{CFLAGS} -- #{t.prerequisites} > #{t.name}"
374
+ end
375
+
376
+ import ".depends.mf"
377
+
378
+ If ".depends" does not exist, or is out of date w.r.t. the source
379
+ files, a new ".depends" file is generated using +makedepend+ before
380
+ loading.
381
+
382
+ == Comments
383
+
384
+ Standard Ruby comments (beginning with "#") can be used anywhere it is
385
+ legal in Ruby source code, including comments for tasks and rules.
386
+ A single-line comment immediately before a task (with no blank line
387
+ between it and the task) will be used as that task's description, and
388
+ the task and description will appear in the list displayed
389
+ using the "-T" switch.
390
+
391
+ === Example:
392
+
393
+ # Create a distribution package
394
+ task :package => [ ... ] do ... end
395
+
396
+ You can also use the +desc+ command before a task to set the
397
+ description for the task. In this case, intervening blank lines
398
+ are allowed
399
+
400
+ === Example:
401
+
402
+ desc 'Create a distribution package'
403
+
404
+ task :package => [ ... ] do ... end
405
+
406
+ The +desc+ comment takes priority over the comment for of description.
407
+
408
+ The "-T" switch (or "--tasks" if you like to spell things out) will
409
+ display a list of tasks that have a description. If you use
410
+ comments or +desc+ to describe your major tasks, you have a
411
+ semi-automatic way of generating a summary of your Rake file.
412
+
413
+ traken$ rake -T
414
+ (in /home/.../rake)
415
+ rake clean # Remove any temporary products.
416
+ rake clobber # Remove any generated file.
417
+ rake clobber_rdoc # Remove rdoc products
418
+ rake contrib_test # Run tests for contrib_test
419
+ rake default # Default Task
420
+ rake install # Install the application
421
+ rake lines # Count lines in the main rake file
422
+ rake rdoc # Build the rdoc HTML Files
423
+ rake rerdoc # Force a rebuild of the RDOC files
424
+ rake test # Run tests
425
+ rake testall # Run all test targets
426
+
427
+ Only tasks with descriptions will be displayed with the "-T" switch.
428
+ Use "-P" (or "--prereqs") to get a list of all tasks and their
429
+ prerequisites.
430
+
431
+ == Namespaces
432
+
433
+ As projects grow (and along with it, the number of tasks), it is
434
+ common for task names to begin to clash. For example, if you might
435
+ have a main program and a set of sample programs built by a single
436
+ Rakefile. By placing the tasks related to the main program in one
437
+ namespace, and the tasks for building the sample programs in a
438
+ different namespace, the task names will not will not interfer with
439
+ each other.
440
+
441
+ For example:
442
+
443
+ namespace "main"
444
+ task :build do
445
+ # Build the main program
446
+ end
447
+ end
448
+
449
+ namespace "samples" do
450
+ task :build do
451
+ # Build the sample programs
452
+ end
453
+ end
454
+
455
+ task :build => ["main:build", "samples:build"]
456
+
457
+ Referencing a task in a separate namespace can be achieved by
458
+ prefixing the task name with the namespace and a colon
459
+ (e.g. "main:build" refers to the :build task in the +main+ namespace).
460
+ Nested namespaces are supported, so
461
+
462
+ Note that the name given in the +task+ command is always the unadorned
463
+ task name without any namespace prefixes. The +task+ command always
464
+ defines a task in the current namespace.
465
+
466
+ === FileTasks
467
+
468
+ File task names are not scoped by the namespace command. Since the
469
+ name of a file task is the name of an actual file in the file system,
470
+ it makes little sense to include file task names in name space.
471
+ Directory tasks (created by the +directory+ command) are a type of
472
+ file task and are also not affected by namespaces.
473
+
474
+ === Name Resolution
475
+
476
+ When looking up a task name, rake will start with the current
477
+ namespace and attempt to find the name there. If it fails to find a
478
+ name in the current namespace, it will search the parent namespaces
479
+ until a match is found (or an error occurs if there is no match).
480
+
481
+ The "rake" namespace is a special implicit namespace that refers to
482
+ the toplevel names.
483
+
484
+ If a task name begins with a "^" character, the name resolution will
485
+ start in the parent namespace. Multiple "^" characters are allowed.
486
+
487
+ Here is an example file with multiple :run tasks and how various names
488
+ resolve in different locations.
489
+
490
+ task :run
491
+
492
+ namespace "one" do
493
+ task :run
494
+
495
+ namespace "two" do
496
+ task :run
497
+
498
+ # :run => "one:two:run"
499
+ # "two:run" => "one:two:run"
500
+ # "one:two:run" => "one:two:run"
501
+ # "one:run" => "one:run"
502
+ # "^run" => "one:run"
503
+ # "^^run" => "rake:run" (the top level task)
504
+ # "rake:run" => "rake:run" (the top level task)
505
+ end
506
+
507
+ # :run => "one:run"
508
+ # "two:run" => "one:two:run"
509
+ # "^run" => "rake:run"
510
+ end
511
+
512
+ # :run => "rake:run"
513
+ # "one:run" => "one:run"
514
+ # "one:two:run" => "one:two:run"
515
+
516
+ == FileLists
517
+
518
+ FileLists are the way Rake manages lists of files. You can treat a
519
+ FileList as an array of strings for the most part, but FileLists
520
+ support some additional operations.
521
+
522
+ === Creating a FileList
523
+
524
+ Creating a file list is easy. Just give it the list of file names:
525
+
526
+ fl = FileList['file1.rb', file2.rb']
527
+
528
+ Or give it a glob pattern:
529
+
530
+ fl = FileList['*.rb']
531
+
532
+ == Odds and Ends
533
+
534
+ === do/end verses { }
535
+
536
+ Blocks may be specified with either a +do+/+end+ pair, or with curly
537
+ braces in Ruby. We _strongly_ recommend using +do+/+end+ to specify the
538
+ actions for tasks and rules. Because the rakefile idiom tends to
539
+ leave off parenthesis on the task/file/rule methods, unusual
540
+ ambiguities can arise when using curly braces.
541
+
542
+ For example, suppose that the method +object_files+ returns a list of
543
+ object files in a project. Now we use +object_files+ as the
544
+ prerequistes in a rule specified with actions in curly braces.
545
+
546
+ # DON'T DO THIS!
547
+ file "prog" => object_files {
548
+ # Actions are expected here (but it doesn't work)!
549
+ }
550
+
551
+ Because curly braces have a higher precedence than +do+/+end+, the
552
+ block is associated with the +object_files+ method rather than the
553
+ +file+ method.
554
+
555
+ This is the proper way to specify the task ...
556
+
557
+ # THIS IS FINE
558
+ file "prog" => object_files do
559
+ # Actions go here
560
+ end
561
+
562
+ ----
563
+
564
+ == See
565
+
566
+ * README.rdoc -- Main documentation for Rake.