detroit 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +7 -0
  2. data/.index +59 -0
  3. data/EXAMPLE.md +66 -64
  4. data/{HISTORY.rdoc → HISTORY.md} +32 -5
  5. data/{COPYING.rdoc → LICENSE.txt} +0 -0
  6. data/README.md +142 -0
  7. data/bin/detroit +1 -1
  8. data/lib/detroit.rb +112 -40
  9. data/lib/detroit.yml +44 -29
  10. data/lib/detroit/assembly.rb +49 -193
  11. data/lib/detroit/basic_tool.rb +200 -0
  12. data/lib/detroit/basic_utils.rb +66 -0
  13. data/lib/detroit/core_ext.rb +2 -136
  14. data/lib/detroit/{tool/core_ext → core_ext}/facets.rb +3 -0
  15. data/lib/detroit/{tool/core_ext → core_ext}/filetest.rb +0 -0
  16. data/lib/detroit/{tool/core_ext → core_ext}/shell_extensions.rb +0 -0
  17. data/lib/detroit/{tool/core_ext → core_ext}/to_actual_filename.rb +0 -0
  18. data/lib/detroit/{tool/core_ext → core_ext}/to_console.rb +1 -0
  19. data/lib/detroit/{tool/core_ext → core_ext}/to_list.rb +0 -0
  20. data/lib/detroit/{tool/core_ext → core_ext}/to_yamlfrag.rb +0 -0
  21. data/lib/detroit/{tool/core_ext → core_ext}/unfold_paragraphs.rb +0 -0
  22. data/lib/detroit/{tool/email_utils.rb → email_utils.rb} +3 -1
  23. data/lib/detroit/exec.rb +55 -0
  24. data/lib/detroit/project.rb +134 -0
  25. data/lib/detroit/ruby_utils.rb +29 -0
  26. data/lib/detroit/{tool/shell_utils.rb → shell_utils.rb} +10 -5
  27. data/lib/detroit/toolchain.rb +6 -0
  28. data/lib/detroit/toolchain/cli.rb +320 -0
  29. data/lib/detroit/toolchain/config.rb +223 -0
  30. data/lib/detroit/toolchain/runner.rb +678 -0
  31. data/lib/detroit/toolchain/script.rb +248 -0
  32. data/lib/detroit/toolchain/worker.rb +84 -0
  33. data/man/detroit.1 +116 -0
  34. data/man/detroit.1.html +171 -0
  35. data/man/detroit.1.ronn +99 -0
  36. metadata +90 -51
  37. data/.ruby +0 -44
  38. data/README.rdoc +0 -132
  39. data/lib/detroit/application.rb +0 -463
  40. data/lib/detroit/assembly_system.rb +0 -80
  41. data/lib/detroit/config.rb +0 -203
  42. data/lib/detroit/control.rb +0 -129
  43. data/lib/detroit/custom.rb +0 -102
  44. data/lib/detroit/dsl.rb +0 -55
  45. data/lib/detroit/service.rb +0 -78
  46. data/lib/detroit/standard_assembly.rb +0 -51
  47. data/lib/detroit/tool.rb +0 -295
  48. data/lib/detroit/tool/core_ext.rb +0 -3
  49. data/lib/detroit/tool/project_utils.rb +0 -41
@@ -1,55 +0,0 @@
1
- module Detroit
2
-
3
- # NOT YET IN USE.
4
- module DSL
5
-
6
- # Define a track.
7
- #
8
- # Examples
9
- #
10
- # track :site do
11
- # route :maintainence do
12
- # stops :reset, :clean, :purge
13
- # end
14
- # end
15
- #
16
- def track(&block)
17
- Track.new(&block)
18
- end
19
-
20
- # Define a service.
21
- #
22
- # Examples
23
- #
24
- # service :foo do
25
- # reset do
26
- # utime(0,0, project.path(:log) + 'foo.log')
27
- # end
28
- # end
29
- #
30
- def service(name, &block)
31
- Service.registry[name.to_s] ||= ServiceDSL.new(&block).service_class
32
- end
33
-
34
- # ServiceDSL is used to define services via the Detroit DSL.
35
- class ServiceDSL < BasicObject
36
- attr :service_class
37
-
38
- def initialize(name, &block)
39
- @service_class = Class.new(Detroit::Service)
40
- end
41
-
42
- def available(&block)
43
- (class << @service_class; self; end).class_eval do
44
- define_method(:available?, &block)
45
- end
46
- end
47
-
48
- def method_missing(name, *args, &block)
49
- @service_class.define_method(name, &block)
50
- end
51
- end
52
-
53
- end
54
-
55
- end
@@ -1,78 +0,0 @@
1
- module Detroit
2
-
3
- # TODO: Need to work on how to limit a service's tracks per-assembly.
4
-
5
- # Service class wraps a Tool instance when it is made part of an assembly.
6
- #
7
- class Service
8
- attr :key
9
- attr :tracks
10
- attr :priority
11
- attr :active
12
- attr :service
13
- #attr :options
14
-
15
- #
16
- # Set the priority. Priority determines the order which
17
- # services on the same stop are run.
18
- #
19
- def priority=(integer)
20
- @priority = integer.to_i
21
- end
22
-
23
- #
24
- # Set the tracks a service will be available on.
25
- #
26
- def tracks=(list)
27
- @tracks = list.to_list
28
- end
29
-
30
- #
31
- #
32
- #
33
- def active=(boolean)
34
- @active = !!boolean
35
- end
36
-
37
- #
38
- # Create new ServiceWrapper.
39
- #
40
- def initialize(key, service_class, options)
41
- @key = key
42
-
43
- ## set service defaults
44
- @tracks = nil #service_class.tracks
45
- @priority = 0
46
- @active = true
47
-
48
- self.active = options.delete('active') if !options['active'].nil?
49
- self.tracks = options.delete('tracks') if options.key?('tracks')
50
- self.priority = options.delete('priority') if options.key?('priority')
51
-
52
- @service = service_class.new(options)
53
- end
54
-
55
- #
56
- # Does the service support the given assembly station?
57
- #
58
- def stop?(station, stop=nil)
59
- @service.assemble?(station.to_sym, :destination=>stop.to_sym)
60
- end
61
-
62
- #
63
- # Run the service assembly station procedure.
64
- #
65
- def invoke(station, stop=nil)
66
- @service.assemble(station.to_sym, :destination=>stop.to_sym)
67
- end
68
-
69
- #
70
- #
71
- #
72
- def inspect
73
- "<#{self.class}:#{object_id} @key='#{key}'>"
74
- end
75
-
76
- end
77
-
78
- end
@@ -1,51 +0,0 @@
1
- module Detroit
2
-
3
- # Standard assembly is the default. In the majority of cases this
4
- # is all that will be needed. It represents the workflow of
5
- # a developing project (particularly Ruby project).
6
- assembly_system :standard do
7
-
8
- # Main track.
9
- #
10
- track :main,
11
- :prepare, # prepare services / ensure service requirements
12
- :generate, # code generation
13
- :compile, # compile source code
14
- :test, # run tests and specifications
15
- :analyze, # perform code analysis
16
- :document, # generate documentation
17
- :package, # create packages
18
- :install, # install the package locally (if need be)
19
- :verify, # post package verification / integration tests
20
- :publish, # publish website/documentation
21
- :release, # release packages
22
- :deploy, # deploy system to servers
23
- :promote # tell the world about your awesome work
24
-
25
- # The site track is a subset of the main track used to
26
- # isolate the distribution of documentation and uploading
27
- # a project's website.
28
- #
29
- # prepare -> generate -> analyze -> document -> publish
30
- #
31
- track :site,
32
- :prepare,
33
- :generate,
34
- :analyze,
35
- :document,
36
- :publish
37
-
38
- # The attention track is a small subset of main track, used to
39
- # isolate the sending of promotional materials, mainly release
40
- # announcements.
41
- #
42
- # prepare -> generate -> promote
43
- #
44
- track :attn,
45
- :prepare,
46
- :generate,
47
- :promote
48
-
49
- end
50
-
51
- end
@@ -1,295 +0,0 @@
1
- module Detroit
2
-
3
- # TODO: The plan is to replace most, if not all, of the fileutils
4
- # functionality with Ratch when it is ready.
5
-
6
- require 'detroit/tool/core_ext'
7
- require 'detroit/tool/shell_utils'
8
- require 'detroit/tool/project_utils'
9
- require 'detroit/tool/email_utils'
10
-
11
- # The Tools module provides an isolated namespace for
12
- # Detoit's tools. This allows for general use of these
13
- # tools by other applications, by including them into
14
- # their own namespace.
15
- #
16
- module Tools
17
- #BasicTool = Detroit::BasicTool
18
- #Tool = Detroit::Tool
19
- end
20
-
21
- #
22
- # Tool registry.
23
- #
24
- def self.tools
25
- @tools ||= {}
26
- end
27
-
28
- #
29
- # Alias for #tools.
30
- #
31
- def self.services
32
- tools
33
- end
34
-
35
- #
36
- #
37
- #
38
- def self.define_tool_method(name, tool_class)
39
- (class << self; self; end).class_eval do
40
- # raise if method_defined?(name)
41
- define_method(name) do |*a, &b|
42
- tool_class.new(*a,&b)
43
- end
44
- end
45
- end
46
-
47
- #
48
- # Add tool class to registry. If class name ends in `Base`
49
- # it will be considered a reusable base class and not be added.
50
- #
51
- def self.register_tool(tool_class)
52
- name = tool_class.basename
53
- return if name.empty?
54
- return if name == 'Tool'
55
- return if name =~ /Base$/
56
- tools[name.downcase] = tool_class
57
- Tools.const_set(name, tool_class)
58
- Detroit.define_tool_method(name, tool_class)
59
- return tool_class
60
- end
61
-
62
- # This base class can be used for tools that do not need
63
- # all of the utility methods provided by the regular Tool
64
- # class.
65
- #
66
- class BasicTool
67
- class << self
68
- # Add an assembly system to which the tool applies.
69
- # By default the `standard` system is implied.
70
- def assembly_system(assembly=nil)
71
- @assembly ||= []
72
- if assembly
73
- @assembly << assembly.to_sym
74
- @assembly.uniq!
75
- end
76
- @assembly
77
- end
78
-
79
- # Shorter alias for #assembly_system.
80
- alias_method :assembly, :assembly_system
81
-
82
- # Override the `tracks` method to limit the lines a service
83
- # will work with by default. Generally this is not used,
84
- # and a return value of +nil+ means all lines apply.
85
- #
86
- # @todo Rename to #lines ?
87
- #
88
- def tracks
89
- end
90
-
91
- # Override this method if the tools availability is conditional.
92
- def available?
93
- true
94
- end
95
-
96
- # Returns list of writer method names. This is used for reference.
97
- def options(service_class=self)
98
- i = service_class.ancestors.index(Tool) ||
99
- service_class.ancestors.index(BasicTool)
100
- m = []
101
- service_class.ancestors[0..i].each do |sc|
102
- sc.public_instance_methods(false).each do |pm|
103
- next if pm !~ /\w+=$/
104
- next if %w{taguri=}.include?(m.to_s)
105
- m << pm.to_s.chomp('=')
106
- end
107
- end
108
- m
109
- end
110
-
111
- # Returns a Class which is a new subclass of the current class.
112
- def factory(&block)
113
- Class.new(self, &block)
114
- end
115
-
116
- # When inherited, add class to tool registry.
117
- def inherited(base)
118
- Detroit.register_tool(base)
119
- end
120
- end
121
-
122
- #
123
- # @todo Is this neeeed? Maybe rename?
124
- #
125
- def service_title
126
- self.class.name
127
- end
128
-
129
- #
130
- # Override this method so the assembly system can determine if the
131
- # station is applicable with the given state of the project. By default
132
- # the return value is always `true`.
133
- #
134
- # @param [Symbol] station
135
- #
136
- # @param [Hash] options
137
- # Additonal information significant to the determination.
138
- #
139
- # @option options [Symbol] :destination
140
- # The final stop designated for the particular run.
141
- #
142
- # @return [Boolean] Is the particular station applicable?
143
- #
144
- def assemble?(station, options={})
145
- warn "tool #{self.class} has not defined an #assemble? method"
146
- false
147
- end
148
-
149
- #
150
- # Use the tool for the given station. By default this method does nothing
151
- # It must be overriden by the tool to direct execution for the given station.
152
- #
153
- # @param [Symbol] station
154
- #
155
- # @param [Hash] options
156
- # Additonal information significant to the determination.
157
- #
158
- # @option options [Symbol] :destination
159
- # The final stop designated for the particular run.
160
- #
161
- def assemble(station, options={})
162
- warn "tool #{self.class} has not defined an #assemble method"
163
- end
164
- end
165
-
166
- # Tool is the base class for all Detroit tools.
167
- #
168
- # Tool class is essentially the same as the {BasicTool} but provides an
169
- # assortment of addtional data and utility methods often useful to tools.
170
- # Use this class to build Detroit tools with all the conveniences.
171
- #
172
- class Tool < BasicTool
173
- include ShellUtils
174
- include ProjectUtils
175
- include EmailUtils
176
-
177
- public
178
-
179
- #
180
- attr :options
181
-
182
- # If applicable tools should override #current to allow tool users
183
- # to know if the tool needs to be used. For example the RDoc tool
184
- # can look to see if any the files it would document are newer that
185
- # the previous generated set of docs.
186
- #
187
- # The method can return a String instead of `true`, to convey a
188
- # custom message explaining that the tool need not be run. For example,
189
- # the RDoc tool returns "RDocs are current (path/to/rdocs)".
190
- def current?
191
- false
192
- end
193
-
194
- private
195
-
196
- # Create a new tool object.
197
- #
198
- # This sets up utility extensions and assigns options to setter attributes
199
- # if they exist and values are not nil. That last point is important.
200
- # You must use 'false' to purposely negate an option, as +nil+ will instead
201
- # allow any default setting to be used.
202
- #
203
- def initialize(options={})
204
- initialize_extension_defaults
205
-
206
- initialize_requires
207
- initialize_defaults
208
-
209
- initialize_options(options)
210
-
211
- initialize_extensions
212
- end
213
-
214
- # TODO: It would be best if an error were raised if an option is not
215
- # supported, however for now only a warning will be issued, b/c
216
- # subclassing makes things more complicated.
217
- def initialize_options(options)
218
- @options = options
219
-
220
- options.each do |k, v|
221
- #send("#{k}=", v) unless v.nil? #if respond_to?("#{k}=") && !v.nil?
222
- if respond_to?("#{k}=")
223
- send("#{k}=", v) unless v.nil? #if respond_to?("#{k}=") && !v.nil?
224
- else
225
- warn "#{self.class.name} does not respond to `#{k}`."
226
- end
227
- end
228
- end
229
-
230
- #
231
- def initialize_extension_defaults
232
- super if defined?(super)
233
- end
234
-
235
- # Require support libraries needed by this service.
236
- #
237
- # def initialize_requires
238
- # require 'ostruct'
239
- # end
240
- #
241
- def initialize_requires
242
- end
243
-
244
- # When subclassing, put default instance variable settngs here.
245
- #
246
- # Examples
247
- #
248
- # def initialize_defaults
249
- # @gravy = true
250
- # end
251
- #
252
- def initialize_defaults
253
- end
254
-
255
- # --- Odd Utilities -------------------------------------------------------
256
-
257
- require 'facets/platform'
258
-
259
- # Current platform.
260
- def current_platform
261
- Platform.local.to_s
262
- end
263
-
264
- # TODO: How to set naming policy in a more universal manner?
265
-
266
- #
267
- #
268
- def naming_policy(*policies)
269
- if policies.empty?
270
- @naming_policy ||= ['down', 'ext']
271
- else
272
- @naming_policy = policies
273
- end
274
- end
275
-
276
- #
277
- #
278
- def apply_naming_policy(name, ext)
279
- naming_policy.each do |policy|
280
- case policy.to_s
281
- when /^low/, /^down/
282
- name = name.downcase
283
- when /^up/
284
- name = name.upcase
285
- when /^cap/
286
- name = name.capitalize
287
- when /^ext/
288
- name = name + ".#{ext}"
289
- end
290
- end
291
- name
292
- end
293
-
294
- end
295
- end