my_enginery 0.2.8

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 (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