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.
- checksums.yaml +7 -0
- data/.index +59 -0
- data/EXAMPLE.md +66 -64
- data/{HISTORY.rdoc → HISTORY.md} +32 -5
- data/{COPYING.rdoc → LICENSE.txt} +0 -0
- data/README.md +142 -0
- data/bin/detroit +1 -1
- data/lib/detroit.rb +112 -40
- data/lib/detroit.yml +44 -29
- data/lib/detroit/assembly.rb +49 -193
- data/lib/detroit/basic_tool.rb +200 -0
- data/lib/detroit/basic_utils.rb +66 -0
- data/lib/detroit/core_ext.rb +2 -136
- data/lib/detroit/{tool/core_ext → core_ext}/facets.rb +3 -0
- data/lib/detroit/{tool/core_ext → core_ext}/filetest.rb +0 -0
- data/lib/detroit/{tool/core_ext → core_ext}/shell_extensions.rb +0 -0
- data/lib/detroit/{tool/core_ext → core_ext}/to_actual_filename.rb +0 -0
- data/lib/detroit/{tool/core_ext → core_ext}/to_console.rb +1 -0
- data/lib/detroit/{tool/core_ext → core_ext}/to_list.rb +0 -0
- data/lib/detroit/{tool/core_ext → core_ext}/to_yamlfrag.rb +0 -0
- data/lib/detroit/{tool/core_ext → core_ext}/unfold_paragraphs.rb +0 -0
- data/lib/detroit/{tool/email_utils.rb → email_utils.rb} +3 -1
- data/lib/detroit/exec.rb +55 -0
- data/lib/detroit/project.rb +134 -0
- data/lib/detroit/ruby_utils.rb +29 -0
- data/lib/detroit/{tool/shell_utils.rb → shell_utils.rb} +10 -5
- data/lib/detroit/toolchain.rb +6 -0
- data/lib/detroit/toolchain/cli.rb +320 -0
- data/lib/detroit/toolchain/config.rb +223 -0
- data/lib/detroit/toolchain/runner.rb +678 -0
- data/lib/detroit/toolchain/script.rb +248 -0
- data/lib/detroit/toolchain/worker.rb +84 -0
- data/man/detroit.1 +116 -0
- data/man/detroit.1.html +171 -0
- data/man/detroit.1.ronn +99 -0
- metadata +90 -51
- data/.ruby +0 -44
- data/README.rdoc +0 -132
- data/lib/detroit/application.rb +0 -463
- data/lib/detroit/assembly_system.rb +0 -80
- data/lib/detroit/config.rb +0 -203
- data/lib/detroit/control.rb +0 -129
- data/lib/detroit/custom.rb +0 -102
- data/lib/detroit/dsl.rb +0 -55
- data/lib/detroit/service.rb +0 -78
- data/lib/detroit/standard_assembly.rb +0 -51
- data/lib/detroit/tool.rb +0 -295
- data/lib/detroit/tool/core_ext.rb +0 -3
- 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
|
-
|
30
|
+
#extend(fileutils)
|
26
31
|
super() if defined?(super)
|
27
32
|
end
|
28
33
|
|
@@ -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
|