my_enginery 0.2.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (118) hide show
  1. data/.gitignore +18 -0
  2. data/.travis.yml +9 -0
  3. data/CHANGELOG.md +14 -0
  4. data/Gemfile +12 -0
  5. data/LICENSE +19 -0
  6. data/README.md +957 -0
  7. data/Rakefile +48 -0
  8. data/app/base/.pryrc +1 -0
  9. data/app/base/Gemfile +25 -0
  10. data/app/base/Rakefile +4 -0
  11. data/app/base/app.rb +8 -0
  12. data/app/base/base/boot.rb +45 -0
  13. data/app/base/base/config.rb +127 -0
  14. data/app/base/base/controllers/rear-controllers/.gitkeep +0 -0
  15. data/app/base/base/database.rb +3 -0
  16. data/app/base/base/helpers/application_helpers.rb +3 -0
  17. data/app/base/base/migrations/.gitkeep +0 -0
  18. data/app/base/base/models/.gitkeep +0 -0
  19. data/app/base/base/specs/.gitkeep +0 -0
  20. data/app/base/base/views/.gitkeep +0 -0
  21. data/app/base/config.ru +4 -0
  22. data/app/base/config/config.yml +17 -0
  23. data/app/base/public/assets/Enginery.png +0 -0
  24. data/app/base/public/assets/Espresso.png +0 -0
  25. data/app/base/public/assets/application.css +13 -0
  26. data/app/base/public/assets/application.js +2 -0
  27. data/app/base/public/assets/bootstrap/css/bootstrap-responsive.min.css +9 -0
  28. data/app/base/public/assets/bootstrap/css/bootstrap.min.css +9 -0
  29. data/app/base/public/assets/bootstrap/img/glyphicons-halflings-white.png +0 -0
  30. data/app/base/public/assets/bootstrap/img/glyphicons-halflings.png +0 -0
  31. data/app/base/public/assets/bootstrap/js/bootstrap.min.js +6 -0
  32. data/app/base/public/assets/jquery.js +6 -0
  33. data/app/base/var/db/.gitkeep +0 -0
  34. data/app/base/var/log/.gitkeep +0 -0
  35. data/app/base/var/pid/.gitkeep +0 -0
  36. data/app/database/ActiveRecord.rb +11 -0
  37. data/app/database/DataMapper.rb +11 -0
  38. data/app/database/Sequel.rb +11 -0
  39. data/app/database/mysql.yml +24 -0
  40. data/app/database/postgres.yml +24 -0
  41. data/app/database/sqlite.yml +24 -0
  42. data/app/gemfiles/ActiveRecord.rb +1 -0
  43. data/app/gemfiles/BlueCloth.rb +1 -0
  44. data/app/gemfiles/DataMapper.rb +1 -0
  45. data/app/gemfiles/FastCGI.rb +1 -0
  46. data/app/gemfiles/Puma.rb +1 -0
  47. data/app/gemfiles/RDiscount.rb +1 -0
  48. data/app/gemfiles/RDoc.rb +1 -0
  49. data/app/gemfiles/RedCloth.rb +1 -0
  50. data/app/gemfiles/WEBrick.rb +1 -0
  51. data/app/gemfiles/WikiCloth.rb +1 -0
  52. data/app/gemfiles/mysql/ActiveRecord.rb +1 -0
  53. data/app/gemfiles/mysql/DataMapper.rb +1 -0
  54. data/app/gemfiles/mysql/Sequel.rb +1 -0
  55. data/app/gemfiles/postgres/ActiveRecord.rb +1 -0
  56. data/app/gemfiles/postgres/DataMapper.rb +1 -0
  57. data/app/gemfiles/postgres/Sequel.rb +1 -0
  58. data/app/gemfiles/sqlite/ActiveRecord.rb +1 -0
  59. data/app/gemfiles/sqlite/DataMapper.rb +1 -0
  60. data/app/gemfiles/sqlite/Sequel.rb +1 -0
  61. data/app/layouts/ERB/layout.erb +56 -0
  62. data/app/layouts/Erubis/layout.erb +56 -0
  63. data/app/layouts/Haml/layout.haml +38 -0
  64. data/app/layouts/Slim/layout.slim +38 -0
  65. data/app/migrations/ActiveRecord.erb +51 -0
  66. data/app/migrations/DataMapper.erb +61 -0
  67. data/app/migrations/Sequel.erb +54 -0
  68. data/app/migrations/tracking_table/ActiveRecord.rb +19 -0
  69. data/app/migrations/tracking_table/DataMapper.rb +26 -0
  70. data/app/migrations/tracking_table/Sequel.rb +18 -0
  71. data/app/rakefiles/ActiveRecord.rb +0 -0
  72. data/app/rakefiles/DataMapper.rb +1 -0
  73. data/app/rakefiles/Sequel.rb +0 -0
  74. data/app/rakefiles/Specular.rb +1 -0
  75. data/app/specfiles/Specular.erb +7 -0
  76. data/bin/my_enginery +235 -0
  77. data/lib/enginery.rb +23 -0
  78. data/lib/enginery/cli.rb +44 -0
  79. data/lib/enginery/configurator.rb +139 -0
  80. data/lib/enginery/delete.rb +116 -0
  81. data/lib/enginery/enginery.rb +41 -0
  82. data/lib/enginery/generator.rb +325 -0
  83. data/lib/enginery/helpers/app.rb +83 -0
  84. data/lib/enginery/helpers/generic.rb +145 -0
  85. data/lib/enginery/helpers/input.rb +123 -0
  86. data/lib/enginery/helpers/orm.rb +86 -0
  87. data/lib/enginery/helpers/validations.rb +101 -0
  88. data/lib/enginery/migrator.rb +371 -0
  89. data/lib/enginery/rake-tasks/data_mapper.rb +49 -0
  90. data/lib/enginery/rake-tasks/specular.rb +41 -0
  91. data/lib/enginery/registry.rb +101 -0
  92. data/lib/enginery/usage.rb +66 -0
  93. data/lib/enginery/version.rb +7 -0
  94. data/logo.png +0 -0
  95. data/my_enginery.gemspec +37 -0
  96. data/test/delete/test__admin.rb +49 -0
  97. data/test/delete/test__controller.rb +37 -0
  98. data/test/delete/test__helper.rb +49 -0
  99. data/test/delete/test__migration.rb +27 -0
  100. data/test/delete/test__model.rb +35 -0
  101. data/test/delete/test__route.rb +35 -0
  102. data/test/delete/test__spec.rb +59 -0
  103. data/test/delete/test__view.rb +51 -0
  104. data/test/generator/test__admin.rb +39 -0
  105. data/test/generator/test__controller.rb +123 -0
  106. data/test/generator/test__helper.rb +56 -0
  107. data/test/generator/test__model.rb +206 -0
  108. data/test/generator/test__project.rb +81 -0
  109. data/test/generator/test__route.rb +110 -0
  110. data/test/generator/test__spec.rb +56 -0
  111. data/test/generator/test__view.rb +85 -0
  112. data/test/migrator/test__auto_generation.rb +41 -0
  113. data/test/migrator/test__manual_generation.rb +59 -0
  114. data/test/migrator/test__migrations.rb +139 -0
  115. data/test/sandbox/.gitkeep +0 -0
  116. data/test/setup.rb +29 -0
  117. data/test/support/spec_helpers.rb +151 -0
  118. metadata +392 -0
@@ -0,0 +1,83 @@
1
+ module Enginery
2
+ module Helpers
3
+
4
+ def load_file file
5
+ pv, $VERBOSE = $VERBOSE, nil
6
+ load file
7
+ ensure
8
+ $VERBOSE = pv
9
+ end
10
+
11
+ def load_boot_rb
12
+ orig = Array.new($:)
13
+ load_file dst_path.boot_rb
14
+ ensure
15
+ # for some reason, Bundler get rid of existing loadpath entries.
16
+ # usually this will break autoloading, so storing orig paths and inserting them back
17
+ orig.each {|p| $:.include?(p) || $: << p}
18
+ end
19
+
20
+ def boot_app
21
+ load_boot_rb
22
+ App.boot!
23
+ end
24
+
25
+ def app_controllers
26
+ App.mounted_controllers.select {|c| controller_exists?(c.name)}
27
+ end
28
+
29
+ def routes_by_controller controller
30
+ Dir[dst_path(:controllers, class_to_route(controller), '*' + ROUTE_SUFFIX)].map do |f|
31
+ File.basename(f, File.extname(f))
32
+ end
33
+ end
34
+
35
+ def controller_exists? name
36
+ path = dst_path(:controllers, class_to_route(name))
37
+ File.file?(path + CONTROLLER_SUFFIX) && path
38
+ end
39
+
40
+ def model_exists? name
41
+ path = dst_path(:models, class_to_route(name))
42
+ File.file?(path + MODEL_SUFFIX) && path
43
+ end
44
+
45
+ def app_models
46
+ load_boot_rb
47
+ identity_methods = ORM_IDENTITY_METHODS[Cfg[:orm].to_s.to_sym]
48
+ return [] unless identity_methods
49
+ ObjectSpace.each_object(Class).select do |o|
50
+ identity_methods.all? {|m| o.respond_to?(m)} && model_exists?(o.name)
51
+ end
52
+ end
53
+
54
+ def migrations_by_model model
55
+ Dir[dst_path(:migrations, class_to_route(model), '*' + MIGRATION_SUFFIX)].map do |f|
56
+ File.basename(f)
57
+ end
58
+ end
59
+
60
+ def view_setups_for ctrl, action
61
+ boot_app
62
+ ctrl_instance = ctrl.new
63
+ ctrl_instance.respond_to?(action.to_sym) || fail('"%s" route does not exists' % action)
64
+
65
+ action_name, request_method = deRESTify_action(action)
66
+ ctrl_instance.action_setup = ctrl.action_setup[action_name][request_method]
67
+ ctrl_instance.call_setups!
68
+ [
69
+ File.join(ctrl_instance.view_path?, ctrl_instance.view_prefix?),
70
+ ctrl_instance.engine_ext?
71
+ ]
72
+ end
73
+
74
+ def app_config
75
+ pv, $VERBOSE = $VERBOSE, nil
76
+ load dst_path.config_rb
77
+ Cfg
78
+ ensure
79
+ $VERBOSE = pv
80
+ end
81
+
82
+ end
83
+ end
@@ -0,0 +1,145 @@
1
+ module Enginery
2
+ class Failure
3
+ attr_reader :failures
4
+ def initialize *failures
5
+ @failures = failures
6
+ end
7
+ end
8
+
9
+ module Helpers
10
+ include EUtils
11
+
12
+ def src_path *args
13
+ @src_path_map ||= begin
14
+ paths = { :root => File.expand_path('../../../../app', __FILE__) + '/' }
15
+ [
16
+ :base,
17
+ :gemfiles,
18
+ :rakefiles,
19
+ :specfiles,
20
+ :database,
21
+ :migrations,
22
+ :layouts,
23
+ ].each {|d| paths[d] = File.join(paths[:root], d.to_s, '')}
24
+ paths.values.map(&:freeze)
25
+ [paths, Struct.new(*paths.keys).new(*paths.values)]
26
+ end
27
+ paths, struct = @src_path_map
28
+ return struct if args.empty?
29
+
30
+ paths[args.first] || fail('%s is not a recognized source path.
31
+ Use one of %s' % [args.first.inspect, paths.map(&:inspect)*', '])
32
+ File.join(paths[args.shift], *args.map(&:to_s)).gsub(/\/+/, '/').freeze
33
+ end
34
+
35
+ def dst_path *args
36
+ @dst_path_map ||= begin
37
+ paths = { :root => @dst_root.to_s.gsub(/\/+/, '/') }
38
+ [
39
+ :base,
40
+ :config,
41
+ ].each {|p| paths[p] = File.join(paths[:root], p.to_s, '')}
42
+ [
43
+ :controllers,
44
+ :models,
45
+ :views,
46
+ :specs,
47
+ :migrations,
48
+ :helpers
49
+ ].each {|d| paths[d] = File.join(paths[:base], d.to_s, '')}
50
+
51
+ paths[:rear_controllers] = File.join(paths[:controllers], 'rear-controllers', '')
52
+ paths[:config_rb] = File.join(paths[:base], 'config.rb')
53
+ paths[:config_yml] = File.join(paths[:config], 'config.yml')
54
+ paths[:database_yml] = File.join(paths[:config], 'database.yml')
55
+
56
+ [
57
+ :Rakefile,
58
+ :Gemfile,
59
+ ].each {|f| paths[f] = File.join(paths[:root], f.to_s)}
60
+ [
61
+ :boot_rb,
62
+ :database_rb,
63
+ ].each {|f| paths[f] = File.join(paths[:base], f.to_s.sub('_rb', '.rb'))}
64
+ paths.values.map(&:freeze)
65
+ [paths, Struct.new(*paths.keys).new(*paths.values)]
66
+ end
67
+ paths, struct = @dst_path_map
68
+ return struct if args.empty?
69
+
70
+ paths[args.first] || fail('%s is not a recognized destination path.
71
+ Use one of %s' % [args.first.inspect, paths.map(&:inspect)*', '])
72
+ File.join(paths[args.shift], *args.map(&:to_s)).gsub(/\/+/, '/').freeze
73
+ end
74
+
75
+ def unrootify path, root = nil
76
+ root = (root || dst_path.root).gsub(/\/+/, '/')
77
+ regexp = /\A#{Regexp.escape(root)}\/?/
78
+ path.gsub(/\/+/, '/').sub(regexp, '')
79
+ end
80
+
81
+ def o *chunks
82
+ @logger ||= Logger.new(STDOUT)
83
+ opts = chunks.last.is_a?(Hash) ? chunks.pop : {}
84
+ @logger << "%s\n" % chunks.join(opts[:join].to_s)
85
+ end
86
+ module_function :o
87
+
88
+ private
89
+
90
+ def write_file file, data
91
+ o '*** Writing "%s" ***' % unrootify(file).gsub('::', '_')
92
+ File.open(file, 'w') {|f| f << (data.respond_to?(:join) ? data.join : data)}
93
+ end
94
+
95
+ def update_file file, data
96
+ o '*** Updating "%s" ***' % unrootify(file)
97
+ File.open(file, 'a+') {|f| f << (data.respond_to?(:join) ? data.join : data)}
98
+ end
99
+
100
+ def namespace_to_source_code name
101
+ names, constants = name.split('::'), []
102
+
103
+ names.uniq.size == names.size ||
104
+ fail('%s namespace constants duplicates' % name)
105
+
106
+ names.map(&:to_sym).inject(Object) do |ns,c|
107
+ validate_constant_name(c)
108
+ c_class, next_ns = Module, nil
109
+
110
+ if ns && ns.const_defined?(c)
111
+ next_ns = ns.const_get(c)
112
+ c_class = next_ns.class
113
+ [Class, Module].include?(c_class) ||
114
+ fail('%s should be a Class or a Module. It is a %s instead' % [constants.keys*'::', c_class])
115
+ end
116
+
117
+ constants << [c, c_class.name.downcase]
118
+ next_ns
119
+ end
120
+
121
+ constant_name = constants.pop.first.to_s
122
+
123
+ before, after = [], []
124
+ constants.each do |(cn,cc)|
125
+ i = INDENT * before.size
126
+ before << '%s%s %s' % [i, cc, cn]
127
+ after << '%send' % i
128
+ end
129
+ [before, constant_name, after.reverse << '']
130
+ end
131
+
132
+ def constant_defined? name
133
+ return unless name
134
+ namespace = name.to_s.strip.sub(/\A::/, '').split('::').map {|c| validate_constant_name c}
135
+ namespace.inject(Object) do |o,c|
136
+ o.const_defined?(c.to_sym) ? o.const_get(c) : break
137
+ end
138
+ end
139
+
140
+ def output_source_code source
141
+ (source.is_a?(String) ? File.readlines(source) : source).each {|l| o "+ " + l.chomp}
142
+ end
143
+
144
+ end
145
+ end
@@ -0,0 +1,123 @@
1
+ module Enginery
2
+ module Helpers
3
+
4
+ # TODO: refactor this huge method
5
+ def parse_input *input
6
+ input.flatten!
7
+ args, setups, string_setups = [], {}, []
8
+ input.each do |a|
9
+ case
10
+
11
+ # generator
12
+ when a =~ /\Ao(rm)?:/
13
+ orm = extract_setup(a)
14
+ if valid_orm = valid_orm?(orm)
15
+ setups[:orm] = valid_orm
16
+ string_setups << a
17
+ else
18
+ fail_verbosely 'Invalid ORM provided - "%s"' % orm, \
19
+ 'Supported ORMs: ActiveRecord, DataMapper, Sequel'
20
+ end
21
+ when a =~ /\Ae(ngine)?:/
22
+ smth = extract_setup(a)
23
+ if engine = valid_engine?(smth)
24
+ setups[:engine] = engine
25
+ string_setups << a
26
+ else
27
+ fail_verbosely 'Invalid engine provided - %s' % smth, \
28
+ 'Supported engines(Case Sensitive): %s' % EConstants::VIEW__ENGINE_BY_SYM.keys.join(', ')
29
+ end
30
+ when a =~ /\Af(ormat|ile)?:/
31
+ if format = extract_setup(a)
32
+ # format if used by generator, file is used by migrator
33
+ setups[:format] = setups[:file] = format
34
+ string_setups << a
35
+ end
36
+ when a =~ /\Ar(oute)?:/
37
+ if route = extract_setup(a)
38
+ setups[:route] = route
39
+ string_setups << a
40
+ end
41
+ when a =~ /\Adb/
42
+ [:type, :host, :port, :name, :user, :pass].each do |s|
43
+ if (a =~ /\Adb(_)?#{s}:/) && (v = extract_setup(a))
44
+ (setups[:db] ||= {}).update s => (s == :type ? valid_db_type?(v) : v)
45
+ string_setups << a
46
+ end
47
+ end
48
+ when a =~ /\As(erver)?:/
49
+ smth = extract_setup(a)
50
+ if server = valid_server?(smth)
51
+ setups[:server] = server.to_sym
52
+ string_setups << a
53
+ else
54
+ fail_verbosely 'Unknown server provided - %s' % smth, \
55
+ 'It wont be added to Gemfile nor to config.yml', \
56
+ 'Known servers(Case Sensitive): %s' % KNOWN_WEB_SERVERS.join(', ')
57
+ end
58
+ when a =~ /\Ap(ort)?:/
59
+ smth = extract_setup(a)
60
+ if (port = smth.to_i) > 0
61
+ setups[:port] = port
62
+ string_setups << a
63
+ else
64
+ fail_verbosely 'Invalid port provided - %s' % smth, 'Port should be a number'
65
+ end
66
+ when a =~ /\Ah(ost(s)?)?:/
67
+ if hosts = extract_setup(a)
68
+ setups[:hosts] = hosts.split(',')
69
+ string_setups << a
70
+ end
71
+ when a =~ /\Ai(nclude)?:/
72
+ mdl = validate_constant_name extract_setup(a)
73
+ (setups[:include] ||= []).push mdl
74
+ string_setups << a
75
+
76
+ # migrator
77
+ when a =~ /\Acreate_table_for:/
78
+ if table = extract_setup(a)
79
+ setups[:create_table] = table
80
+ string_setups << a
81
+ end
82
+ when a =~ /\Am(odel)?:/
83
+ if table = extract_setup(a)
84
+ setups[:update_table] = table
85
+ string_setups << a
86
+ end
87
+ when a =~ /\Aa?(dd_)?c(olumn)?:/
88
+ if column = extract_setup(a)
89
+ (setups[:create_columns] ||= []).push column.split(':')
90
+ string_setups << a
91
+ end
92
+ when a =~ /\Au(pdate_)?c?(olumn)?:/
93
+ if column = extract_setup(a)
94
+ (setups[:update_columns] ||= []).push column.split(':')
95
+ string_setups << a
96
+ end
97
+ when a =~ /\Ar(ename_)?c?(olumn)?:/
98
+ if column = extract_setup(a)
99
+ (setups[:rename_columns] ||= []).push column.split(':')
100
+ string_setups << a
101
+ end
102
+ else
103
+ args.push(a) unless ORM_ASSOCIATIONS.find {|an| a =~ /#{an}/}
104
+ end
105
+ end
106
+ ORM_ASSOCIATIONS.each do |a|
107
+ input.select {|x| x =~ /\A#{a}:/}.each do |s|
108
+ next unless v = extract_setup(s)
109
+ (setups[a] ||= []).push v
110
+ string_setups << s
111
+ end
112
+ end
113
+ [args.freeze, setups.freeze, string_setups.join(' ').freeze]
114
+ end
115
+ module_function :parse_input
116
+
117
+ def extract_setup input
118
+ input.scan(/:(.+)/).flatten.last
119
+ end
120
+ module_function :extract_setup
121
+
122
+ end
123
+ end
@@ -0,0 +1,86 @@
1
+ module Enginery
2
+ module Helpers
3
+
4
+ def activerecord_associations setups = {}
5
+ ORM_ASSOCIATIONS.inject([]) do |lines,a|
6
+ (setups[a]||[]).each do |s|
7
+ line, input = nil, s.split(':')
8
+ target = input[0]
9
+ if target =~ /\W/
10
+ o '*** WARN: invalid association target "%s", association not added ***' % target
11
+ else
12
+ line = '%s :%s' % [a, target]
13
+ if through = input[1].to_s =~ /through/ && input[2]
14
+ if through =~ /\W/
15
+ o '*** WARN: invalid :through option "%s", association not added ***' % through
16
+ line = nil
17
+ else
18
+ line << ', through: :%s' % through
19
+ end
20
+ end
21
+ end
22
+ lines.push(line) if line
23
+ end
24
+ lines
25
+ end
26
+ end
27
+
28
+ def datamapper_associations setups = {}
29
+ ORM_ASSOCIATIONS.inject([]) do |lines,a|
30
+ (setups[a]||[]).each do |s|
31
+ line, input = nil, s.split(':')
32
+ target = input[0]
33
+ if target =~ /\W/
34
+ o '*** WARN: invalid association target "%s", association not added ***' % target
35
+ else
36
+ if a == :has_one
37
+ line = 'has 1, :%s' % target
38
+ elsif a =~ /has_(and|many)/
39
+ line = 'has n, :%s' % target
40
+ else
41
+ line = '%s :%s' % [a, target]
42
+ end
43
+ if through = input[1].to_s =~ /through/ && input[2]
44
+ if through =~ /\W/
45
+ o '*** WARN: invalid :through option "%s", association not added ***' % through
46
+ line = nil
47
+ else
48
+ line << ', through: :%s' % through
49
+ end
50
+ end
51
+ end
52
+ lines.push(line) if line
53
+ end
54
+ lines
55
+ end
56
+ end
57
+
58
+ def sequel_associations setups = {}
59
+ ORM_ASSOCIATIONS.inject([]) do |lines,a|
60
+ (setups[a]||[]).each do |s|
61
+ line, input = nil, s.split(':')
62
+ target = input[0]
63
+ if target =~ /\W/
64
+ o '*** WARN: invalid association target "%s", association not added ***' % target
65
+ else
66
+ case a
67
+ when :belongs_to
68
+ line = 'many_to_one :%s' % target
69
+ when :has_one
70
+ line = 'one_to_one :%s' % target
71
+ when :has_many
72
+ line = 'one_to_many :%s' % target
73
+ when :has_and_belongs_to_many
74
+ line = 'many_to_many :%s' % target
75
+ end
76
+ if through = input[1].to_s =~ /through/ && input[2]
77
+ o '*** INFO: Sequel does not support :through option, ignoring ***' % through
78
+ end
79
+ end
80
+ lines.push(line) if line
81
+ end
82
+ lines
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,101 @@
1
+ module Enginery
2
+ module Helpers
3
+
4
+ def in_app_folder?
5
+ File.directory?(dst_path.controllers)
6
+ end
7
+
8
+ def fail_unless_in_app_folder!
9
+ in_app_folder? || fail("Seems current folder does not contain a Espresso application")
10
+ end
11
+
12
+ def fail *failures
13
+ throw :enginery_failures, Failure.new(*failures)
14
+ end
15
+ module_function :fail
16
+
17
+ def fail_verbosely *failures
18
+ o *failures
19
+ fail *failures
20
+ end
21
+ module_function :fail_verbosely
22
+
23
+ def valid_server? smth
24
+ server = smth.to_s.to_sym
25
+ KNOWN_WEB_SERVERS.include?(server) ? server : false
26
+ end
27
+ module_function :valid_server?
28
+
29
+ def valid_orm? smth
30
+ return unless smth.is_a?(String) || smth.is_a?(Symbol)
31
+ case
32
+ when smth =~ /\Aa/i
33
+ :ActiveRecord
34
+ when smth =~ /\Ad/i
35
+ :DataMapper
36
+ when smth =~ /\As/i
37
+ :Sequel
38
+ end
39
+ end
40
+ module_function :valid_orm?
41
+
42
+ def valid_db_type? smth
43
+ return unless smth.is_a?(String) || smth.is_a?(Symbol)
44
+ case
45
+ when smth =~ /\Am/i
46
+ :mysql
47
+ when smth =~ /\Ap/i
48
+ :postgres
49
+ when smth =~ /\As/i
50
+ :sqlite
51
+ end
52
+ end
53
+ module_function :valid_db_type?
54
+
55
+ def valid_engine? smth
56
+ engine = smth.to_s.to_sym
57
+ EConstants::VIEW__ENGINE_BY_SYM.has_key?(engine) ? engine : false
58
+ end
59
+ module_function :valid_engine?
60
+
61
+ def valid_controller? name
62
+ name.nil? || name.empty? && fail("Please provide controller name")
63
+ ctrl_path = controller_exists?(name) || fail('"%s" controller does not exists' % name)
64
+
65
+ ctrl = name.split('::').map(&:to_sym).inject(Object) do |ns,c|
66
+ ctrl_dirname = unrootify(ctrl_path)
67
+ ns.const_defined?(c) || fail("#{ctrl_dirname} exists but #{name} controller not defined.
68
+ Please define it manually or delete #{ctrl_dirname} and start over.")
69
+ ns.const_get(c)
70
+ end
71
+ [ctrl_path, ctrl]
72
+ end
73
+
74
+ def valid_route? ctrl_name, name
75
+ ctrl_path, ctrl = valid_controller?(ctrl_name)
76
+ name.nil? || name.empty? && fail("Please provide route name")
77
+ path_rules = ctrl.path_rules.inject({}) do |map,(r,s)|
78
+ map.merge %r[#{Regexp.escape s}] => r.source
79
+ end
80
+ route = action_to_route(name, path_rules)
81
+ validate_route_name(route)
82
+ file = File.join(ctrl_path, route + '.rb')
83
+ [file, route]
84
+ end
85
+
86
+ def validate_constant_name constant
87
+ constant =~ /[^\w|\d|\:]/ && fail("Wrong constant name - %s, it should contain only alphanumerics" % constant)
88
+ constant =~ /\A[0-9]/ && fail("Wrong constant name - %s, it should start with a letter" % constant)
89
+ constant =~ /\A[A-Z]/ || fail("Wrong constant name - %s, it should start with a uppercase letter" % constant)
90
+ constant
91
+ end
92
+ module_function :validate_constant_name
93
+
94
+ def validate_route_name name
95
+ name =~ /\W/ && fail("Routes may contain only alphanumerics")
96
+ name
97
+ end
98
+
99
+
100
+ end
101
+ end