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
@@ -0,0 +1,134 @@
1
+ module Detroit
2
+
3
+ require 'indexer'
4
+
5
+ def self.project(root)
6
+ Project.factory(root)
7
+ end
8
+
9
+ ##
10
+ # Base class for more specific Project types.
11
+ #
12
+ class Project
13
+
14
+ # FIXME: Lookup root directory. How?
15
+ def self.root
16
+ Dir.pwd
17
+ end
18
+
19
+ #
20
+ def self.lookup
21
+ dir = Dir.pwd
22
+ while dir != '/' #&& dir != $HOME
23
+ return new(dir) if project?(dir)
24
+ dir = File.dirname(dir)
25
+ end
26
+ return nil
27
+ end
28
+
29
+ # Get a new project instance based on criteria of the project.
30
+ # For instance a project with a `*.gemspec` is recognized as a
31
+ # Ruby project and thus returns an instance of {RubyProject}.
32
+ #
33
+ # @return [Project]
34
+ def self.factory(root)
35
+ if RubyProject.project?(root)
36
+ RubyProject.new(root)
37
+ else
38
+ Project.new(root)
39
+ end
40
+ end
41
+
42
+ # Initialize new instance of Project.
43
+ #
44
+ # @param [String,Pathname] root
45
+ # Root directory of project.
46
+ #
47
+ # @return [Pathname]
48
+ def initialize(root)
49
+ @root = Pathname.new(root)
50
+ @log = @root + 'log'
51
+ end
52
+
53
+ # Root directory.
54
+ #
55
+ # @return [Pathname]
56
+ attr :root
57
+
58
+ # Log directory. By defaul this is `{root}/log/`.
59
+ attr :log
60
+
61
+ # Detroit configuration for project.
62
+ #
63
+ # @return [Config]
64
+ def config
65
+ @config ||= Config.new(root)
66
+ end
67
+
68
+ # TODO: Indexer's Loadable module is confusing!!!
69
+
70
+ # Access to project metadata. Metadata is handled by Indexer.
71
+ # If a specific project type has different needs then override
72
+ # this method. The return value should work akin to an OpenStruct
73
+ # instance, and if possible it should respond to `#to_h` method.
74
+ #
75
+ # @return [Indexer::Metadata]
76
+ def metadata
77
+ @metadata ||= Indexer::Metadata.open(root)
78
+ end
79
+
80
+ # If method is missing see if it is a piece of metadata.
81
+ def method_missing(s, *a, &b)
82
+ super(s, *a, &b) unless a.empty?
83
+ super(s, *a, &b) if block_given?
84
+ metadata.send(s)
85
+ end
86
+
87
+ end
88
+
89
+ ##
90
+ # Ruby Project class.
91
+ #
92
+ class RubyProject < Project
93
+
94
+ # Determine if a directory is a Ruby project by
95
+ # looking for a .gemspec file.
96
+ #
97
+ # @todo While this will work well in the vase majority of
98
+ # cases, there may be a few outlays.
99
+ #
100
+ def self.project?(root)
101
+ Dir[File.join(root, "{*,}.gemspec")].first
102
+ end
103
+
104
+ #
105
+ #def initialize(root)
106
+ # super(root)
107
+ #end
108
+
109
+ #
110
+ def metadata
111
+ @metadata ||= (
112
+ if index_file
113
+ Indexer::Metadata.open(root)
114
+ elsif file = gemspec_file
115
+ Indexer::Metadata.from_gemspec(file)
116
+ else
117
+ super # TODO: what metadata?
118
+ end
119
+ )
120
+ end
121
+
122
+ #
123
+ def index_file
124
+ Dir[File.join(root, ".index")].first
125
+ end
126
+
127
+ #
128
+ def gemspec_file
129
+ Dir[File.join(root, "{*,}.gemspec")].first
130
+ end
131
+
132
+ end
133
+
134
+ end
@@ -0,0 +1,29 @@
1
+ require_relative 'project'
2
+
3
+ module Detroit
4
+
5
+ ##
6
+ # Methods for working with a Ruby projects.
7
+ #
8
+ module RubyUtils
9
+
10
+ # TODO: Rename to preinitialize.
11
+ def prerequisite
12
+ require 'facets/platform'
13
+ end
14
+
15
+ # Current platform.
16
+ def current_platform
17
+ Platform.local.to_s
18
+ end
19
+
20
+
21
+ ## Set project manually.
22
+ ##
23
+ #def project=(proj)
24
+ # @project = proj
25
+ #end
26
+
27
+ end
28
+
29
+ end
@@ -1,15 +1,20 @@
1
- require 'detroit/tool/core_ext/shell_extensions'
2
- require 'rbconfig'
3
- require 'ansi/core'
4
-
5
1
  module Detroit
6
2
 
3
+ ##
7
4
  # ShellUtils provides the whole slew of FileUtils,
8
5
  # FileTest and File class methods in a single module
9
6
  # and modifies methods according to noop? and verbose?
10
7
  # options.
8
+ #
11
9
  module ShellUtils
12
10
 
11
+ #
12
+ def prerequisite
13
+ require 'rbconfig'
14
+ require 'ansi/core'
15
+ #require 'detroit/core_ext/shell_extensions'
16
+ end
17
+
13
18
  #
14
19
  def initialize_extension_defaults
15
20
  @quiet = false
@@ -22,7 +27,7 @@ module Detroit
22
27
 
23
28
  #
24
29
  def initialize_extensions
25
- # extend(fileutils)
30
+ #extend(fileutils)
26
31
  super() if defined?(super)
27
32
  end
28
33
 
@@ -0,0 +1,6 @@
1
+ require_relative 'toolchain/worker'
2
+ require_relative 'toolchain/script'
3
+ #require_relative 'toolchain/config'
4
+ require_relative 'toolchain/runner'
5
+ require_relative 'toolchain/cli'
6
+
@@ -0,0 +1,320 @@
1
+ module Detroit
2
+
3
+ module Toolchain
4
+
5
+ #
6
+ def self.cli(argv=ARGV)
7
+ CLI.execute(argv)
8
+ end
9
+
10
+ ##
11
+ # The CLI class.
12
+ class CLI
13
+
14
+ # Location of standard plugins.
15
+ #PLUGIN_DIRECTORY = File.dirname(__FILE__) + '/plugins'
16
+
17
+ # Returns Array of standard plugin file names.
18
+ #def standard_plugins
19
+ # Dir[PLUGIN_DIRECTORY + '/*.rb']
20
+ #end
21
+
22
+ # Universal acccess to the current project.
23
+ #
24
+ # TODO: Is Control#project being used?
25
+ #def project
26
+ # @project ||= POM::Project.find
27
+ #end
28
+
29
+ #
30
+ # argv - Command line arguments.
31
+ #
32
+ def self.execute(argv=ARGV)
33
+ new.execute(*argv)
34
+ end
35
+
36
+ # Run the command line interface.
37
+ def initialize
38
+ @options = {
39
+ :toolchains => [],
40
+ :assembly => nil,
41
+ :trace => nil,
42
+ :trial => nil,
43
+ :debug => nil,
44
+ :quiet => nil,
45
+ :verbose => nil,
46
+ :force => nil,
47
+ :multitask => nil,
48
+ :skip => []
49
+ }
50
+ end
51
+
52
+ #
53
+ def execute(*argv)
54
+ #if /\.assembly$/ =~ argv[0]
55
+ # job = argv[1]
56
+ # begin
57
+ # application(cli_options).runscript(argv[0], job)
58
+ # rescue => error
59
+ # $stderr.puts error.message
60
+ # exit -1
61
+ # end
62
+ #else
63
+
64
+ option_parser.parse!(argv)
65
+
66
+ if argv.empty?
67
+ # TODO: What about a defualt destination, e.g. test?
68
+ $stderr.puts "No assembly destination given."
69
+ exit -1
70
+ end
71
+
72
+ if $DEBUG
73
+ application(options).start(*argv)
74
+ else
75
+ begin
76
+ application(options).start(*argv)
77
+ rescue => error
78
+ $stderr.puts error.message
79
+ exit -1
80
+ end
81
+ end
82
+ end
83
+
84
+ # Returns Runner instance given options.
85
+ def application(options={})
86
+ Runner.new(options)
87
+ end
88
+
89
+ # Command line options.
90
+ def options
91
+ @options
92
+ end
93
+
94
+ #
95
+ def toolchains
96
+ @options[:toolchains]
97
+ end
98
+
99
+ #
100
+ def skip
101
+ @options[:skip]
102
+ end
103
+
104
+ #
105
+ def multitask
106
+ @options[:multitask]
107
+ end
108
+
109
+ #
110
+ def multitask=(boolean)
111
+ @options[:multitask] = !!boolean
112
+ end
113
+
114
+ #
115
+ def assembly
116
+ @options[:assembly]
117
+ end
118
+
119
+ #
120
+ def assembly=(name)
121
+ @options[:assembly] = name.to_sym
122
+ end
123
+
124
+ #
125
+ def force
126
+ @options[:force]
127
+ end
128
+
129
+ #
130
+ def force=(boolean)
131
+ @options[:force] = !!boolean
132
+ end
133
+
134
+ #
135
+ def trial
136
+ @options[:trial]
137
+ end
138
+
139
+ #
140
+ def trial=(boolean)
141
+ @options[:trial] = !!boolean
142
+ end
143
+
144
+ #
145
+ def trace
146
+ @options[:trace]
147
+ end
148
+
149
+ #
150
+ def trace=(boolean)
151
+ @options[:trace] = !!boolean
152
+ end
153
+
154
+ #
155
+ def quiet
156
+ @options[:quiet]
157
+ end
158
+
159
+ #
160
+ def quiet=(boolean)
161
+ @options[:quiet] = !!boolean
162
+ end
163
+
164
+ #
165
+ def verbose
166
+ @options[:quiet]
167
+ end
168
+
169
+ #
170
+ def verbose=(boolean)
171
+ @options[:verbose] = !!boolean
172
+ end
173
+
174
+ # Create command line option parser.
175
+ def option_parser
176
+ usage_banner
177
+ option_multitask
178
+ option_assembly
179
+ option_toolchain
180
+ option_skip
181
+ option_trial
182
+ option_trace
183
+ option_loadpath
184
+ option_force
185
+ option_verbose
186
+ option_quiet
187
+ option_config
188
+ option_debug
189
+ option_warn
190
+ option_help
191
+ usage
192
+ end
193
+
194
+ # Cached instance of OptionParser.
195
+ #
196
+ # @return [OptionParser]
197
+ def usage
198
+ @usage ||= OptionParser.new
199
+ end
200
+
201
+ # @return [String]
202
+ def usage_banner
203
+ usage.banner = "Usage: detroit [<track>:]<stop> [options]"
204
+ end
205
+
206
+ # @return [void]
207
+ def option_multitask
208
+ usage.on('-m', '--multitask', "Run work elements in parallel.") do
209
+ self.multitask = true
210
+ end
211
+ end
212
+
213
+ # @return [void]
214
+ def option_assembly
215
+ usage.on('-a', '--assembly=NAME', "Select assembly. Default is `standard'.") do |a|
216
+ self.assembly = a
217
+ end
218
+ end
219
+
220
+ # @return [void]
221
+ def option_toolchain
222
+ usage.on('-t', '--toolchain [FILE]', 'Use specific toolchain file(s).') do |file|
223
+ self.toolchains << file
224
+ end
225
+ end
226
+
227
+ # @return [void]
228
+ def option_skip
229
+ usage.on('-S', '--skip [NAME]', 'Skip a tool instance.') do |skip|
230
+ self.skip << skip
231
+ end
232
+ end
233
+
234
+ # @return [void]
235
+ def option_trial
236
+ usage.on('--trial', "Run in TRIAL mode (no disk writes).") do
237
+ #$TRIAL = true
238
+ self.trial = true
239
+ end
240
+ end
241
+
242
+ # @return [void]
243
+ def option_trace
244
+ usage.on('--trace', "Run in TRACE mode.") do
245
+ #$TRACE = true
246
+ self.trace = true
247
+ end
248
+ end
249
+
250
+ # @todo Do we really need verbose?
251
+ #
252
+ # @return [void]
253
+ def option_verbose
254
+ usage.on('--verbose', "Provide extra output.") do
255
+ self.verbose = true
256
+ end
257
+ end
258
+
259
+ # @return [void]
260
+ def option_quiet
261
+ usage.on('-q', '--quiet', "Run silently.") do
262
+ self.quiet = true
263
+ end
264
+ end
265
+
266
+ # @return [void]
267
+ def option_force
268
+ usage.on('-F', '--force', "Force operations.") do
269
+ self.force = true
270
+ end
271
+ end
272
+
273
+ # @return [void]
274
+ def option_loadpath
275
+ usage.on('-I=PATH', "Add directory to $LOAD_PATH") do |dirs|
276
+ dirs.to_list.each do |dir|
277
+ $LOAD_PATH.unshift(dir)
278
+ end
279
+ end
280
+ end
281
+
282
+ # @return [void]
283
+ def option_debug
284
+ usage.on('--debug', "Run with $DEBUG set to true.") do
285
+ $DEBUG = true
286
+ end
287
+ end
288
+
289
+ # @return [void]
290
+ def option_warn
291
+ usage.on('--warn', "Run with $VERBOSE set to true.") do
292
+ $VERBOSE = true # wish this were called $WARN
293
+ end
294
+ end
295
+
296
+ # @return [void]
297
+ def option_help
298
+ usage.on_tail('--help [TOOL]', "Display this help message.") do |tool|
299
+ if tool
300
+ application.display_help(tool)
301
+ else
302
+ puts usage
303
+ end
304
+ exit
305
+ end
306
+ end
307
+
308
+ #
309
+ def option_config
310
+ usage.on_tail('-c', '--config TOOL', "Produce a configuration template.") do |tool|
311
+ puts application.config_template(tool).to_yaml
312
+ exit
313
+ end
314
+ end
315
+
316
+ end
317
+
318
+ end
319
+
320
+ end