module Enginery::Helpers
Public Class Methods
extract_setup(input)
click to toggle source
# File lib/enginery/helpers/input.rb, line 117 def extract_setup input input.scan(/:(.+)/).flatten.last end
fail(*failures)
click to toggle source
# File lib/enginery/helpers/validations.rb, line 12 def fail *failures throw :enginery_failures, Failure.new(*failures) end
fail_verbosely(*failures)
click to toggle source
# File lib/enginery/helpers/validations.rb, line 17 def fail_verbosely *failures o *failures fail *failures end
o(*chunks)
click to toggle source
# File lib/enginery/helpers/generic.rb, line 93 def o *chunks @logger ||= Logger.new(STDOUT) opts = chunks.last.is_a?(Hash) ? chunks.pop : {} @logger << "%s\n" % chunks.join(opts[:join].to_s) end
parse_input(*input)
click to toggle source
TODO: refactor this huge method
# File lib/enginery/helpers/input.rb, line 5 def parse_input *input input.flatten! args, setups, string_setups = [], {}, [] input.each do |a| case # generator when a =~ /\Ao(rm)?:/ orm = extract_setup(a) if valid_orm = valid_orm?(orm) setups[:orm] = valid_orm string_setups << a else fail_verbosely 'Invalid ORM provided - "%s"' % orm, \ 'Supported ORMs: ActiveRecord, DataMapper, Sequel' end when a =~ /\Ae(ngine)?:/ smth = extract_setup(a) if engine = valid_engine?(smth) setups[:engine] = engine string_setups << a else fail_verbosely 'Invalid engine provided - %s' % smth, \ 'Supported engines(Case Sensitive): %s' % EConstants::VIEW__ENGINE_BY_SYM.keys.join(', ') end when a =~ /\Af(ormat|ile)?:/ if format = extract_setup(a) # format if used by generator, file is used by migrator setups[:format] = setups[:file] = format string_setups << a end when a =~ /\Ar(oute)?:/ if route = extract_setup(a) setups[:route] = route string_setups << a end when a =~ /\Adb/ [:type, :host, :port, :name, :user, :pass].each do |s| if (a =~ /\Adb(_)?#{s}:/) && (v = extract_setup(a)) (setups[:db] ||= {}).update s => (s == :type ? valid_db_type?(v) : v) string_setups << a end end when a =~ /\As(erver)?:/ smth = extract_setup(a) if server = valid_server?(smth) setups[:server] = server.to_sym string_setups << a else fail_verbosely 'Unknown server provided - %s' % smth, \ 'It wont be added to Gemfile nor to config.yml', \ 'Known servers(Case Sensitive): %s' % KNOWN_WEB_SERVERS.join(', ') end when a =~ /\Ap(ort)?:/ smth = extract_setup(a) if (port = smth.to_i) > 0 setups[:port] = port string_setups << a else fail_verbosely 'Invalid port provided - %s' % smth, 'Port should be a number' end when a =~ /\Ah(ost(s)?)?:/ if hosts = extract_setup(a) setups[:hosts] = hosts.split(',') string_setups << a end when a =~ /\Ai(nclude)?:/ mdl = validate_constant_name extract_setup(a) (setups[:include] ||= []).push mdl string_setups << a # migrator when a =~ /\Acreate_table_for:/ if table = extract_setup(a) setups[:create_table] = table string_setups << a end when a =~ /\Am(odel)?:/ if table = extract_setup(a) setups[:update_table] = table string_setups << a end when a =~ /\Aa?(dd_)?c(olumn)?:/ if column = extract_setup(a) (setups[:create_columns] ||= []).push column.split(':') string_setups << a end when a =~ /\Au(pdate_)?c?(olumn)?:/ if column = extract_setup(a) (setups[:update_columns] ||= []).push column.split(':') string_setups << a end when a =~ /\Ar(ename_)?c?(olumn)?:/ if column = extract_setup(a) (setups[:rename_columns] ||= []).push column.split(':') string_setups << a end else args.push(a) unless ORM_ASSOCIATIONS.find {|an| a =~ /#{an}/} end end ORM_ASSOCIATIONS.each do |a| input.select {|x| x =~ /\A#{a}:/}.each do |s| next unless v = extract_setup(s) (setups[a] ||= []).push v string_setups << s end end [args.freeze, setups.freeze, string_setups.join(' ').freeze] end
valid_db_type?(smth)
click to toggle source
# File lib/enginery/helpers/validations.rb, line 42 def valid_db_type? smth return unless smth.is_a?(String) || smth.is_a?(Symbol) case when smth =~ /\Am/i :mysql when smth =~ /\Ap/i :postgres when smth =~ /\As/i :sqlite end end
valid_engine?(smth)
click to toggle source
# File lib/enginery/helpers/validations.rb, line 55 def valid_engine? smth engine = smth.to_s.to_sym EConstants::VIEW__ENGINE_BY_SYM.has_key?(engine) ? engine : false end
valid_orm?(smth)
click to toggle source
# File lib/enginery/helpers/validations.rb, line 29 def valid_orm? smth return unless smth.is_a?(String) || smth.is_a?(Symbol) case when smth =~ /\Aa/i :ActiveRecord when smth =~ /\Ad/i :DataMapper when smth =~ /\As/i :Sequel end end
valid_server?(smth)
click to toggle source
# File lib/enginery/helpers/validations.rb, line 23 def valid_server? smth server = smth.to_s.to_sym KNOWN_WEB_SERVERS.include?(server) ? server : false end
validate_constant_name(constant)
click to toggle source
# File lib/enginery/helpers/validations.rb, line 86 def validate_constant_name constant constant =~ /[^\w|\d|\:]/ && fail("Wrong constant name - %s, it should contain only alphanumerics" % constant) constant =~ /\A[0-9]/ && fail("Wrong constant name - %s, it should start with a letter" % constant) constant =~ /\A[A-Z]/ || fail("Wrong constant name - %s, it should start with a uppercase letter" % constant) constant end
Public Instance Methods
activerecord_associations(setups = {})
click to toggle source
# File lib/enginery/helpers/orm.rb, line 4 def activerecord_associations setups = {} ORM_ASSOCIATIONS.inject([]) do |lines,a| (setups[a]||[]).each do |s| line, input = nil, s.split(':') target = input[0] if target =~ /\W/ o '*** WARN: invalid association target "%s", association not added ***' % target else line = '%s :%s' % [a, target] if through = input[1].to_s =~ /through/ && input[2] if through =~ /\W/ o '*** WARN: invalid :through option "%s", association not added ***' % through line = nil else line << ', through: :%s' % through end end end lines.push(line) if line end lines end end
app_config()
click to toggle source
# File lib/enginery/helpers/app.rb, line 70 def app_config pv, $VERBOSE = $VERBOSE, nil load dst_path.config_rb Cfg ensure $VERBOSE = pv end
app_controllers()
click to toggle source
# File lib/enginery/helpers/app.rb, line 21 def app_controllers App.mounted_controllers.select {|c| controller_exists?(c.name)} end
app_models()
click to toggle source
# File lib/enginery/helpers/app.rb, line 41 def app_models load_boot_rb identity_methods = ORM_IDENTITY_METHODS[Cfg[:orm].to_s.to_sym] return [] unless identity_methods ObjectSpace.each_object(Class).select do |o| identity_methods.all? {|m| o.respond_to?(m)} && model_exists?(o.name) end end
boot_app()
click to toggle source
# File lib/enginery/helpers/app.rb, line 16 def boot_app load_boot_rb App.boot! end
controller_exists?(name)
click to toggle source
# File lib/enginery/helpers/app.rb, line 31 def controller_exists? name path = dst_path(:controllers, class_to_route(name)) File.file?(path + CONTROLLER_SUFFIX) && path end
datamapper_associations(setups = {})
click to toggle source
# File lib/enginery/helpers/orm.rb, line 28 def datamapper_associations setups = {} ORM_ASSOCIATIONS.inject([]) do |lines,a| (setups[a]||[]).each do |s| line, input = nil, s.split(':') target = input[0] if target =~ /\W/ o '*** WARN: invalid association target "%s", association not added ***' % target else if a == :has_one line = 'has 1, :%s' % target elsif a =~ /has_(and|many)/ line = 'has n, :%s' % target else line = '%s :%s' % [a, target] end if through = input[1].to_s =~ /through/ && input[2] if through =~ /\W/ o '*** WARN: invalid :through option "%s", association not added ***' % through line = nil else line << ', through: :%s' % through end end end lines.push(line) if line end lines end end
dst_path(*args)
click to toggle source
# File lib/enginery/helpers/generic.rb, line 35 def dst_path *args @dst_path_map ||= begin paths = { :root => @dst_root.to_s.gsub(/\/+/, '/') } [ :base, :config, ].each {|p| paths[p] = File.join(paths[:root], p.to_s, '')} [ :controllers, :models, :views, :specs, :migrations, :helpers ].each {|d| paths[d] = File.join(paths[:base], d.to_s, '')} paths[:rear_controllers] = File.join(paths[:controllers], 'rear-controllers', '') paths[:config_rb] = File.join(paths[:base], 'config.rb') paths[:config_yml] = File.join(paths[:config], 'config.yml') paths[:database_yml] = File.join(paths[:config], 'database.yml') [ :Rakefile, :Gemfile, ].each {|f| paths[f] = File.join(paths[:root], f.to_s)} [ :boot_rb, :database_rb, ].each {|f| paths[f] = File.join(paths[:base], f.to_s.sub('_rb', '.rb'))} paths.values.map(&:freeze) [paths, Struct.new(*paths.keys).new(*paths.values)] end paths, struct = @dst_path_map return struct if args.empty? paths[args.first] || fail('%s is not a recognized destination path. Use one of %s' % [args.first.inspect, paths.map(&:inspect)*', ']) File.join(paths[args.shift], *args.map(&:to_s)).gsub(/\/+/, '/').freeze end
fail_unless_in_app_folder!()
click to toggle source
# File lib/enginery/helpers/validations.rb, line 8 def fail_unless_in_app_folder! in_app_folder? || fail("Seems current folder does not contain a Espresso application") end
in_app_folder?()
click to toggle source
# File lib/enginery/helpers/validations.rb, line 4 def in_app_folder? File.directory?(dst_path.controllers) end
load_boot_rb()
click to toggle source
# File lib/enginery/helpers/app.rb, line 4 def load_boot_rb pv, $VERBOSE = $VERBOSE, nil orig = Array.new($:) # loading app load dst_path.boot_rb # for some reason, Bundler get rid of existing loadpath entries. # usually this will break autoloading, so storing orig paths and inserting them back orig.each {|p| $:.include?(p) || $: << p} ensure $VERBOSE = pv end
migrations_by_model(model)
click to toggle source
# File lib/enginery/helpers/app.rb, line 50 def migrations_by_model model Dir[dst_path(:migrations, class_to_route(model), '*' + MIGRATION_SUFFIX)].map do |f| File.basename(f) end end
model_exists?(name)
click to toggle source
# File lib/enginery/helpers/app.rb, line 36 def model_exists? name path = dst_path(:models, class_to_route(name)) File.file?(path + MODEL_SUFFIX) && path end
routes_by_controller(controller)
click to toggle source
# File lib/enginery/helpers/app.rb, line 25 def routes_by_controller controller Dir[dst_path(:controllers, class_to_route(controller), '*' + ROUTE_SUFFIX)].map do |f| File.basename(f, File.extname(f)) end end
sequel_associations(setups = {})
click to toggle source
# File lib/enginery/helpers/orm.rb, line 58 def sequel_associations setups = {} ORM_ASSOCIATIONS.inject([]) do |lines,a| (setups[a]||[]).each do |s| line, input = nil, s.split(':') target = input[0] if target =~ /\W/ o '*** WARN: invalid association target "%s", association not added ***' % target else case a when :belongs_to line = 'many_to_one :%s' % target when :has_one line = 'one_to_one :%s' % target when :has_many line = 'one_to_many :%s' % target when :has_and_belongs_to_many line = 'many_to_many :%s' % target end if through = input[1].to_s =~ /through/ && input[2] o '*** INFO: Sequel does not support :through option, ignoring ***' % through end end lines.push(line) if line end lines end end
src_path(*args)
click to toggle source
# File lib/enginery/helpers/generic.rb, line 12 def src_path *args @src_path_map ||= begin paths = { :root => File.expand_path('../../../../app', __FILE__) + '/' } [ :base, :gemfiles, :rakefiles, :specfiles, :database, :migrations, :layouts, ].each {|d| paths[d] = File.join(paths[:root], d.to_s, '')} paths.values.map(&:freeze) [paths, Struct.new(*paths.keys).new(*paths.values)] end paths, struct = @src_path_map return struct if args.empty? paths[args.first] || fail('%s is not a recognized source path. Use one of %s' % [args.first.inspect, paths.map(&:inspect)*', ']) File.join(paths[args.shift], *args.map(&:to_s)).gsub(/\/+/, '/').freeze end
unrootify(path, root = nil)
click to toggle source
# File lib/enginery/helpers/generic.rb, line 75 def unrootify path, root = nil root = (root || dst_path.root).gsub(/\/+/, '/') regexp = /\A#{Regexp.escape(root)}\/?/ path.gsub(/\/+/, '/').sub(regexp, '') end
valid_controller?(name)
click to toggle source
# File lib/enginery/helpers/validations.rb, line 61 def valid_controller? name name.nil? || name.empty? && fail("Please provide controller name") ctrl_path = controller_exists?(name) || fail('"%s" controller does not exists' % name) ctrl = name.split('::').map(&:to_sym).inject(Object) do |ns,c| ctrl_dirname = unrootify(ctrl_path) ns.const_defined?(c) || fail("#{ctrl_dirname} exists but #{name} controller not defined. Please define it manually or delete #{ctrl_dirname} and start over.") ns.const_get(c) end [ctrl_path, ctrl] end
valid_route?(ctrl_name, name)
click to toggle source
# File lib/enginery/helpers/validations.rb, line 74 def valid_route? ctrl_name, name ctrl_path, ctrl = valid_controller?(ctrl_name) name.nil? || name.empty? && fail("Please provide route name") path_rules = ctrl.path_rules.inject({}) do |map,(r,s)| map.merge %r[#{Regexp.escape s}] => r.source end route = action_to_route(name, path_rules) validate_route_name(route) file = File.join(ctrl_path, route + '.rb') [file, route] end
validate_route_name(name)
click to toggle source
# File lib/enginery/helpers/validations.rb, line 94 def validate_route_name name name =~ /\W/ && fail("Routes may contain only alphanumerics") name end
view_setups_for(ctrl, action)
click to toggle source
# File lib/enginery/helpers/app.rb, line 56 def view_setups_for ctrl, action boot_app ctrl_instance = ctrl.new ctrl_instance.respond_to?(action.to_sym) || fail('"%s" route does not exists' % action) action_name, request_method = deRESTify_action(action) ctrl_instance.action_setup = ctrl.action_setup[action_name][request_method] ctrl_instance.call_setups! [ File.join(ctrl_instance.view_path?, ctrl_instance.view_prefix?), ctrl_instance.engine_ext? ] end
Private Instance Methods
constant_defined?(name)
click to toggle source
# File lib/enginery/helpers/generic.rb, line 132 def constant_defined? name return unless name namespace = name.to_s.strip.sub(/\A::/, '').split('::').map {|c| validate_constant_name c} namespace.inject(Object) do |o,c| o.const_defined?(c.to_sym) ? o.const_get(c) : break end end
extract_setup(input)
click to toggle source
# File lib/enginery/helpers/input.rb, line 117 def extract_setup input input.scan(/:(.+)/).flatten.last end
fail(*failures)
click to toggle source
# File lib/enginery/helpers/validations.rb, line 12 def fail *failures throw :enginery_failures, Failure.new(*failures) end
fail_verbosely(*failures)
click to toggle source
# File lib/enginery/helpers/validations.rb, line 17 def fail_verbosely *failures o *failures fail *failures end
namespace_to_source_code(name)
click to toggle source
# File lib/enginery/helpers/generic.rb, line 100 def namespace_to_source_code name names, constants = name.split('::'), [] names.uniq.size == names.size || fail('%s namespace constants duplicates' % name) names.map(&:to_sym).inject(Object) do |ns,c| validate_constant_name(c) c_class, next_ns = Module, nil if ns && ns.const_defined?(c) next_ns = ns.const_get(c) c_class = next_ns.class [Class, Module].include?(c_class) || fail('%s should be a Class or a Module. It is a %s instead' % [constants.keys*'::', c_class]) end constants << [c, c_class.name.downcase] next_ns end constant_name = constants.pop.first.to_s before, after = [], [] constants.each do |(cn,cc)| i = INDENT * before.size before << '%s%s %s' % [i, cc, cn] after << '%send' % i end [before, constant_name, after.reverse << ''] end
o(*chunks)
click to toggle source
# File lib/enginery/helpers/generic.rb, line 93 def o *chunks @logger ||= Logger.new(STDOUT) opts = chunks.last.is_a?(Hash) ? chunks.pop : {} @logger << "%s\n" % chunks.join(opts[:join].to_s) end
output_source_code(source)
click to toggle source
# File lib/enginery/helpers/generic.rb, line 140 def output_source_code source (source.is_a?(String) ? File.readlines(source) : source).each {|l| o "+ " + l.chomp} end
parse_input(*input)
click to toggle source
TODO: refactor this huge method
# File lib/enginery/helpers/input.rb, line 5 def parse_input *input input.flatten! args, setups, string_setups = [], {}, [] input.each do |a| case # generator when a =~ /\Ao(rm)?:/ orm = extract_setup(a) if valid_orm = valid_orm?(orm) setups[:orm] = valid_orm string_setups << a else fail_verbosely 'Invalid ORM provided - "%s"' % orm, \ 'Supported ORMs: ActiveRecord, DataMapper, Sequel' end when a =~ /\Ae(ngine)?:/ smth = extract_setup(a) if engine = valid_engine?(smth) setups[:engine] = engine string_setups << a else fail_verbosely 'Invalid engine provided - %s' % smth, \ 'Supported engines(Case Sensitive): %s' % EConstants::VIEW__ENGINE_BY_SYM.keys.join(', ') end when a =~ /\Af(ormat|ile)?:/ if format = extract_setup(a) # format if used by generator, file is used by migrator setups[:format] = setups[:file] = format string_setups << a end when a =~ /\Ar(oute)?:/ if route = extract_setup(a) setups[:route] = route string_setups << a end when a =~ /\Adb/ [:type, :host, :port, :name, :user, :pass].each do |s| if (a =~ /\Adb(_)?#{s}:/) && (v = extract_setup(a)) (setups[:db] ||= {}).update s => (s == :type ? valid_db_type?(v) : v) string_setups << a end end when a =~ /\As(erver)?:/ smth = extract_setup(a) if server = valid_server?(smth) setups[:server] = server.to_sym string_setups << a else fail_verbosely 'Unknown server provided - %s' % smth, \ 'It wont be added to Gemfile nor to config.yml', \ 'Known servers(Case Sensitive): %s' % KNOWN_WEB_SERVERS.join(', ') end when a =~ /\Ap(ort)?:/ smth = extract_setup(a) if (port = smth.to_i) > 0 setups[:port] = port string_setups << a else fail_verbosely 'Invalid port provided - %s' % smth, 'Port should be a number' end when a =~ /\Ah(ost(s)?)?:/ if hosts = extract_setup(a) setups[:hosts] = hosts.split(',') string_setups << a end when a =~ /\Ai(nclude)?:/ mdl = validate_constant_name extract_setup(a) (setups[:include] ||= []).push mdl string_setups << a # migrator when a =~ /\Acreate_table_for:/ if table = extract_setup(a) setups[:create_table] = table string_setups << a end when a =~ /\Am(odel)?:/ if table = extract_setup(a) setups[:update_table] = table string_setups << a end when a =~ /\Aa?(dd_)?c(olumn)?:/ if column = extract_setup(a) (setups[:create_columns] ||= []).push column.split(':') string_setups << a end when a =~ /\Au(pdate_)?c?(olumn)?:/ if column = extract_setup(a) (setups[:update_columns] ||= []).push column.split(':') string_setups << a end when a =~ /\Ar(ename_)?c?(olumn)?:/ if column = extract_setup(a) (setups[:rename_columns] ||= []).push column.split(':') string_setups << a end else args.push(a) unless ORM_ASSOCIATIONS.find {|an| a =~ /#{an}/} end end ORM_ASSOCIATIONS.each do |a| input.select {|x| x =~ /\A#{a}:/}.each do |s| next unless v = extract_setup(s) (setups[a] ||= []).push v string_setups << s end end [args.freeze, setups.freeze, string_setups.join(' ').freeze] end
update_file(file, data)
click to toggle source
# File lib/enginery/helpers/generic.rb, line 88 def update_file file, data o '*** Updating "%s" ***' % unrootify(file) File.open(file, 'a+') {|f| f << (data.respond_to?(:join) ? data.join : data)} end
valid_db_type?(smth)
click to toggle source
# File lib/enginery/helpers/validations.rb, line 42 def valid_db_type? smth return unless smth.is_a?(String) || smth.is_a?(Symbol) case when smth =~ /\Am/i :mysql when smth =~ /\Ap/i :postgres when smth =~ /\As/i :sqlite end end
valid_engine?(smth)
click to toggle source
# File lib/enginery/helpers/validations.rb, line 55 def valid_engine? smth engine = smth.to_s.to_sym EConstants::VIEW__ENGINE_BY_SYM.has_key?(engine) ? engine : false end
valid_orm?(smth)
click to toggle source
# File lib/enginery/helpers/validations.rb, line 29 def valid_orm? smth return unless smth.is_a?(String) || smth.is_a?(Symbol) case when smth =~ /\Aa/i :ActiveRecord when smth =~ /\Ad/i :DataMapper when smth =~ /\As/i :Sequel end end
valid_server?(smth)
click to toggle source
# File lib/enginery/helpers/validations.rb, line 23 def valid_server? smth server = smth.to_s.to_sym KNOWN_WEB_SERVERS.include?(server) ? server : false end
validate_constant_name(constant)
click to toggle source
# File lib/enginery/helpers/validations.rb, line 86 def validate_constant_name constant constant =~ /[^\w|\d|\:]/ && fail("Wrong constant name - %s, it should contain only alphanumerics" % constant) constant =~ /\A[0-9]/ && fail("Wrong constant name - %s, it should start with a letter" % constant) constant =~ /\A[A-Z]/ || fail("Wrong constant name - %s, it should start with a uppercase letter" % constant) constant end
write_file(file, data)
click to toggle source
# File lib/enginery/helpers/generic.rb, line 83 def write_file file, data o '*** Writing "%s" ***' % unrootify(file).gsub('::', '_') File.open(file, 'w') {|f| f << (data.respond_to?(:join) ? data.join : data)} end