reactive-dev 0.2.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.
- data/History +3 -0
- data/LICENSE +21 -0
- data/Manifest +29 -0
- data/README +130 -0
- data/Rakefile +19 -0
- data/app_generators/reactive/USAGE +14 -0
- data/app_generators/reactive/reactive_generator.rb +137 -0
- data/app_generators/reactive/templates/README +101 -0
- data/app_generators/reactive/templates/Rakefile +16 -0
- data/app_generators/reactive/templates/config/boot.rb +118 -0
- data/app_generators/reactive/templates/config/config.rb +29 -0
- data/app_generators/reactive/templates/config/empty.log +0 -0
- data/app_generators/reactive/templates/script/console +47 -0
- data/app_generators/reactive/templates/script/destroy +18 -0
- data/app_generators/reactive/templates/script/generate +18 -0
- data/app_generators/reactive/templates/script/run +9 -0
- data/app_generators/reactive/templates/script/win_script.cmd +1 -0
- data/bin/reactive +15 -0
- data/lib/reactive-dev.rb +3 -0
- data/lib/reactive-dev/code_statistics.rb +107 -0
- data/lib/reactive-dev/generated_attribute.rb +40 -0
- data/lib/reactive-dev/named_base_generator.rb +79 -0
- data/lib/reactive-dev/rubigen_plugin_sources.rb +49 -0
- data/lib/reactive-dev/source_annotation_extractor.rb +62 -0
- data/lib/reactive-dev/tasks/annotations.rake +23 -0
- data/lib/reactive-dev/tasks/app.rake +51 -0
- data/lib/reactive-dev/tasks/plugin.rb +147 -0
- data/lib/reactive-dev/tasks/statistics.rake +7 -0
- data/lib/reactive-dev/tasks/testing.rake +118 -0
- metadata +129 -0
@@ -0,0 +1,16 @@
|
|
1
|
+
# Add your own tasks in files placed in lib/tasks ending in .rake,
|
2
|
+
# and they will automatically be available to Rake.
|
3
|
+
|
4
|
+
APP_PATH = File.dirname(__FILE__)
|
5
|
+
APP_NAME = APP_PATH.split('/').last
|
6
|
+
|
7
|
+
require ["#{File.dirname(__FILE__)}/config/boot.rb", "#{File.dirname(__FILE__)}/boot.rb"].find {|path| File.file? path}
|
8
|
+
Reactive.load(['--root', APP_PATH])
|
9
|
+
Reactive::Initializer.stages.delete(:check_plugins)
|
10
|
+
Reactive.init(:configure)
|
11
|
+
|
12
|
+
require 'rake'
|
13
|
+
require 'rake/testtask'
|
14
|
+
require 'rake/rdoctask'
|
15
|
+
|
16
|
+
require 'reactive-core/tasks/reactive'
|
@@ -0,0 +1,118 @@
|
|
1
|
+
module Reactive
|
2
|
+
class << self
|
3
|
+
def load(argv = ARGV)
|
4
|
+
return @bootstrapper if @bootstrapper
|
5
|
+
options = {}
|
6
|
+
options[:root_dir] = if index = argv.rindex(argv.find {|arg| arg == '--root' })
|
7
|
+
argv[index+1]
|
8
|
+
end
|
9
|
+
options[:config_file] = if index = argv.rindex(argv.find {|arg| arg == '--config-file' })
|
10
|
+
argv[index+1]
|
11
|
+
end
|
12
|
+
@argv = argv
|
13
|
+
@bootstrapper ||= Bootstrapper.new(options)
|
14
|
+
end
|
15
|
+
|
16
|
+
def loaded?
|
17
|
+
@bootstrapper
|
18
|
+
end
|
19
|
+
|
20
|
+
def init(stage = :final, argv = @argv || ARGV)
|
21
|
+
load(argv)
|
22
|
+
Reactive::Initializer.run(stage, Configuration.new(argv))
|
23
|
+
end
|
24
|
+
|
25
|
+
def run(argv = @argv || ARGV)
|
26
|
+
init(:final, argv)
|
27
|
+
Dispatcher::Base.dispatch(Reactive.configuration.initial_request.is_a?(Hash) ? Request.new(Reactive.configuration.initial_request) : Reactive.configuration.initial_request)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class Bootstrapper
|
32
|
+
def initialize(options)
|
33
|
+
@config_file = options[:config_file]
|
34
|
+
@root_dir = File.expand_path(options[:root_dir]) if options[:root_dir]
|
35
|
+
load_rubygems
|
36
|
+
|
37
|
+
# add apps gem directory to load path
|
38
|
+
if @root_dir
|
39
|
+
Gem.clear_paths
|
40
|
+
Gem.path.unshift("#{@root_dir}/gems")
|
41
|
+
end
|
42
|
+
|
43
|
+
load_reactive_gem
|
44
|
+
require 'reactive-core/initializer'
|
45
|
+
end
|
46
|
+
|
47
|
+
def load_reactive_gem
|
48
|
+
# load activesupport first
|
49
|
+
begin
|
50
|
+
if version = activesupport_gem_version
|
51
|
+
gem 'activesupport', version
|
52
|
+
end
|
53
|
+
rescue Gem::LoadError => load_error
|
54
|
+
$stderr.puts "Missing the activesupport #{version} gem. Either install the required version or choose an appropriate value for the ACTIVESUPPORT_GEM_VERSION setting in config/config.rb"
|
55
|
+
exit 1
|
56
|
+
end
|
57
|
+
|
58
|
+
if version = reactive_gem_version
|
59
|
+
gem 'reactive-core', version
|
60
|
+
else
|
61
|
+
gem 'reactive-core'
|
62
|
+
end
|
63
|
+
rescue Gem::LoadError => load_error
|
64
|
+
$stderr.puts "Missing the reactive-core #{version} gem. Please `gem install -v=#{version} reactive-core`, update your REACTIVE_GEM_VERSION setting in config/config.rb for the Reactive version you do have installed, or comment out REACTIVE_GEM_VERSION to use the latest version installed."
|
65
|
+
exit 1
|
66
|
+
end
|
67
|
+
|
68
|
+
def rubygems_version
|
69
|
+
Gem::RubyGemsVersion if defined? Gem::RubyGemsVersion
|
70
|
+
end
|
71
|
+
|
72
|
+
def reactive_gem_version
|
73
|
+
if defined? REACTIVE_GEM_VERSION
|
74
|
+
REACTIVE_GEM_VERSION
|
75
|
+
elsif ENV.include?('REACTIVE_GEM_VERSION')
|
76
|
+
ENV['REACTIVE_GEM_VERSION']
|
77
|
+
else
|
78
|
+
parse_gem_version('reactive', read_config_rb)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def activesupport_gem_version
|
83
|
+
parse_gem_version('activesupport', read_config_rb)
|
84
|
+
end
|
85
|
+
|
86
|
+
def load_rubygems
|
87
|
+
require 'rubygems'
|
88
|
+
|
89
|
+
unless rubygems_version >= '1.1.0'
|
90
|
+
$stderr.puts "Reactive requires RubyGems >= 1.1.0 (you have #{rubygems_version}). Please `gem update --system` and try again."
|
91
|
+
exit 1
|
92
|
+
end
|
93
|
+
|
94
|
+
rescue LoadError
|
95
|
+
$stderr.puts "Reactive requires RubyGems >= 1.1.0. Please install RubyGems and try again: http://rubygems.rubyforge.org"
|
96
|
+
exit 1
|
97
|
+
end
|
98
|
+
|
99
|
+
def parse_gem_version(gem_name, text)
|
100
|
+
$1 if text =~ Regexp.new(%Q{^[^#]*#{gem_name.upcase}_GEM_VERSION\\s*=\\s*["']([!~<>=]*\\s*[\\d.]+)["']})
|
101
|
+
end
|
102
|
+
|
103
|
+
private
|
104
|
+
def read_config_rb
|
105
|
+
return if @config_rb
|
106
|
+
files = [
|
107
|
+
@config_file,
|
108
|
+
@root_dir ? "#{@root_dir}/config/config.rb" : nil,
|
109
|
+
@root_dir ? "#{@root_dir}/config.rb" : nil,
|
110
|
+
"config.rb"
|
111
|
+
].compact.select {|name| File.file? name}
|
112
|
+
|
113
|
+
raise StandardError, "No config file found, you may specify it with --config-file" if files.empty?
|
114
|
+
@config_rb = File.read(files.first)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# You may specify the activesupport gem version that will be used.
|
2
|
+
# It is provided to resolve dependency issues. Note that the minimum version is 2.0.0
|
3
|
+
# ACTIVESUPPORT_GEM_VERSION = "= 2.0.2"
|
4
|
+
|
5
|
+
# You may also specifiy the Reactive gem version to use
|
6
|
+
# REACTIVE_GEM_VERSION = ">= 0.2.0"
|
7
|
+
|
8
|
+
with Reactive.configuration do |config|
|
9
|
+
# Don't forget to specify the default dispatcher which is one of your plugins, ex:
|
10
|
+
# config.dispatcher.default_dispatcher = :mvc
|
11
|
+
# You also have to configure an inital request like so:
|
12
|
+
# config.initial_request = {:controller => 'application', :action => 'initial', :format => :wx}
|
13
|
+
|
14
|
+
# put the .gem statements in the order you want them loaded.
|
15
|
+
# You may add a version requirement for each of the gems, like:
|
16
|
+
# config.gem 'reactive-mvc', '>=0.2.0'
|
17
|
+
<% for plugin in plugins -%>
|
18
|
+
config.gem '<%= plugin %>'<% end %>
|
19
|
+
|
20
|
+
config.app_gem_spec do |s|
|
21
|
+
s.name = "<%= app_name %>"
|
22
|
+
s.version = "1.0.0"
|
23
|
+
s.author = "Your name"
|
24
|
+
s.email = "you@there.com"
|
25
|
+
s.homepage = "http://there.com"
|
26
|
+
s.summary = "My great application"
|
27
|
+
s.description = "Visit our website for further information"
|
28
|
+
end
|
29
|
+
end
|
File without changes
|
@@ -0,0 +1,47 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
boot_location = [
|
4
|
+
["#{File.dirname(__FILE__)}/../config/boot.rb", ".."],
|
5
|
+
["#{File.dirname(__FILE__)}/boot.rb", "."]
|
6
|
+
].find{|path, root| File.file? path}
|
7
|
+
|
8
|
+
require boot_location.first
|
9
|
+
Reactive.load(['--root', File.join(File.dirname(__FILE__), boot_location.last)])
|
10
|
+
|
11
|
+
irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
|
12
|
+
|
13
|
+
require 'optparse'
|
14
|
+
|
15
|
+
options = { :sandbox => false, :irb => irb }
|
16
|
+
OptionParser.new do |opt|
|
17
|
+
opt.banner = "Usage: console [environment] [options]"
|
18
|
+
opt.on("--irb=[#{irb}]", 'Invoke a different irb.') { |v| options[:irb] = v }
|
19
|
+
opt.on("--debugger", 'Enable ruby-debugging for the console.') { |v| options[:debugger] = v }
|
20
|
+
opt.parse!(ARGV)
|
21
|
+
end
|
22
|
+
|
23
|
+
libs = " -r irb/completion"
|
24
|
+
libs << %( -r "#{boot_location.first}")
|
25
|
+
libs << %( -r "#{Gem.loaded_specs['reactive-core'].full_gem_path}/lib/reactive-core/console_app")
|
26
|
+
|
27
|
+
if options[:debugger]
|
28
|
+
begin
|
29
|
+
require 'ruby-debug'
|
30
|
+
libs << " -r ruby-debug"
|
31
|
+
puts "=> Debugger enabled"
|
32
|
+
rescue Exception
|
33
|
+
puts "You need to install ruby-debug to run the console in debugging mode. With gems, use 'gem install ruby-debug'"
|
34
|
+
exit
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
ENV['REACTIVE_ENV'] = case ARGV.first
|
39
|
+
when "p"; "production"
|
40
|
+
when "d"; "development"
|
41
|
+
when "t"; "test"
|
42
|
+
else
|
43
|
+
ARGV.first || ENV['REACTIVE_ENV'] || 'development'
|
44
|
+
end
|
45
|
+
|
46
|
+
puts "Loading #{ENV['REACTIVE_ENV']} environment (Reactive #{Reactive::VERSION::STRING})"
|
47
|
+
exec "#{options[:irb]} #{libs} --simple-prompt"
|
@@ -0,0 +1,18 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
boot_location = [
|
4
|
+
["#{File.dirname(__FILE__)}/../config/boot.rb", ".."],
|
5
|
+
["#{File.dirname(__FILE__)}/boot.rb", "."]
|
6
|
+
].find{|path, root| File.file? path}
|
7
|
+
|
8
|
+
APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), boot_location.last))
|
9
|
+
require boot_location.first
|
10
|
+
|
11
|
+
Reactive.init(:configure, ARGV + ['--root', APP_ROOT])
|
12
|
+
|
13
|
+
require 'rubigen'
|
14
|
+
require 'rubigen/scripts/destroy'
|
15
|
+
|
16
|
+
ARGV.shift if ['--help', '-h'].include?(ARGV[0])
|
17
|
+
RubiGen::Base.use_plugin_sources! [:reactive, :reactive_app, :test_unit]
|
18
|
+
RubiGen::Scripts::Destroy.new.run(ARGV)
|
@@ -0,0 +1,18 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
boot_location = [
|
4
|
+
["#{File.dirname(__FILE__)}/../config/boot.rb", ".."],
|
5
|
+
["#{File.dirname(__FILE__)}/boot.rb", "."]
|
6
|
+
].find{|path, root| File.file? path}
|
7
|
+
|
8
|
+
APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), boot_location.last))
|
9
|
+
require boot_location.first
|
10
|
+
|
11
|
+
Reactive.init(:configure, ARGV + ['--root', APP_ROOT])
|
12
|
+
|
13
|
+
require 'rubigen'
|
14
|
+
require 'rubigen/scripts/generate'
|
15
|
+
|
16
|
+
ARGV.shift if ['--help', '-h'].include?(ARGV[0])
|
17
|
+
RubiGen::Base.use_plugin_sources! [:reactive, :reactive_app, :test_unit]
|
18
|
+
RubiGen::Scripts::Generate.new.run(ARGV)
|
@@ -0,0 +1,9 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
boot_location = [
|
4
|
+
["#{File.dirname(__FILE__)}/../config/boot.rb", ".."],
|
5
|
+
["#{File.dirname(__FILE__)}/boot.rb", "."]
|
6
|
+
].find{|path, root| File.file? path}
|
7
|
+
|
8
|
+
require boot_location.first
|
9
|
+
Reactive.run(ARGV + ['--root', File.join(File.dirname(__FILE__), boot_location.last)])
|
@@ -0,0 +1 @@
|
|
1
|
+
@ruby <%= File.join("script", filename) %> %*
|
data/bin/reactive
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'reactive-core/version'
|
5
|
+
if %w(--version -v).include? ARGV.first
|
6
|
+
puts "Reactive #{Reactive::VERSION::STRING}"
|
7
|
+
exit(0)
|
8
|
+
end
|
9
|
+
|
10
|
+
require 'reactive-dev'
|
11
|
+
require 'rubigen'
|
12
|
+
require 'rubigen/scripts/generate'
|
13
|
+
RubiGen::Base.reset_sources
|
14
|
+
RubiGen::Base.append_sources(RubiGen::PathSource.new(:application, File.join(File.dirname(__FILE__), "../app_generators")))
|
15
|
+
RubiGen::Scripts::Generate.new.run(ARGV, :generator => 'reactive')
|
data/lib/reactive-dev.rb
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
class CodeStatistics #:nodoc:
|
2
|
+
|
3
|
+
TEST_TYPES = %w(Units Functionals Unit\ tests Functional\ tests Integration\ tests)
|
4
|
+
|
5
|
+
def initialize(*pairs)
|
6
|
+
@pairs = pairs
|
7
|
+
@statistics = calculate_statistics
|
8
|
+
@total = calculate_total if pairs.length > 1
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_s
|
12
|
+
print_header
|
13
|
+
@pairs.each { |pair| print_line(pair.first, @statistics[pair.first]) }
|
14
|
+
print_splitter
|
15
|
+
|
16
|
+
if @total
|
17
|
+
print_line("Total", @total)
|
18
|
+
print_splitter
|
19
|
+
end
|
20
|
+
|
21
|
+
print_code_test_stats
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
def calculate_statistics
|
26
|
+
@pairs.inject({}) { |stats, pair| stats[pair.first] = calculate_directory_statistics(pair.last); stats }
|
27
|
+
end
|
28
|
+
|
29
|
+
def calculate_directory_statistics(directory, pattern = /.*\.rb$/)
|
30
|
+
stats = { "lines" => 0, "codelines" => 0, "classes" => 0, "methods" => 0 }
|
31
|
+
|
32
|
+
Dir.foreach(directory) do |file_name|
|
33
|
+
if File.stat(directory + "/" + file_name).directory? and (/^\./ !~ file_name)
|
34
|
+
newstats = calculate_directory_statistics(directory + "/" + file_name, pattern)
|
35
|
+
stats.each { |k, v| stats[k] += newstats[k] }
|
36
|
+
end
|
37
|
+
|
38
|
+
next unless file_name =~ pattern
|
39
|
+
|
40
|
+
f = File.open(directory + "/" + file_name)
|
41
|
+
|
42
|
+
while line = f.gets
|
43
|
+
stats["lines"] += 1
|
44
|
+
stats["classes"] += 1 if line =~ /class [A-Z]/
|
45
|
+
stats["methods"] += 1 if line =~ /def [a-z]/
|
46
|
+
stats["codelines"] += 1 unless line =~ /^\s*$/ || line =~ /^\s*#/
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
stats
|
51
|
+
end
|
52
|
+
|
53
|
+
def calculate_total
|
54
|
+
total = { "lines" => 0, "codelines" => 0, "classes" => 0, "methods" => 0 }
|
55
|
+
@statistics.each_value { |pair| pair.each { |k, v| total[k] += v } }
|
56
|
+
total
|
57
|
+
end
|
58
|
+
|
59
|
+
def calculate_code
|
60
|
+
code_loc = 0
|
61
|
+
@statistics.each { |k, v| code_loc += v['codelines'] unless TEST_TYPES.include? k }
|
62
|
+
code_loc
|
63
|
+
end
|
64
|
+
|
65
|
+
def calculate_tests
|
66
|
+
test_loc = 0
|
67
|
+
@statistics.each { |k, v| test_loc += v['codelines'] if TEST_TYPES.include? k }
|
68
|
+
test_loc
|
69
|
+
end
|
70
|
+
|
71
|
+
def print_header
|
72
|
+
print_splitter
|
73
|
+
puts "| Name | Lines | LOC | Classes | Methods | M/C | LOC/M |"
|
74
|
+
print_splitter
|
75
|
+
end
|
76
|
+
|
77
|
+
def print_splitter
|
78
|
+
puts "+----------------------+-------+-------+---------+---------+-----+-------+"
|
79
|
+
end
|
80
|
+
|
81
|
+
def print_line(name, statistics)
|
82
|
+
m_over_c = (statistics["methods"] / statistics["classes"]) rescue m_over_c = 0
|
83
|
+
loc_over_m = (statistics["codelines"] / statistics["methods"]) - 2 rescue loc_over_m = 0
|
84
|
+
|
85
|
+
start = if TEST_TYPES.include? name
|
86
|
+
"| #{name.ljust(20)} "
|
87
|
+
else
|
88
|
+
"| #{name.ljust(20)} "
|
89
|
+
end
|
90
|
+
|
91
|
+
puts start +
|
92
|
+
"| #{statistics["lines"].to_s.rjust(5)} " +
|
93
|
+
"| #{statistics["codelines"].to_s.rjust(5)} " +
|
94
|
+
"| #{statistics["classes"].to_s.rjust(7)} " +
|
95
|
+
"| #{statistics["methods"].to_s.rjust(7)} " +
|
96
|
+
"| #{m_over_c.to_s.rjust(3)} " +
|
97
|
+
"| #{loc_over_m.to_s.rjust(5)} |"
|
98
|
+
end
|
99
|
+
|
100
|
+
def print_code_test_stats
|
101
|
+
code = calculate_code
|
102
|
+
tests = calculate_tests
|
103
|
+
|
104
|
+
puts " Code LOC: #{code} Test LOC: #{tests} Code to Test Ratio: 1:#{sprintf("%.1f", tests.to_f/code)}"
|
105
|
+
puts ""
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
|
3
|
+
module Reactive
|
4
|
+
class GeneratedAttribute # :nodoc:
|
5
|
+
attr_accessor :name, :type, :column
|
6
|
+
|
7
|
+
def initialize(name, type)
|
8
|
+
@name, @type = name, type.to_sym
|
9
|
+
@column = ActiveRecord::ConnectionAdapters::Column.new(name, nil, @type)
|
10
|
+
end
|
11
|
+
|
12
|
+
def field_type
|
13
|
+
@field_type ||= case type
|
14
|
+
when :integer, :float, :decimal then :text_field
|
15
|
+
when :datetime, :timestamp, :time then :datetime_select
|
16
|
+
when :date then :date_select
|
17
|
+
when :string then :text_field
|
18
|
+
when :text then :text_area
|
19
|
+
when :boolean then :check_box
|
20
|
+
else
|
21
|
+
:text_field
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def default
|
26
|
+
@default ||= case type
|
27
|
+
when :integer then 1
|
28
|
+
when :float then 1.5
|
29
|
+
when :decimal then "9.99"
|
30
|
+
when :datetime, :timestamp, :time then Time.now.to_s(:db)
|
31
|
+
when :date then Date.today.to_s(:db)
|
32
|
+
when :string then "MyString"
|
33
|
+
when :text then "MyText"
|
34
|
+
when :boolean then false
|
35
|
+
else
|
36
|
+
""
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module Reactive
|
2
|
+
# The base generator for named components: models, controllers, etc.
|
3
|
+
# The target name is taken as the first argument and inflected to
|
4
|
+
# several forms, see the attributes below..
|
5
|
+
#
|
6
|
+
# If no name is provided, the generator raises a usage error with content
|
7
|
+
# optionally read from the USAGE file in the generator's base path.
|
8
|
+
#
|
9
|
+
# For example, the +controller+ generator takes the first argument as
|
10
|
+
# the name of the class and subsequent arguments as the names of
|
11
|
+
# actions to be generated:
|
12
|
+
#
|
13
|
+
# ./script/generate controller Article index new create
|
14
|
+
#
|
15
|
+
class NamedBaseGenerator < RubiGen::Base
|
16
|
+
attr_reader :name, :underscore_name, :singular_name, :plural_name, :class_name, :singular_class_name, :plural_class_name
|
17
|
+
|
18
|
+
# these are arrays containing parts (path parts and module parts respectively)
|
19
|
+
attr_reader :path, :class_nesting
|
20
|
+
|
21
|
+
# complete pathname
|
22
|
+
attr_reader :pathname
|
23
|
+
|
24
|
+
def initialize(runtime_args, runtime_options = {})
|
25
|
+
super
|
26
|
+
|
27
|
+
# Name argument is required.
|
28
|
+
usage if runtime_args.empty?
|
29
|
+
|
30
|
+
@args = runtime_args.dup
|
31
|
+
assign_names!(@args.shift)
|
32
|
+
|
33
|
+
self.class.use_plugin_sources! [:reactive, :test_unit]
|
34
|
+
end
|
35
|
+
|
36
|
+
protected
|
37
|
+
# Override with your own usage banner.
|
38
|
+
def banner
|
39
|
+
"Usage: #{$0} #{spec.name} #{spec.name.camelize}Name [options]"
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
def assign_names!(name)
|
44
|
+
@name, @underscore_name = name, name.underscore
|
45
|
+
base_name, @path, @pathname, @class_nesting = extract_modules(@name)
|
46
|
+
@class_name_without_nesting, @singular_name, @plural_name = inflect_names(base_name)
|
47
|
+
if @class_nesting.empty?
|
48
|
+
@class_name = @class_name_without_nesting
|
49
|
+
@singular_class_name = @class_name_without_nesting.singularize
|
50
|
+
@plural_class_name = @class_name_without_nesting.pluralize
|
51
|
+
else
|
52
|
+
@class_name = "#{@class_nesting}::#{@class_name_without_nesting}"
|
53
|
+
@singular_class_name = "#{@class_nesting}::#{@class_name_without_nesting.singularize}"
|
54
|
+
@plural_class_name = "#{@class_nesting}::#{@class_name_without_nesting.pluralize}"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Extract modules from filesystem-style or ruby-style path:
|
59
|
+
# good/fun/stuff
|
60
|
+
# Good::Fun::Stuff
|
61
|
+
# produce the same results.
|
62
|
+
def extract_modules(name)
|
63
|
+
modules = name.include?('/') ? name.split('/') : name.split('::')
|
64
|
+
name = modules.pop
|
65
|
+
path = modules.map { |m| m.underscore }
|
66
|
+
file_path = (path + [name.underscore]).join('/')
|
67
|
+
nesting = modules.map { |m| m.camelize }.join('::')
|
68
|
+
[name, path, file_path, nesting]
|
69
|
+
end
|
70
|
+
|
71
|
+
def inflect_names(name)
|
72
|
+
camel = name.camelize
|
73
|
+
singular = camel.underscore.singularize
|
74
|
+
plural = singular.pluralize
|
75
|
+
[camel, singular, plural]
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|