kitestrings 1.0.2 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/CHANGELOG.md +10 -0
  4. data/kitestrings.gemspec +0 -2
  5. data/lib/generators/kitestrings/install_generator.rb +26 -6
  6. data/lib/generators/kitestrings/message_templates/default.text.erb +7 -0
  7. data/lib/generators/kitestrings/message_templates/index.html.haml +26 -0
  8. data/lib/generators/kitestrings/{templates → message_templates}/message.rb.erb +19 -2
  9. data/lib/generators/kitestrings/message_templates/message_mailer.rb +19 -0
  10. data/lib/generators/kitestrings/message_templates/message_migration.rb +20 -0
  11. data/lib/generators/kitestrings/message_templates/message_spec.rb +73 -0
  12. data/lib/generators/kitestrings/message_templates/messages.rb +11 -0
  13. data/lib/generators/kitestrings/message_templates/messages_controller.rb +41 -0
  14. data/lib/generators/kitestrings/message_templates/messages_controller_spec.rb +86 -0
  15. data/lib/generators/kitestrings/message_templates/show.html.haml +32 -0
  16. data/lib/generators/kitestrings/messages_generator.rb +64 -1
  17. data/lib/generators/templates/{deploy.rb → config/deploy.rb} +19 -16
  18. data/lib/generators/templates/config/deploy/integ.rb +3 -0
  19. data/lib/generators/templates/config/deploy/production.rb +12 -0
  20. data/lib/generators/templates/config/deploy/uat.rb +3 -0
  21. data/lib/generators/templates/config/environments/integ.rb +21 -0
  22. data/lib/generators/templates/config/environments/uat.rb +21 -0
  23. data/lib/generators/templates/views/public/403.html +30 -0
  24. data/lib/kitestrings/menu.rb +10 -0
  25. data/lib/kitestrings/menu/admin_controller.rb +21 -0
  26. data/lib/kitestrings/menu/controller.rb +24 -0
  27. data/lib/kitestrings/menu/item.rb +94 -0
  28. data/lib/kitestrings/menu/item_collection.rb +29 -0
  29. data/lib/kitestrings/menu/model.rb +29 -0
  30. data/lib/kitestrings/menu/view_helper.rb +68 -0
  31. data/lib/kitestrings/version.rb +1 -1
  32. data/spec/lib/generators/kitestrings/install_generator_spec.rb +17 -13
  33. data/spec/lib/generators/kitestrings/messages_generator_spec.rb +31 -3
  34. data/spec/lib/kitestrings/menu/model_spec.rb +33 -0
  35. data/spec/support/active_record.rb +0 -1
  36. data/spec/support/generator_support.rb +15 -0
  37. metadata +30 -35
  38. data/lib/generators/templates/deploy/integ.rb +0 -21
  39. data/lib/generators/templates/deploy/production.rb +0 -26
  40. data/lib/generators/templates/deploy/uat.rb +0 -23
@@ -1,10 +1,73 @@
1
1
  module Kitestrings
2
2
  module Generators
3
3
  class MessagesGenerator < Rails::Generators::Base
4
- source_root File.expand_path("../templates", __FILE__)
4
+
5
+ include Rails::Generators::Migration
6
+
7
+ source_root File.expand_path("../message_templates", __FILE__)
5
8
 
6
9
  def setup_messages_model
7
10
  template "message.rb.erb", "app/models/message.rb"
11
+ copy_file "message_mailer.rb", "app/mailers/message_mailer.rb"
12
+ copy_file "default.text.erb", "app/views/message_mailer/default.text.erb"
13
+ copy_file "message_spec.rb", "spec/models/message_spec.rb"
14
+ copy_file "messages.rb", "spec/factories/messages.rb"
15
+ copy_file "messages_controller.rb", "app/controllers/messages_controller.rb"
16
+ copy_file "messages_controller_spec.rb", "spec/controllers/messages_controller_spec.rb"
17
+ copy_file "index.html.haml", "app/views/messages/index.html.haml"
18
+ copy_file "show.html.haml", "app/views/messages/show.html.haml"
19
+
20
+ if Dir.glob(destination_root + "/db/migrate/*create_messages.rb").count == 0
21
+ migration_template "message_migration.rb", "db/migrate/create_messages.rb"
22
+ end
23
+
24
+ routes = <<RUBY
25
+ resources :messages, only: [:index, :show]
26
+ # also nest under user, for example:
27
+ # resources :user do
28
+ # resources :messages, only: [:index, :show]
29
+ # end
30
+ RUBY
31
+ inject_into_file "config/routes.rb", routes, :before => /^end/
32
+
33
+
34
+ puts <<OUTPUT
35
+ -------------------------------------------------------------------------------
36
+
37
+ Kitestrings Message scaffold. Please complete the following manually:
38
+
39
+ 1. Check config/routes.rb for nesting messages under the user model. For example:
40
+
41
+ resources :user do
42
+ resources :messages, only: [:index, :show]
43
+ end
44
+
45
+ 2. Update CanCan abilities so users can read their messages, for example:
46
+
47
+ can(:read, Message) { |message| message.user == user }
48
+ can(:index_all, Message) if user.admin?
49
+
50
+ 3. Add the following to your user model
51
+
52
+ has_many :messages
53
+
54
+ 4. Set the default host. This is needed as the Message model needs to generate
55
+ absolute URLs to be inserted into email bodies. Example, add to routes.rb:
56
+
57
+ default_url_options :host => (ENV['DEFAULT_URL_HOST'] || 'localhost')
58
+
59
+ 5. Add "message" and "message_other" to your common lets. Example:
60
+
61
+ # Messages
62
+ let(:message) { create :message, user: user }
63
+ let(:message_other) { create :message, user: user_other }
64
+
65
+ -------------------------------------------------------------------------------
66
+ OUTPUT
67
+ end
68
+
69
+ def self.next_migration_number(dirname)
70
+ Time.now.utc.strftime("%Y%m%d%H%M%S")
8
71
  end
9
72
  end
10
73
  end
@@ -5,18 +5,20 @@ require 'airbrake/capistrano'
5
5
 
6
6
  set :stages, %w(integ, uat, production)
7
7
  set :default_stage, "integ"
8
- set :application, 'pwi'
9
- set :user, 'pwi'
8
+ set :application, 'APP_NAME'
9
+ set :user, 'APP_NAME'
10
10
  set (:deploy_to) { "/home/#{user}/apps/#{rails_env}" }
11
11
  set :deploy_via, :remote_cache
12
12
  set :use_sudo, false
13
13
  set :scm, 'git'
14
- #set :repository, 'git@github.com:2rk/pwi.git'
14
+
15
+ #set :repository, 'git@github.com:2rk/APP_NAME.git'
15
16
 
16
17
  set :ssl, false
17
- # set :ssl_certificates_path, '/home/amt/ssl'
18
- # set :ssl_certificates_name, 'amt'
18
+ # set :ssl_certificates_path, '/home/APP_NAME/ssl'
19
+ # set :ssl_certificates_name, 'APP_NAME'
19
20
 
21
+ set :rvm_ruby_string, File.read(".ruby-version").chomp
20
22
  set :mysql_password, YAML::load_file("config/database.yml.server")["production"]["password"]
21
23
  set :bundle_flags, "--deployment"
22
24
 
@@ -68,9 +70,11 @@ conf
68
70
 
69
71
 
70
72
  task :github_ssh_key do
71
- run "ssh-keygen -t rsa -f ~/.ssh/id_rsa -P ''; ssh -oStrictHostKeyChecking=no git@github.com; cat .ssh/id_rsa.pub"
73
+ run "if [ ! -f ~/.ssh/id_rsa ]; then ssh-keygen -t rsa -f ~/.ssh/id_rsa -P ''; fi"
74
+ # This will return an error back but it is not an issue
75
+ run "ssh -T -oStrictHostKeyChecking=no git@github.com; true"
76
+ run "cat .ssh/id_rsa.pub"
72
77
  end
73
-
74
78
  task :symlink_config do
75
79
  run "ln -nfs #{shared_path}/config/database.yml #{release_path}/config/database.yml"
76
80
  end
@@ -102,7 +106,7 @@ namespace :ruby_make do
102
106
  desc "Run a task on a remote server."
103
107
  # run like: cap staging rake:invoke task=a_certain_task
104
108
  task :invoke do
105
- run("cd #{deploy_to}/current; /usr/bin/env rake #{ENV['task']} RAILS_ENV=#{rails_env}")
109
+ run("cd #{deploy_to}/current; bin/rake #{ENV['task']} RAILS_ENV=#{rails_env}")
106
110
  end
107
111
  end
108
112
 
@@ -121,16 +125,15 @@ namespace :deploy do
121
125
  end
122
126
  desc "reload the database with seed data"
123
127
  task :seed do
124
- run "cd #{current_path}; bundle exec rake db:seed RAILS_ENV=#{rails_env}"
128
+ run "cd #{current_path}; bin/rake db:seed RAILS_ENV=#{rails_env}"
125
129
  end
126
130
  end
127
131
 
128
- namespace :rvm do
129
- task :trust_rvmrc do
130
- run "rvm rvmrc trust #{release_path}"
131
- end
132
- end
133
-
134
- after "deploy", "rvm:trust_rvmrc"
135
132
  after 'deploy:setup', 'deploy:create_database', 'deploy:github_ssh_key', 'deploy:nginx_conf', 'deploy:create_shared_database_config'
136
133
  after 'deploy:cold', 'deploy:airbrake_test'
134
+
135
+ before 'deploy:setup', 'rvm:install_rvm' # update RVM
136
+ before 'deploy:setup', 'rvm:install_ruby'
137
+
138
+ # load additional deploy steps and configuration from lib/capistrano/*.cap files:
139
+ Dir["lib/capistrano/*.cap"].each { |file| load file }
@@ -0,0 +1,3 @@
1
+ set :rails_env, 'integ'
2
+ set :branch, 'develop'
3
+ #server 'APP_NAME.integ.tworedkites.com', :web, :app, :db, primary: true
@@ -0,0 +1,12 @@
1
+ set :rails_env, 'production'
2
+
3
+ $:.unshift(File.expand_path('./lib', ENV['rvm_path']))
4
+
5
+ set :rvm_install_ruby_params, '--verify-downloads 1'
6
+ set :rvm_type, :user
7
+ set :branch, 'master'
8
+
9
+ #default_run_option[:pty] = true
10
+ ssh_options[:forward_agent] = true
11
+
12
+ #server 'APP_NAME.production.tworedkites.com', :web, :app, :db, primary: true
@@ -0,0 +1,3 @@
1
+ set :rails_env, 'uat'
2
+ set :branch, 'develop'
3
+ #server 'APP_NAME.uat.tworedkites.com', :web, :app, :db, primary: true
@@ -0,0 +1,21 @@
1
+ load File.expand_path("../production.rb", __FILE__)
2
+
3
+ Rails.application.configure do
4
+
5
+ config.loglevel = :debug
6
+
7
+ # config.airbrake_api_key = 'AIRBRAKE_KEY'
8
+
9
+ # used by message model to create links (outside of a controller / mailer)
10
+ Rails.application.routes.default_url_options[:host] = 'APP_NAME.integ.tworedkites.com'
11
+
12
+ # config.action_mailer.delivery_method = :mail_gate
13
+ # config.action_mailer.mail_gate_settings = {
14
+ # :whitelist => /VALIDATE_EMAIL_REGEX/,
15
+ # :subject_prefix => '[INTEG] ',
16
+ # :delivery_method => :smtp,
17
+ # :smtp_settings => {
18
+ # :address => 'smtp.example.com'
19
+ # }
20
+ # }
21
+ end
@@ -0,0 +1,21 @@
1
+ load File.expand_path("../production.rb", __FILE__)
2
+
3
+ Rails.application.configure do
4
+
5
+ config.log_level = :info
6
+
7
+ # config.airbrake_api_key = 'AIRBRAKE_KEY'
8
+
9
+ # used by message model to create links (outside of a controller / mailer)
10
+ Rails.application.routes.default_url_options[:host] = 'APP_NAME.uat.tworedkites.com'
11
+
12
+ # config.action_mailer.delivery_method = :mail_gate
13
+ # config.action_mailer.mail_gate_settings = {
14
+ # :whitelist => /VALIDATE_EMAIL_REGEX/,
15
+ # :subject_prefix => '[UAT] ',
16
+ # :delivery_method => :smtp,
17
+ # :smtp_settings => {
18
+ # :address => 'smtp.example.com'
19
+ # }
20
+ # }
21
+ end
@@ -0,0 +1,30 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Access Denied (403)</title>
5
+ <style type="text/css">
6
+ body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
7
+ div.dialog {
8
+ width: 25em;
9
+ padding: 0 4em;
10
+ margin: 4em auto 0 auto;
11
+ border: 1px solid #ccc;
12
+ border-right-color: #999;
13
+ border-bottom-color: #999;
14
+ }
15
+ h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
16
+ </style>
17
+ </head>
18
+
19
+ <body>
20
+ <!-- This file lives in public/500.html -->
21
+ <div class="dialog">
22
+ <h1>Access Denied.</h1>
23
+ <p>
24
+ You do not have permissions to view the current page.
25
+ </p>
26
+ <p>&nbsp;</p>
27
+ <p>Click <a href="/">here</a> to return to the home page.</p>
28
+ </div>
29
+ </body>
30
+ </html>
@@ -0,0 +1,10 @@
1
+ module Kitestrings::Menu
2
+ extend ActiveSupport::Concern
3
+
4
+ # include Kitestrings::Menu into ApplicationController or each controller where required.
5
+ included do
6
+ include Controller
7
+ helper ViewHelper
8
+ helper_method :current_menu_item
9
+ end
10
+ end
@@ -0,0 +1,21 @@
1
+ module Kitestrings
2
+ module Menu::AdminController
3
+ def menu_context
4
+ Admin.new
5
+ end
6
+
7
+ # this class acts like a Menu::Item
8
+ class Admin
9
+
10
+ # pretend to be a persisted resource (new pages don't show context menu)
11
+ def persisted?
12
+ true
13
+ end
14
+
15
+ # use 'admin' as the menu partial name
16
+ def partial_name
17
+ "admin"
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,24 @@
1
+ module Kitestrings
2
+ module Menu::Controller
3
+ # return an array of the menu items constructed as polymorphic paths. For example, if loaded_resources was:
4
+ # [Company:1, Project:2, Audit:3] then this would return an array of Menu::Item objects for the following paths:
5
+ # - /companies/1
6
+ # - /companies/1/projects/2
7
+ # - /companies/1/projects/2/audits/3
8
+ #
9
+ # Each item is constructed with polymorphic path
10
+ def loaded_menu_items
11
+ @loaded_menu_items ||= Menu::ItemCollection.new(loaded_resources)
12
+ end
13
+
14
+ # get the menu item for the contextual menu (second row). On an index page, this is the item the index is nested
15
+ # under, if present. For normal pages it is the last item in the array.
16
+ def current_menu_item
17
+ if action_name == "index"
18
+ loaded_menu_items[-2]
19
+ else
20
+ loaded_menu_items[-1]
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,94 @@
1
+ module Kitestrings::Menu
2
+ # A class to represent an item in the menu. It is capable of looking up menu item paths and names and a link id,
3
+ # all the required data to construct links, include links to subpaths
4
+ class Item
5
+ include Rails.application.routes.url_helpers
6
+
7
+ attr :resources
8
+ attr_accessor :active
9
+
10
+ def initialize(resources)
11
+ @resources = resources
12
+ end
13
+
14
+ # the path of the item. eg: /companies/1/projects/2/audits/3
15
+ def path
16
+ @path ||= polymorphic_path @resources
17
+ end
18
+
19
+ # return a new item with the given extra resources added to the resource list.
20
+ def sub_item(*extras)
21
+ Item.new([*@resources, *extras].compact)
22
+ end
23
+
24
+ def parent_item
25
+ Item.new(resources[0..-2])
26
+ end
27
+
28
+ # return the menu display name for the object. This defaults to the .name method of an instance, and the
29
+ # localised human name for classes.
30
+ def name
31
+ object.try(:menu_display_name)
32
+ end
33
+
34
+ # return the name of a menu partial to use for contextual menus relating to this item.
35
+ def partial_name
36
+ last = @resources.last
37
+ klass = last.is_a?(Class) ? last : last.class
38
+ klass.model_name.underscore
39
+ end
40
+
41
+ # fetch the last object in the chain. This is the resource that is actually being rendered. If this is an
42
+ # index action, this will be the class representing the type to be shown in the list.
43
+ def object
44
+ @resources.last
45
+ end
46
+
47
+ # a string to use as a link id in the menu link. Eg: for the path /companies/1/projects/2, the link would be
48
+ # menu_companies_projects_link
49
+ def link_id
50
+ names = @resources.map do |resource|
51
+ case resource
52
+ when Class
53
+ resource.name.pluralize.downcase
54
+ else
55
+ resource.class.name.downcase
56
+ end
57
+ end
58
+ "menu_#{names.join('_')}_link"
59
+ end
60
+
61
+ # Active is set on the last item in the Menu::ItemCollection based on the assumption that this is the active item
62
+ # in the collection.
63
+ def active?
64
+ @active
65
+ end
66
+
67
+ # Should the item be hidden in the menus? If so, menu_link_to will not generate any output. Implement a menu_hidden
68
+ # instance or class method to hide that instance or class from the menu.
69
+ def hidden?
70
+ if object.respond_to? :menu_hidden
71
+ object.menu_hidden
72
+ end
73
+ end
74
+
75
+ def collection?
76
+ object.is_a?(Class)
77
+ end
78
+
79
+ # if this item is for a resource instance (eg: companies/1 => <# Company id:1 #>, then make a new item representing
80
+ # the collection of that class, eg: companies/ => <# Company class #>
81
+ def index_item
82
+ if @resources.last && @resources.last.is_a?(ActiveRecord::Base)
83
+ index_resources = @resources.dup
84
+ index_resources << index_resources.pop.class
85
+ Item.new index_resources
86
+ end
87
+ end
88
+
89
+ # true if the object is persisted. Classes are not persisted.
90
+ def persisted?
91
+ object.respond_to?(:persisted?) && object.persisted?
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,29 @@
1
+ require 'delegate'
2
+
3
+ module Kitestrings
4
+ class Menu::ItemCollection < ::SimpleDelegator
5
+ attr :items
6
+
7
+ def initialize(loaded_resources)
8
+ length = loaded_resources.length
9
+ @items = (0...length).map do |count|
10
+ Menu::Item.new loaded_resources[0..count]
11
+ end
12
+
13
+ # if the last item in the resources is a new_record? object, then substitute it for the class. This will
14
+ # cause polymorphic path to show the #index action in the breadcrumb instead of the new action, or a route
15
+ # error looking for an object that has no id.
16
+ last = @items.last
17
+ if last && last.object.respond_to?(:new_record?) && last.object.new_record?
18
+ @items.pop
19
+ @items << Menu::Item.new(last.resources[0..-2] + [last.object.class])
20
+ end
21
+
22
+ # the last item in the array is assumed to be active.
23
+ @items.last.active = true unless items.empty?
24
+
25
+ # delegate all methods to this array object
26
+ super(@items)
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,29 @@
1
+ module Kitestrings::Menu::Model
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ class_attribute :menu_name_method
6
+
7
+ # default to :name
8
+ self.menu_name_method = :name
9
+ end
10
+
11
+ # get the display name for this item in the menu structure. Defaults to the :name method, can be specified by setting
12
+ # the menu_name_method class attribute on the class.
13
+ def menu_display_name
14
+ case
15
+ when respond_to?(menu_name_method)
16
+ self.send(menu_name_method)
17
+ else
18
+ "##{to_key}"
19
+ end
20
+ end
21
+
22
+ module ClassMethods
23
+ # Get the display name of the collection for this class (index action). This uses ActiveModel::Naming to fetch
24
+ # the plural name of the resource class.
25
+ def menu_display_name
26
+ self.model_name.human.pluralize.titlecase
27
+ end
28
+ end
29
+ end