kitestrings 1.0.2 → 1.0.3

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