detroit 0.3.0 → 0.4.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 (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