From 93c4226a66cc4b24fb0992a55f43090ccf388bde Mon Sep 17 00:00:00 2001 From: Kristian Meier Date: Mon, 5 Sep 2011 10:43:09 +0530 Subject: [PATCH] initial commit --- .gitignore | 3 + MIT-LICENSE | 20 +++ README.md | 64 +++++++ TODO | 9 + features/generators.feature | 6 + features/step_definitions/ruby_maven.rb | 170 ++++++++++++++++++ features/step_definitions/simple_steps.rb | 82 +++++++++ ixtlan-generators.gemspec | 31 ++++ ixtlan-generators.gemspec.files | 1 + lib/generators/ixtlan/base.rb | 45 +++++ .../configuration_model_generator.rb | 12 ++ .../configuration_scaffold_generator.rb | 12 ++ .../ixtlan/setup/setup_generator.rb | 38 ++++ .../templates/application_layout.html.erb | 17 ++ .../setup/templates/database.yml.example | 48 +++++ .../ixtlan/setup/templates/error.html.erb | 1 + .../templates/error_with_session.html.erb | 1 + .../ixtlan/setup/templates/gitignore | 2 + .../ixtlan/setup/templates/initializer.rb | 64 +++++++ .../ixtlan/setup/templates/preinitializer.rb | 31 ++++ .../setup/templates/production.yml.example | 8 + .../ixtlan/setup/templates/stale.html.erb | 2 + lib/generators/model/model_generator.rb | 12 ++ .../active_record/active_record_generator.rb | 40 +++++ .../rails/active_record/model/migration.rb | 19 ++ .../rails/active_record/model/model.rb | 16 ++ lib/generators/rails/erb/erb_generator.rb | 37 ++++ .../rails/erb/scaffold/_form.html.erb | 28 +++ .../rails/erb/scaffold/edit.html.erb | 24 +++ .../rails/erb/scaffold/index.html.erb | 49 +++++ .../rails/erb/scaffold/new.html.erb | 11 ++ .../rails/erb/scaffold/show.html.erb | 30 ++++ .../scaffold_controller/controller.rb | 129 +++++++++++++ .../singleton_controller.rb | 43 +++++ lib/generators/scaffold/scaffold_generator.rb | 35 ++++ .../scaffold_controller_generator.rb | 34 ++++ lib/ixtlan-generators.rb | 3 + lib/ixtlan/railtie.rb | 9 + templates/generators.template | 6 + 39 files changed, 1192 insertions(+) create mode 100644 .gitignore create mode 100644 MIT-LICENSE create mode 100644 README.md create mode 100644 TODO create mode 100644 features/generators.feature create mode 100644 features/step_definitions/ruby_maven.rb create mode 100644 features/step_definitions/simple_steps.rb create mode 100644 ixtlan-generators.gemspec create mode 100644 ixtlan-generators.gemspec.files create mode 100644 lib/generators/ixtlan/base.rb create mode 100644 lib/generators/ixtlan/configuration_model/configuration_model_generator.rb create mode 100644 lib/generators/ixtlan/configuration_scaffold/configuration_scaffold_generator.rb create mode 100644 lib/generators/ixtlan/setup/setup_generator.rb create mode 100644 lib/generators/ixtlan/setup/templates/application_layout.html.erb create mode 100644 lib/generators/ixtlan/setup/templates/database.yml.example create mode 100644 lib/generators/ixtlan/setup/templates/error.html.erb create mode 100644 lib/generators/ixtlan/setup/templates/error_with_session.html.erb create mode 100644 lib/generators/ixtlan/setup/templates/gitignore create mode 100644 lib/generators/ixtlan/setup/templates/initializer.rb create mode 100644 lib/generators/ixtlan/setup/templates/preinitializer.rb create mode 100644 lib/generators/ixtlan/setup/templates/production.yml.example create mode 100644 lib/generators/ixtlan/setup/templates/stale.html.erb create mode 100644 lib/generators/model/model_generator.rb create mode 100644 lib/generators/rails/active_record/active_record_generator.rb create mode 100644 lib/generators/rails/active_record/model/migration.rb create mode 100644 lib/generators/rails/active_record/model/model.rb create mode 100644 lib/generators/rails/erb/erb_generator.rb create mode 100644 lib/generators/rails/erb/scaffold/_form.html.erb create mode 100644 lib/generators/rails/erb/scaffold/edit.html.erb create mode 100644 lib/generators/rails/erb/scaffold/index.html.erb create mode 100644 lib/generators/rails/erb/scaffold/new.html.erb create mode 100644 lib/generators/rails/erb/scaffold/show.html.erb create mode 100644 lib/generators/rails/scaffold_controller/scaffold_controller/controller.rb create mode 100644 lib/generators/rails/scaffold_controller/scaffold_controller/singleton_controller.rb create mode 100644 lib/generators/scaffold/scaffold_generator.rb create mode 100644 lib/generators/scaffold_controller/scaffold_controller_generator.rb create mode 100644 lib/ixtlan-generators.rb create mode 100644 lib/ixtlan/railtie.rb create mode 100644 templates/generators.template diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2cab04f --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +target +*.pom +*~ diff --git a/MIT-LICENSE b/MIT-LICENSE new file mode 100644 index 0000000..472e94b --- /dev/null +++ b/MIT-LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2008 Kristian Meier + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..3bd783c --- /dev/null +++ b/README.md @@ -0,0 +1,64 @@ +# Ixtlan # + +this gem adds more security related headers to the response for a rails3 application. mainly inspired by +[google-gets-a-1-for-browser-security](http://www.barracudalabs.com/wordpress/index.php/2011/07/21/google-gets-a-1-for-browser-security-3/) +and +[HttpCaching](http://code.google.com/p/doctype/wiki/ArticleHttpCaching). +and +[Clickjacking](http://www.owasp.org/index.php/Clickjacking) + +the extra headers are + +* x-frame headers +* x-content-type headers +* x-xss-protection headers +* caching headers + +the main idea is to set the default as strict as possible and the application might relax the setup here and there. + +## rails configuration ## + +in _config/application.rb_ or in one of the _config/environments/*rb_ files or in an initializer. all three x-headers can be configured here, for example + + config.x_content_type_headers = :nosniff + +## controller configuration ## + +just add in your controller something like + + x_xss_protection :block + +## option for each *render*, *send\_file*, *send\_data* methods + +an example for an inline render + + render :inline => 'behappy', :x_frame_headers => :deny + +## possible values ## + +* x\_frame\_headers : `:deny, :sameorigin, :off` default `:deny` + +* x\_content\_type\_headers : `:nosniff, :off` default `:nosniff` + +* x\_xss\_protection\_headers : `:block, :disabled, :off` default `:block` + +## cache headers + +the cache headers needs to have a **current\_user**, i.e. the current\_user method of the controller needs to return a non-nil value. further the the method needs to `:get` and the response status an "ok" status, + +then you can use the controller configuration or the options with *render*, *send\_file* and *send\_data*. + +## possible values ## + +* `:private` : which tells not to cache or store any data except the browser memory: [no caching](http://code.google.com/p/doctype/wiki/ArticleHttpCaching#No_caching) + +* `:protected` : no caching but the browser: [Only the end user's browser is allowed to cache](http://code.google.com/p/doctype/wiki/ArticleHttpCaching#Only_the_end_user%27s_browser_is_allowed_to_cache) + +* `:public` : caching is allowed: [Both browser and proxy allowed to cache](http://code.google.com/p/doctype/wiki/ArticleHttpCaching#Both_browser_and_proxy_allowed_to_cache) + +* `:my_headers` : custom header method like + +> def my_headers + no_store = false + no_caching(no_store) + end diff --git a/TODO b/TODO new file mode 100644 index 0000000..ccc4cc5 --- /dev/null +++ b/TODO @@ -0,0 +1,9 @@ +* singleton unit tests + +* singleton erb templates are not found + +* plural attributes are singular in Model.java - have them plural as well + +* production.yml => password.yml and see taperoom how to deal with default - maybe + +* attr_accessors in model - mass-assignments diff --git a/features/generators.feature b/features/generators.feature new file mode 100644 index 0000000..c91ed42 --- /dev/null +++ b/features/generators.feature @@ -0,0 +1,6 @@ +Feature: Generators for Ixtlan + + Scenario: Create a rails application and adding 'ixtlan-generators' gem will provide the ixtlan generators + Given I create new rails application with template "generators.template" + And I execute "rails generate" + Then the output should contain "ixtlan:setup" and "ixtlan:configuration_model" and "ixtlan:configuration_scaffold" diff --git a/features/step_definitions/ruby_maven.rb b/features/step_definitions/ruby_maven.rb new file mode 100644 index 0000000..9de2db6 --- /dev/null +++ b/features/step_definitions/ruby_maven.rb @@ -0,0 +1,170 @@ +require 'fileutils' + +module Maven + class RubyMaven + + # make the command line for the goals of the jruby-maven-plugins nicer + PLUGINS = { + :rake => [:rake], + :ruby => [:jruby, :compile], + :gem => [:package, :install, :push, :exec, :pom, :initialize, :irb], + :gemify => [:gemify, :versions], + :rails2 => [:new, :generate, :rake, :server, :console], + :rails3 => [:new, :generate, :rake, :server, :console, :dbconsole, :pom, :initialize], + :cucumber => [:test], + :rspec => [:test], + :runit => [:test], + :bundler => [:install] + } + ALIASES = { + :jruby => :ruby, + :spec => :rspec, + :rails => :rails3, + :bundle => :bundler + } + + def initialize + @command = "#{ENV['GEM_HOME']}/bin/rmvn" + @jruby = File.read(@command).split("\n")[0].sub(/^#!/, '') + @maven_home = File.expand_path(Dir.glob("#{ENV['GEM_HOME']}/gems/ruby-maven-*-java")[0]) + end + + def launch_jruby(args) + classpath_array.each do |path| + require path + end + + java.lang.System.setProperty("classworlds.conf", + File.join(@maven_home, 'bin', "m2.conf")) + + java.lang.System.setProperty("maven.home", @maven_home) + + org.codehaus.plexus.classworlds.launcher.Launcher.main(args) + end + + def classpath_array + (Dir.glob(File.join(@maven_home, "boot", "*jar")) + + Dir.glob(File.join(@maven_home, "ext", "ruby-tools*jar"))).each do |path| + path + end + end + + def launch_java(*args) + "java -cp #{classpath_array.join(':')} -Dmaven.home=#{File.expand_path(@maven_home)} -Dclassworlds.conf=#{File.expand_path(File.join(@maven_home, 'bin', 'm2.conf'))} org.codehaus.plexus.classworlds.launcher.Launcher #{args.join ' '}" + end + + def prepare(args) + if args.size > 0 + name = args[0].to_sym + name = ALIASES[name] || name + if PLUGINS.member?(name) + start = 1 + if args.size > 1 + if PLUGINS[name].member? args[1].to_sym + goal = args[1].to_sym + start = 2 + else + goal = PLUGINS[name][0] + end + else + goal = PLUGINS[name][0] + end + aa = if index = args.index("--") + args[(index + 1)..-1] + else + [] + end + ruby_args = (args[start, (index || 1000) - start] || []).join(' ') + + # determine the version and delete from args if given + version = args.detect do |a| + a =~ /^-Dplugin.version=/ + end + if version + aa.delete(version) + version.sub!(/^-Dplugin.version=/, ':') + end + aa << "de.saumya.mojo:#{name}-maven-plugin#{version}:#{goal}" + aa << "-Dargs=#{ruby_args}" if ruby_args.size > 0 + args.replace(aa) + else + args.delete("--") + end + end + args + end + + def log(args) + log = File.join('log', 'rmvn.log') + if File.exists? File.dirname(log) + File.open(log, 'a') do |f| + f.puts args.join ' ' + end + end + end + + def maybe_print_help(args) + if args.size == 0 || args[0] == "--help" + puts "usage: rmvn [| [] [-- ] | [| ] | --help" + PLUGINS.each do |name, goals| + puts + print "plugin #{name}" + print " - alias: #{ALIASES[name]}" if ALIASES[name] + puts + if goals.size > 1 + print "\tgoals : #{goals.join(',')}" + puts + end + print "\tdefault goal: #{goals[0]}" + puts + end + puts + ["--help"] + else + args + end + end + + def options + @options ||= {} + end + + def options_string + options_array.join ' ' + end + + def options_array + options.collect do |k,v| + if k =~ /^-D/ + v = "=#{v}" if v + else + v = " #{v}" if v + end + "#{k}#{v}" + end + end + + def command_line(args) + args = prepare(args) + args = maybe_print_help(args) + args + end + + def exec(*args) + a = command_line(args.dup.flatten) + a << options_array + a.flatten! + #puts a.join ' ' + #launch_jruby(a) + args_line = args.join ' ' + full = "#{@jruby} #{@command} #{args_line} #{args_line =~ / -- / ? '' : '--'} #{options_string}" + system full + end + + def exec_in(launchdirectory, *args) + FileUtils.cd(launchdirectory) do + exec(args) + end + end + end +end diff --git a/features/step_definitions/simple_steps.rb b/features/step_definitions/simple_steps.rb new file mode 100644 index 0000000..b9e8240 --- /dev/null +++ b/features/step_definitions/simple_steps.rb @@ -0,0 +1,82 @@ +require 'fileutils' +require File.join(File.dirname(__FILE__), 'ruby_maven') + +def rmvn + @rmvn ||= Maven::RubyMaven.new +end + +def copy_tests(tests) + FileUtils.mkdir_p(@app_directory) + FileUtils.cp_r(File.join('templates', "tests-#{tests}", "."), + File.join(@app_directory, 'test')) +end + +def copy_specs(specs) + FileUtils.mkdir_p(@app_directory) + FileUtils.cp_r(File.join('templates', "specs-#{specs}", "."), + File.join(@app_directory, 'spec')) +end + +def create_rails_application(template) + name = template.sub(/.template$/, '') + @app_directory = File.join('target', name) + + # rails version from gemspec + gemspec = File.read(Dir.glob("*.gemspec")[0]) + rails_version = gemspec.split("\n").detect { |l| l =~ /development_dep.*rails/ }.sub(/'$/, '').sub(/.*'/, '') + + rmvn.options['-Dplugin.version'] = '0.28.4-SNAPSHOT' + rmvn.options['-Drails.version'] = rails_version + rmvn.options['-Dgem.home'] = ENV['GEM_HOME'] + rmvn.options['-Dgem.path'] = ENV['GEM_PATH'] + rmvn.options['-o'] = nil + + FileUtils.rm_rf(@app_directory) + + rmvn.exec("rails", "new", @app_directory, "-f") + + # TODO that should be done via the rails new task !!! + rmvn.exec_in(@app_directory, "rails", "rake", "rails:template LOCATION=" + File.expand_path("templates/#{template}")) +end + +Given /^I create new rails application with template "(.*)"$/ do |template| + create_rails_application(template) +end + +Given /^I create new rails application with template "(.*)" and "(.*)" tests$/ do |template, tests| + create_rails_application(template) + copy_tests(tests) +end + +Given /^I create new rails application with template "(.*)" and "(.*)" specs$/ do |template, specs| + create_rails_application(template) + copy_specs(specs) +end + +Given /^me an existing rails application "(.*)"$/ do |name| + @app_directory = File.join('target', name) +end + +Given /^me an existing rails application "(.*)" and "(.*)" tests$/ do |name, tests| + @app_directory = File.join('target', name) + copy_tests(tests) +end + +Given /^me an existing rails application "(.*)" and "(.*)" specs$/ do |name, specs| + @app_directory = File.join('target', name) + copy_specs(specs) +end + +And /^I execute \"(.*)\"$/ do |args| + rmvn.options['-l'] = "output.log" + rmvn.exec_in(@app_directory, args) +end + +Then /^the output should contain \"(.*)\"$/ do |expected| + result = File.read(File.join(@app_directory, "output.log")) + expected.split(/\"?\s+and\s+\"?/).each do |exp| + puts exp + (result =~ /.*#{exp}.*/).should_not be_nil + end +end + diff --git a/ixtlan-generators.gemspec b/ixtlan-generators.gemspec new file mode 100644 index 0000000..9c39470 --- /dev/null +++ b/ixtlan-generators.gemspec @@ -0,0 +1,31 @@ +# -*- mode: ruby -*- +Gem::Specification.new do |s| + s.name = 'ixtlan-generators' + s.version = '0.1.0' + + s.summary = 'rails generator templates for ixtlan gems' + s.description = s.summary + s.homepage = 'http://github.com/mkristian/ixtlan-generators' + + s.authors = ['mkristian'] + s.email = ['m.kristian@web.de'] + + s.files = Dir['MIT-LICENSE'] + s.licenses << 'MIT-LICENSE' +# s.files += Dir['History.txt'] + s.files += Dir['README.md'] + s.files += Dir['lib/**/*'] + s.files += Dir['spec/**/*'] + s.files += Dir['features/**/*rb'] + s.files += Dir['features/**/*feature'] + s.test_files += Dir['spec/**/*_spec.rb'] + s.test_files += Dir['features/*.feature'] + s.test_files += Dir['features/step_definitions/*.rb'] + s.add_development_dependency 'ixtlan-core', '~>0.5' + s.add_development_dependency 'rails', '3.0.9' + s.add_development_dependency 'rspec', '2.6.0' + s.add_development_dependency 'cucumber', '0.9.4' + s.add_development_dependency 'ruby-maven', '0.8.3.0.3.0.28.3' +end + +# vim: syntax=Ruby diff --git a/ixtlan-generators.gemspec.files b/ixtlan-generators.gemspec.files new file mode 100644 index 0000000..7f8a07c --- /dev/null +++ b/ixtlan-generators.gemspec.files @@ -0,0 +1 @@ +ixtlan-generators.gemspec diff --git a/lib/generators/ixtlan/base.rb b/lib/generators/ixtlan/base.rb new file mode 100644 index 0000000..dc0c868 --- /dev/null +++ b/lib/generators/ixtlan/base.rb @@ -0,0 +1,45 @@ +require 'rails/generators/named_base' +module Ixtlan + module Generators + class Base < Rails::Generators::Base + + argument :name, :type => :string, :required => false + + protected + def generator_name + raise "please overwrite generator_name" + end + + public + def create + args = [] + if name + args << ARGV.shift + else + args << "configuration" + end + + if defined? ::Ixtlan::Errors + args << "errors_keep_dump:integer" + args << "errors_dir:string" + args << "errors_from:string" + args << "errors_to:string" + end + + if defined? ::Ixtlan::Sessions + args << "idle_session_timeout:integer" + end + + if defined? ::Ixtlan::Audit + args << "audit_keep_log:integer" + end + + args += ARGV[0, 10000] || [] + + args << "--singleton" + + generate generator_name, *args + end + end + end +end diff --git a/lib/generators/ixtlan/configuration_model/configuration_model_generator.rb b/lib/generators/ixtlan/configuration_model/configuration_model_generator.rb new file mode 100644 index 0000000..81812ce --- /dev/null +++ b/lib/generators/ixtlan/configuration_model/configuration_model_generator.rb @@ -0,0 +1,12 @@ +require 'generators/ixtlan/base' +module Ixtlan + module Generators + class ConfigurationModelGenerator < Base + + protected + def generator_name + "model" + end + end + end +end diff --git a/lib/generators/ixtlan/configuration_scaffold/configuration_scaffold_generator.rb b/lib/generators/ixtlan/configuration_scaffold/configuration_scaffold_generator.rb new file mode 100644 index 0000000..171a686 --- /dev/null +++ b/lib/generators/ixtlan/configuration_scaffold/configuration_scaffold_generator.rb @@ -0,0 +1,12 @@ +require 'generators/ixtlan/base' +module Ixtlan + module Generators + class ConfigurationScaffoldGenerator < Base + + protected + def generator_name + "scaffold" + end + end + end +end diff --git a/lib/generators/ixtlan/setup/setup_generator.rb b/lib/generators/ixtlan/setup/setup_generator.rb new file mode 100644 index 0000000..25b1366 --- /dev/null +++ b/lib/generators/ixtlan/setup/setup_generator.rb @@ -0,0 +1,38 @@ +require 'rails/generators/base' +module Ixtlan + module Generators + class SetupGenerator < Rails::Generators::Base + + source_root File.expand_path('../templates', __FILE__) + + def create_preinitializer_files + template 'preinitializer.rb', File.join('config', "preinitializer.rb") + template 'gitignore', File.join('config', ".gitignore") + template 'production.yml.example', File.join('config', "production.yml.example") + template 'database.yml.example', File.join('config', "database.yml.example") + end + + def create_initializer_file + template 'initializer.rb', File.join('config', "initializers", "ixtlan.rb") + end + + # TODO make only if template-engine is ERB + def error_templates + if defined? Ixtlan::Errors + views_dir = File.join('app', 'views', 'errors') + ['error', 'error_with_session', 'stale'].each do |f| + file = "#{f}.html.erb" + template file, File.join(views_dir, file) + end + end + end + + def create_application_layout_file + if defined? Ixtlan::Sessions + layout = File.join('app', 'views', 'layouts', 'application.html.erb') + template 'application_layout.html.erb', layout + end + end + end + end +end diff --git a/lib/generators/ixtlan/setup/templates/application_layout.html.erb b/lib/generators/ixtlan/setup/templates/application_layout.html.erb new file mode 100644 index 0000000..1c44745 --- /dev/null +++ b/lib/generators/ixtlan/setup/templates/application_layout.html.erb @@ -0,0 +1,17 @@ + + + + <%= app_const_base %> + <%%= stylesheet_link_tag :all %> + <%%= javascript_include_tag :defaults %> + <%%= csrf_meta_tag %> + <%% if controller.respond_to?(:current_user) && controller.send(:current_user) != nil %> + + <%% end %> + + + +<%%= yield %> + + + diff --git a/lib/generators/ixtlan/setup/templates/database.yml.example b/lib/generators/ixtlan/setup/templates/database.yml.example new file mode 100644 index 0000000..203a424 --- /dev/null +++ b/lib/generators/ixtlan/setup/templates/database.yml.example @@ -0,0 +1,48 @@ +# MySQL. Versions 4.1 and 5.0 are recommended. +# +# Install the MySQL driver: +# gem install mysql +# On Mac OS X: +# sudo gem install mysql -- --with-mysql-dir=/usr/local/mysql +# On Mac OS X Leopard: +# sudo env ARCHFLAGS="-arch i386" gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config +# This sets the ARCHFLAGS environment variable to your native architecture +# On Windows: +# gem install mysql +# Choose the win32 build. +# Install MySQL and put its /bin directory on your path. +# +# And be sure to use new-style password hashing: +# http://dev.mysql.com/doc/refman/5.0/en/old-client.html +development: + adapter: mysql + encoding: utf8 + reconnect: false + database: test_development + pool: 5 + username: root + password: + socket: /var/run/mysqld/mysqld.sock + +# Warning: The database defined as "test" will be erased and +# re-generated from your development database when you run "rake". +# Do not set this db to the same as development or production. +test: + adapter: mysql + encoding: utf8 + reconnect: false + database: test_test + pool: 5 + username: root + password: + socket: /var/run/mysqld/mysqld.sock + +production: + adapter: mysql + encoding: utf8 + reconnect: false + database: CONFIG[:db][:database] + pool: 5 + username: CONFIG[:db][:username] + password: CONFIG[:db][:password] + socket: /var/run/mysqld/mysqld.sock diff --git a/lib/generators/ixtlan/setup/templates/error.html.erb b/lib/generators/ixtlan/setup/templates/error.html.erb new file mode 100644 index 0000000..0145b0a --- /dev/null +++ b/lib/generators/ixtlan/setup/templates/error.html.erb @@ -0,0 +1 @@ +

<%%= @notice %>

diff --git a/lib/generators/ixtlan/setup/templates/error_with_session.html.erb b/lib/generators/ixtlan/setup/templates/error_with_session.html.erb new file mode 100644 index 0000000..0145b0a --- /dev/null +++ b/lib/generators/ixtlan/setup/templates/error_with_session.html.erb @@ -0,0 +1 @@ +

<%%= @notice %>

diff --git a/lib/generators/ixtlan/setup/templates/gitignore b/lib/generators/ixtlan/setup/templates/gitignore new file mode 100644 index 0000000..2cdcf9f --- /dev/null +++ b/lib/generators/ixtlan/setup/templates/gitignore @@ -0,0 +1,2 @@ +production.yml +*.example \ No newline at end of file diff --git a/lib/generators/ixtlan/setup/templates/initializer.rb b/lib/generators/ixtlan/setup/templates/initializer.rb new file mode 100644 index 0000000..646189f --- /dev/null +++ b/lib/generators/ixtlan/setup/templates/initializer.rb @@ -0,0 +1,64 @@ +# dynamic configuration through a Configuration singleton model + +# configuration model +# ------------------- +# CONFIGURATION = Configuration +# config.configuration_model = CONFIGURATION +begin + config_instance = CONFIGURATION.instance +rescue + # allow rake tasks to work without configuration migrated + return +end + +# notification email on errors and dump directory for the system dump +# the error dumps will be cleanup after the days to keeps dump expired +# -------------------------------------------------------------------- +# config_instance.register("error_dumper") do |config| +# Rails.configuration.error_dumper.dump_dir = config.errors_dir +# Rails.configuration.error_dumper.email_from = config.errors_from +# Rails.configuration.error_dumper.email_to = config.errors_to +# Rails.configuration.error_dumper.keep_dumps = config.errors_keep_dump # days +# end + +# idle session timeout configuration (in minutes) +# ----------------------------------------------- +# config_instance.register("session_idle_timeout") do |config| +# Rails.configuration.session_idle_timeout = config.session_idle_timeout +# end + +# audit log manager +# ----------------- + +# config.audit_manager.model = MyAudit # default: Audit +# config.audit_manager.username_method = :username # default: :login + +# config_instance.register("audit_manager") do |config| +# Rails.configuration.audit_manager.keep_log = config.keep_log # days +# end + +# -------------------- +# static configuration +# -------------------- + +# error dumper +# ------------ +# notification email on errors and dump directory for the system dump. per +# default there is no email notification and if email_from or email_to is +# missing then there is no email too + +# config.error_dumper.dump_dir = Rails.root + "/log/errors" # default: log/errors +# config.error_dumper.email_from = "no-reply@example.com" +# config.error_dumper.email_to = "developer1@example.com,developer2@example.com" +# config.error_dumper.keep_dumps = 30 # days +# config.skip_rescue_module = true # do not include the predefined Rescue + +# idle session timeout configuration +# ---------------------------------- +# config.session_idle_timeout = 30 #minutes + +# audit log manager +# ----------------- +# config.audit_manager.model = MyAudit # default: Audit +# config.audit_manager.username_method = :username # default: :login +# config.audit_manager.keep_log = 30 # days diff --git a/lib/generators/ixtlan/setup/templates/preinitializer.rb b/lib/generators/ixtlan/setup/templates/preinitializer.rb new file mode 100644 index 0000000..6d06460 --- /dev/null +++ b/lib/generators/ixtlan/setup/templates/preinitializer.rb @@ -0,0 +1,31 @@ +require 'yaml' +require 'erb' +module Ixtlan + class Configurator + + def self.symbolize_keys(h) + result = {} + + h.each do |k, v| + v = ' ' if v.nil? + if v.is_a?(Hash) + result[k.to_sym] = symbolize_keys(v) unless v.size == 0 + else + result[k.to_sym] = v unless k.to_sym == v.to_sym + end + end + + result + end + + def self.load(file) + if File.exists?(file) + symbolize_keys(YAML::load(ERB.new(IO.read(file)).result)) + else + warn "no file #{file} to load - maybe the is a #{file}.example" + end + end + end +end + +CONFIG = Ixtlan::Configurator.load(File.join(File.dirname(__FILE__), 'production.yml')) || {} diff --git a/lib/generators/ixtlan/setup/templates/production.yml.example b/lib/generators/ixtlan/setup/templates/production.yml.example new file mode 100644 index 0000000..057421a --- /dev/null +++ b/lib/generators/ixtlan/setup/templates/production.yml.example @@ -0,0 +1,8 @@ +db: + database: production + username: worker + password: behappy +smtp: + host: mail.example.com + username: mailworker + password: secret \ No newline at end of file diff --git a/lib/generators/ixtlan/setup/templates/stale.html.erb b/lib/generators/ixtlan/setup/templates/stale.html.erb new file mode 100644 index 0000000..3f1e7b9 --- /dev/null +++ b/lib/generators/ixtlan/setup/templates/stale.html.erb @@ -0,0 +1,2 @@ +

stale resource

+

please reload resource and change it again

diff --git a/lib/generators/model/model_generator.rb b/lib/generators/model/model_generator.rb new file mode 100644 index 0000000..4cc250f --- /dev/null +++ b/lib/generators/model/model_generator.rb @@ -0,0 +1,12 @@ +module Rails + module Generators + class ModelGenerator < NamedBase #metagenerator + argument :attributes, :type => :array, :default => [], :banner => "field:type field:type" + hook_for :orm, :required => true + + if defined? Resty + hook_for :resty, :type => :boolean, :default => true + end + end + end +end diff --git a/lib/generators/rails/active_record/active_record_generator.rb b/lib/generators/rails/active_record/active_record_generator.rb new file mode 100644 index 0000000..7216740 --- /dev/null +++ b/lib/generators/rails/active_record/active_record_generator.rb @@ -0,0 +1,40 @@ +require 'rails/generators/active_record' + +module ActiveRecord + module Generators + class ModelGenerator < Base + include ::Ixtlan::Core::Singleton + + argument :attributes, :type => :array, :default => [], :banner => "field:type field:type" + + check_class_collision + + class_option :migration, :type => :boolean + class_option :timestamps, :type => :boolean + class_option :parent, :type => :string, :desc => "The parent class for the generated model" + + def create_migration_file + return unless options[:migration] && options[:parent].nil? + migration_template "migration.rb", "db/migrate/create_#{table_name}.rb" + end + + def create_model_file + template 'model.rb', File.join('app/models', class_path, "#{file_name}.rb") + end + + def create_module_file + return if class_path.empty? + template 'module.rb', File.join('app/models', "#{class_path.join('/')}.rb") if behavior == :invoke + end + + hook_for :test_framework + + protected + + def parent_class_name + options[:parent] || "ActiveRecord::Base" + end + + end + end +end diff --git a/lib/generators/rails/active_record/model/migration.rb b/lib/generators/rails/active_record/model/migration.rb new file mode 100644 index 0000000..30b3b4d --- /dev/null +++ b/lib/generators/rails/active_record/model/migration.rb @@ -0,0 +1,19 @@ +class <%= migration_class_name %> < ActiveRecord::Migration + def self.up + create_table :<%= table_name %> do |t| +<% attributes.select {|attr| ![:has_one, :has_many].include?(attr.type) }.each do |attribute| -%> + t.<%= attribute.type %> :<%= attribute.name %> +<% end -%> +<% if options[:timestamps] %> + t.timestamps +<% end -%> +<% if options[:modified_by] %> + t.references :modified_by +<% end -%> + end + end + + def self.down + drop_table :<%= table_name %> + end +end diff --git a/lib/generators/rails/active_record/model/model.rb b/lib/generators/rails/active_record/model/model.rb new file mode 100644 index 0000000..418bdde --- /dev/null +++ b/lib/generators/rails/active_record/model/model.rb @@ -0,0 +1,16 @@ +class <%= class_name %> < <%= parent_class_name.classify %> +<% attributes.select {|attr| attr.reference? }.each do |attribute| -%> + belongs_to :<%= attribute.name %> +<% end -%> +<% attributes.select {|attr| [:has_one, :has_many].include?(attr.type) }.each do |attribute| -%> + <%= attribute.type %> :<%= attribute.name %> +<% end -%> +<% if options[:modified_by] -%> + belongs_to :modified_by, :class_name => "<%= options[:user_model] %>" +<% end -%> +<% if options[:singleton] -%> + def self.instance + self.first || self.new + end +<% end -%> +end diff --git a/lib/generators/rails/erb/erb_generator.rb b/lib/generators/rails/erb/erb_generator.rb new file mode 100644 index 0000000..81332d7 --- /dev/null +++ b/lib/generators/rails/erb/erb_generator.rb @@ -0,0 +1,37 @@ +require 'rails/generators/erb' +require 'rails/generators/resource_helpers' + +module Erb + module Generators + class ScaffoldGenerator < Base + include Rails::Generators::ResourceHelpers + + class_option :optimistic, :type => :boolean, :default => false + class_option :singleton, :type => :boolean, :default => false + class_option :timestamps, :type => :boolean, :default => true + + argument :attributes, :type => :array, :default => [], :banner => "field:type field:type" + + def create_root_folder + empty_directory File.join("app/views", controller_file_path) + end + + def copy_view_files + available_views.each do |view| + filename = filename_with_extensions(view) + template filename, File.join("app/views", controller_file_path, filename) + end + end + + protected + + def available_views + if options[:singleton] + %w(edit show _form) + else + %w(index edit show new _form) + end + end + end + end +end diff --git a/lib/generators/rails/erb/scaffold/_form.html.erb b/lib/generators/rails/erb/scaffold/_form.html.erb new file mode 100644 index 0000000..7f4c3dd --- /dev/null +++ b/lib/generators/rails/erb/scaffold/_form.html.erb @@ -0,0 +1,28 @@ +<%%= form_for(@<%= singular_table_name %><% if options[:singleton] -%> +, :url => <%= singular_table_name %>_path, :html => { :method => :put, :class => "edit_<%= singular_table_name %>", :id => "edit_<%= singular_table_name %>"}<% end -%> +) do |f| %> + <%% if @<%= singular_table_name %>.errors.any? %> +
+

<%%= pluralize(@<%= singular_table_name %>.errors.count, "error") %> prohibited this <%= singular_table_name %> from being saved:

+ +
    + <%% @<%= singular_table_name %>.errors.full_messages.each do |msg| %> +
  • <%%= msg %>
  • + <%% end %> +
+
+ <%% end %> + +<% for attribute in attributes -%> +
+ <%%= f.label :<%= attribute.name %> %>
+ <%%= f.<%= attribute.field_type %> :<%= attribute.name %> %> +
+<% end -%> +
+<% if options[:optimistic] && options[:timestamps] -%> + <%%= f.hidden_field :updated_at %> +<% end -%> + <%%= f.submit %> +
+<%% end %> diff --git a/lib/generators/rails/erb/scaffold/edit.html.erb b/lib/generators/rails/erb/scaffold/edit.html.erb new file mode 100644 index 0000000..a19bf09 --- /dev/null +++ b/lib/generators/rails/erb/scaffold/edit.html.erb @@ -0,0 +1,24 @@ +

Editing <%= singular_table_name %>

+ +<%%= render 'form' %> + +<% if defined? ::Ixtlan::Guard -%> +<%% if allowed?(:<%= table_name %>, :show) %> +<% end -%> +<% if options[:singleton] -%> +<%%= link_to 'Show', <%= singular_table_name %>_path %> +<% else -%> +<%%= link_to 'Show', @<%= singular_table_name %> %> +<% end -%> +<% if defined? ::Ixtlan::Guard -%> +<%% end %> +<% end -%> +<% unless options[:singleton] -%> +<% if defined? ::Ixtlan::Guard -%> +<%% if allowed?(:<%= table_name %>, :index) %> +<% end -%> +| <%%= link_to 'Back', <%= index_helper %>_path %> +<% if defined? ::Ixtlan::Guard -%> +<%% end %> +<% end -%> +<% end -%> diff --git a/lib/generators/rails/erb/scaffold/index.html.erb b/lib/generators/rails/erb/scaffold/index.html.erb new file mode 100644 index 0000000..57fc10d --- /dev/null +++ b/lib/generators/rails/erb/scaffold/index.html.erb @@ -0,0 +1,49 @@ +

Listing <%= plural_table_name %>

+ + + +<% for attribute in attributes -%> + +<% end -%> + + + + + +<%% @<%= plural_table_name %>.each do |<%= singular_table_name %>| %> + +<% for attribute in attributes -%> + +<% end -%> +<% if defined? ::Ixtlan::Guard -%> +<%% if allowed?(:<%= table_name %>, :show) %> +<% end -%> + +<% if defined? ::Ixtlan::Guard -%> +<%% end %> +<%% if allowed?(:<%= table_name %>, :update) %> +<% end -%> + +<% if defined? ::Ixtlan::Guard -%> +<%% end %> +<%% if allowed?(:<%= table_name %>, :destroy) %> +<% end -%> + +<% if defined? ::Ixtlan::Guard -%> +<%% end %> +<% end -%> + +<%% end %> +
<%= attribute.human_name %>
<%%= <%= singular_table_name %>.<%= attribute.name %> %><%%= link_to 'Show', <%= singular_table_name %> %><%%= link_to 'Edit', edit_<%= singular_table_name %>_path(<%= singular_table_name %>) %><% if options[:optimistic] && options[:timestamps] -%> +<%%= link_to 'Destroy', <%= singular_table_name %>_path(<%= singular_table_name %>) + "?<%= singular_table_name %>[updated_at]=#{<%= singular_table_name %>.updated_at.utc.strftime('%Y-%m-%d %H:%M:%S') + ("%06d" % <%= singular_table_name %>.updated_at.utc)}", :confirm => 'Are you sure?', :method => :delete %><% else -%><%%= link_to 'Destroy', <%= singular_table_name %>, :confirm => 'Are you sure?', :method => :delete %> +<% end -%>
+ +
+ +<% if defined? ::Ixtlan::Guard -%> +<%% if allowed?(:<%= table_name %>, :create) %> +<% end -%> +<%%= link_to 'New <%= human_name %>', new_<%= singular_table_name %>_path %> +<% if defined? ::Ixtlan::Guard -%> +<%% end %> +<% end -%> diff --git a/lib/generators/rails/erb/scaffold/new.html.erb b/lib/generators/rails/erb/scaffold/new.html.erb new file mode 100644 index 0000000..680483e --- /dev/null +++ b/lib/generators/rails/erb/scaffold/new.html.erb @@ -0,0 +1,11 @@ +

New <%= singular_table_name %>

+ +<%%= render 'form' %> + +<% if defined? ::Ixtlan::Guard -%> +<%% if allowed?(:<%= table_name %>, :index) %> +<% end -%> +<%%= link_to 'Back', <%= index_helper %>_path %> +<% if defined? ::Ixtlan::Guard -%> +<%% end %> +<% end -%> diff --git a/lib/generators/rails/erb/scaffold/show.html.erb b/lib/generators/rails/erb/scaffold/show.html.erb new file mode 100644 index 0000000..da0cc0c --- /dev/null +++ b/lib/generators/rails/erb/scaffold/show.html.erb @@ -0,0 +1,30 @@ +

<%%= notice %>

+ +<% for attribute in attributes -%> +

+ <%= attribute.human_name %>: + <%%= @<%= singular_table_name %>.<%= attribute.name %> %> +

+ +<% end -%> + +<% if defined? ::Ixtlan::Guard -%> +<%% if allowed?(:<%= table_name %>, :update) %> +<% end -%> +<% if options[:singleton] -%> +<%%= link_to 'Edit', edit_<%= singular_table_name %>_path %> +<% else -%> +<%%= link_to 'Edit', edit_<%= singular_table_name %>_path(@<%= singular_table_name %>) %> +<% end -%> +<% if defined? ::Ixtlan::Guard -%> +<%% end %> +<% end -%> +<% unless options[:singleton] -%> +<% if defined? ::Ixtlan::Guard -%> +<%% if allowed?(:<%= table_name %>, :index) %> +<% end -%> + | <%%= link_to 'Back', <%= index_helper %>_path %> +<% if defined? ::Ixtlan::Guard -%> +<%% end %> +<% end -%> +<% end -%> diff --git a/lib/generators/rails/scaffold_controller/scaffold_controller/controller.rb b/lib/generators/rails/scaffold_controller/scaffold_controller/controller.rb new file mode 100644 index 0000000..5f579c2 --- /dev/null +++ b/lib/generators/rails/scaffold_controller/scaffold_controller/controller.rb @@ -0,0 +1,129 @@ +class <%= controller_class_name %>Controller < ApplicationController + # GET <%= route_url %> + # GET <%= route_url %>.xml + # GET <%= route_url %>.json + def index + @<%= plural_table_name %> = <%= orm_class.all(class_name) %> + + respond_to do |format| + format.html # index.html.erb + format.xml { render :xml => @<%= plural_table_name %> } + format.json { render :json => @<%= plural_table_name %> } + end + end + + # GET <%= route_url %>/1 + # GET <%= route_url %>/1.xml + # GET <%= route_url %>/1.json + def show + @<%= singular_table_name %> = <%= orm_class.find(class_name, "params[:id]") %> + + respond_to do |format| + format.html # show.html.erb + format.xml { render :xml => @<%= singular_table_name %> } + format.json { render :json => @<%= singular_table_name %> } + end + end + + # GET <%= route_url %>/new + def new + @<%= singular_table_name %> = <%= orm_class.build(class_name) %> + end + + # GET <%= route_url %>/1/edit + def edit + @<%= singular_table_name %> = <%= orm_class.find(class_name, "params[:id]") %> + end + + # POST <%= route_url %> + # POST <%= route_url %>.xml + # POST <%= route_url %>.json + def create + @<%= singular_table_name %> = <%= orm_class.build(class_name, "params[:#{singular_table_name}]") %> +<% if options[:modified_by] -%> + @<%= singular_table_name %>.current_user = current_user +<% end -%> + + respond_to do |format| + if @<%= orm_instance.save %> + format.html { redirect_to(@<%= singular_table_name %>, :notice => '<%= human_name %> was successfully created.') } + format.xml { render :xml => @<%= singular_table_name %>, :status => :created, :location => @<%= singular_table_name %> } + format.json { render :json => @<%= singular_table_name %>, :status => :created, :location => @<%= singular_table_name %> } + else + format.html { render :action => "new" } + format.xml { render :xml => @<%= orm_instance.errors %>, :status => :unprocessable_entity } + format.json { render :json => @<%= orm_instance.errors %>, :status => :unprocessable_entity } + end + end + end + + # PUT <%= route_url %>/1 + # PUT <%= route_url %>/1.xml + # PUT <%= route_url %>/1.json + def update +<% if options[:optimistic] && options[:timestamps] -%> + @<%= singular_table_name %> = <%= orm_class.find(class_name, "(params[:#{singular_table_name}]||[]).delete(:updated_at), params[:id]").sub(/\.(get|find)/, '.optimistic_\1') %> + + if @<%= singular_table_name %>.nil? + @<%= singular_table_name %> = <%= orm_class.find(class_name, "params[:id]") %> + respond_to do |format| + format.html { render :action => "edit" } + format.xml { render :xml => nil, :status => :conflict } + format.json { render :json => nil, :status => :conflict } + end + return + end +<% else -%> + @<%= singular_table_name %> = <%= orm_class.find(class_name, "params[:id]") %> + (params[:<%= singular_table_name %>]||[]).delete(:updated_at) +<% end -%> + (params[:<%= singular_table_name %>]||[]).delete(:id) +<% if options[:modified_by] -%> + @<%= singular_table_name %>.current_user = current_user +<% end -%> + + respond_to do |format| + if @<%= orm_instance.update_attributes("params[:#{singular_table_name}]") %> + format.html { redirect_to(@<%= singular_table_name %>, :notice => '<%= human_name %> was successfully updated.') } + format.xml { render :xml => @<%= singular_table_name %> } + format.json { render :json => @<%= singular_table_name %> } + else + format.html { render :action => "edit" } + format.xml { render :xml => @<%= orm_instance.errors %>, :status => :unprocessable_entity } + format.json { render :json => @<%= orm_instance.errors %>, :status => :unprocessable_entity } + end + end + end + + # DELETE <%= route_url %>/1 + # DELETE <%= route_url %>/1.xml + # DELETE <%= route_url %>/1.json + def destroy +<% if options[:optimistic] && options[:timestamps] -%> + @<%= singular_table_name %> = <%= orm_class.find(class_name, "(params[:#{singular_table_name}]||[]).delete(:updated_at), params[:id]").sub(/\.(get|find)/, '.optimistic_\1') %> + + if @<%= singular_table_name %>.nil? + @<%= singular_table_name %> = <%= orm_class.find(class_name, "params[:id]") %> + respond_to do |format| + format.html { render :action => "edit" } + format.xml { render :xml => nil, :status => :conflict } + format.json { render :json => nil, :status => :conflict } + end + return + end +<% else -%> + @<%= singular_table_name %> = <%= orm_class.find(class_name, "params[:id]") %> +<% end -%> +<% if options[:modified_by] -%> + @<%= singular_table_name %>.current_user = current_user +<% end -%> + + @<%= orm_instance.destroy %> + + respond_to do |format| + format.html { redirect_to(<%= index_helper %>_url) } + format.xml { head :ok } + format.json { head :ok } + end + end +end diff --git a/lib/generators/rails/scaffold_controller/scaffold_controller/singleton_controller.rb b/lib/generators/rails/scaffold_controller/scaffold_controller/singleton_controller.rb new file mode 100644 index 0000000..52095e9 --- /dev/null +++ b/lib/generators/rails/scaffold_controller/scaffold_controller/singleton_controller.rb @@ -0,0 +1,43 @@ +class <%= controller_class_name %>Controller < ApplicationController + + # GET <%= route_url %> + # GET <%= route_url %>.xml + # GET <%= route_url %>.json + def show + @<%= singular_table_name %> = <%= class_name %>.instance + + respond_to do |format| + format.html # show.html.erb + format.xml { render :xml => @<%= singular_table_name %> } + format.json { render :json => @<%= singular_table_name %> } + end + end + + # GET <%= route_url %>/edit + def edit + @<%= singular_table_name %> = <%= class_name %>.instance + end + + # PUT <%= route_url %> + # PUT <%= route_url %>.xml + # PUT <%= route_url %>.json + def update + @<%= singular_table_name %> = <%= class_name %>.instance +<% orm_class.find(class_name) + if options[:modified_by] -%> + @<%= singular_table_name %>.current_user = current_user +<% end -%> + + respond_to do |format| + if @<%= orm_instance.update_attributes("params[:#{singular_table_name}]") %> + format.html { redirect_to(<%= singular_table_name %>_path, :notice => '<%= human_name %> was successfully updated.') } + format.xml { render :xml => @<%= singular_table_name %> } + format.json { render :json => @<%= singular_table_name %> } + else + format.html { render :action => "edit" } + format.xml { render :xml => @<%= orm_instance.errors %>, :status => :unprocessable_entity } + format.json { render :json => @<%= orm_instance.errors %>, :status => :unprocessable_entity } + end + end + end +end diff --git a/lib/generators/scaffold/scaffold_generator.rb b/lib/generators/scaffold/scaffold_generator.rb new file mode 100644 index 0000000..32bd32c --- /dev/null +++ b/lib/generators/scaffold/scaffold_generator.rb @@ -0,0 +1,35 @@ +require 'rails/generators/rails/resource/resource_generator' + +module Rails + module Generators + class ScaffoldGenerator < ResourceGenerator #metagenerator + remove_hook_for :resource_controller + remove_class_option :actions + + class_option :singleton, :type => :boolean, :default => false + + hook_for :scaffold_controller, :required => true, :in => :scaffold_controller + hook_for :stylesheets + + if defined? Resty + hook_for :resty, :type => :boolean, :default => true + end + + if defined? ::Ixtlan::Guard + hook_for :guard, :type => :boolean, :default => true + end + + def add_resource_route + return if options[:actions].present? + route_config = class_path.collect{|namespace| "namespace :#{namespace} do " }.join(" ") + if options[:singleton] + route_config << "resource :#{file_name}" + else + route_config << "resources :#{file_name.pluralize}" + end + route_config << " end" * class_path.size + route route_config + end + end + end +end diff --git a/lib/generators/scaffold_controller/scaffold_controller_generator.rb b/lib/generators/scaffold_controller/scaffold_controller_generator.rb new file mode 100644 index 0000000..15dd4bf --- /dev/null +++ b/lib/generators/scaffold_controller/scaffold_controller_generator.rb @@ -0,0 +1,34 @@ +require 'rails/generators/resource_helpers' +require 'rails/generators/named_base' + +module ScaffoldController + module Generators + class ScaffoldControllerGenerator < ::Rails::Generators::NamedBase + include ::Rails::Generators::ResourceHelpers + + check_class_collision :suffix => "Controller" + + class_option :orm, :banner => "NAME", :type => :string, :required => true, + :desc => "ORM to generate the controller for" + + class_option :singleton, :type => :boolean, :default => false + class_option :optimistic, :type => :boolean, :default => false + class_option :timestamps, :type => :boolean, :default => true + + def create_controller_files + if options[:singleton] + template 'singleton_controller.rb', File.join('app/controllers', class_path, "#{controller_file_name}_controller.rb") + else + template 'controller.rb', File.join('app/controllers', class_path, "#{controller_file_name}_controller.rb") + end + end + + hook_for :template_engine, :test_framework, :as => :scaffold, :in => :rails + + # Invoke the helper using the controller name (pluralized) + hook_for :helper, :as => :scaffold, :in => :rails do |invoked| + invoke invoked, [ controller_name ] + end + end + end +end diff --git a/lib/ixtlan-generators.rb b/lib/ixtlan-generators.rb new file mode 100644 index 0000000..9c89286 --- /dev/null +++ b/lib/ixtlan-generators.rb @@ -0,0 +1,3 @@ +if defined?(Rails) + require 'ixtlan/railtie' +end diff --git a/lib/ixtlan/railtie.rb b/lib/ixtlan/railtie.rb new file mode 100644 index 0000000..e6d9b07 --- /dev/null +++ b/lib/ixtlan/railtie.rb @@ -0,0 +1,9 @@ +module Ixtlan + class Railtie < Rails::Railtie + config.generators do |config| + + config.templates << File.expand_path('../../generators/rails', __FILE__) + + end + end +end diff --git a/templates/generators.template b/templates/generators.template new file mode 100644 index 0000000..ad80d7b --- /dev/null +++ b/templates/generators.template @@ -0,0 +1,6 @@ +#-*- mode: ruby -*- + +gem 'ruby-maven', '0.8.3.0.3.0.28.3' +gem 'ixtlan-generators', :path => '../..' + +# vim: syntax=Ruby