katapult 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.ruby-version +1 -1
  4. data/README.md +61 -35
  5. data/bin/katapult +24 -34
  6. data/features/authenticate.feature +344 -0
  7. data/features/basics.feature +590 -0
  8. data/features/binary.feature +33 -1
  9. data/features/model.feature +9 -13
  10. data/features/step_definitions/rails_steps.rb +3 -2
  11. data/features/wui.feature +49 -4
  12. data/lib/generators/katapult/basics/basics_generator.rb +63 -17
  13. data/lib/generators/katapult/basics/templates/.gitignore +1 -0
  14. data/lib/generators/katapult/basics/templates/.ruby-version +1 -1
  15. data/lib/generators/katapult/basics/templates/Capfile +25 -0
  16. data/lib/generators/katapult/basics/templates/Gemfile +14 -6
  17. data/lib/generators/katapult/basics/templates/Guardfile +44 -0
  18. data/lib/generators/katapult/basics/templates/config/database.sample.yml +3 -2
  19. data/lib/generators/katapult/basics/templates/config/database.yml +3 -2
  20. data/lib/generators/katapult/basics/templates/config/deploy/production.rb +8 -0
  21. data/lib/generators/katapult/basics/templates/config/deploy/staging.rb +7 -0
  22. data/lib/generators/katapult/basics/templates/config/deploy.rb +37 -0
  23. data/lib/generators/katapult/basics/templates/config/initializers/ext.rb +3 -0
  24. data/lib/generators/katapult/basics/templates/features/support/factory_girl.rb +1 -0
  25. data/lib/generators/katapult/basics/templates/features/support/paths.rb +6 -0
  26. data/lib/generators/katapult/basics/templates/lib/capistrano/tasks/db.rake +28 -0
  27. data/lib/generators/katapult/basics/templates/lib/capistrano/tasks/deploy.rake +15 -0
  28. data/lib/generators/katapult/basics/templates/lib/capistrano/tasks/passenger.rake +8 -0
  29. data/lib/generators/katapult/basics/templates/{config/initializers → lib/ext/action_view}/form_for_with_development_errors.rb +0 -2
  30. data/lib/generators/katapult/basics/templates/lib/ext/action_view/spec_label.rb +46 -0
  31. data/lib/generators/katapult/basics/templates/{config/initializers → lib/ext/active_record}/find_by_anything.rb +0 -0
  32. data/lib/generators/katapult/basics/templates/lib/ext/active_record/these.rb +7 -0
  33. data/lib/generators/katapult/basics/templates/lib/ext/array/xss_aware_join.rb +10 -0
  34. data/lib/generators/katapult/basics/templates/lib/ext/enumerable/natural_sort.rb +15 -0
  35. data/lib/generators/katapult/basics/templates/lib/ext/hash/infinite.rb +7 -0
  36. data/lib/generators/katapult/basics/templates/lib/ext/string/html_entities.rb +11 -0
  37. data/lib/generators/katapult/basics/templates/lib/ext/string/to_sort_atoms.rb +52 -0
  38. data/lib/generators/katapult/basics/templates/lib/tasks/pending_migrations.rake +24 -0
  39. data/lib/generators/katapult/basics/templates/spec/factories/factories.rb +9 -0
  40. data/lib/generators/katapult/basics/templates/spec/support/factory_girl.rb +3 -0
  41. data/lib/generators/katapult/clearance/clearance_generator.rb +125 -0
  42. data/lib/generators/katapult/clearance/templates/app/controllers/passwords_controller.rb +16 -0
  43. data/lib/generators/katapult/clearance/templates/app/views/clearance_mailer/change_password.html.haml +6 -0
  44. data/lib/generators/katapult/clearance/templates/app/views/clearance_mailer/change_password.text.erb +3 -0
  45. data/lib/generators/katapult/clearance/templates/app/views/passwords/create.html.haml +5 -0
  46. data/lib/generators/katapult/clearance/templates/app/views/passwords/edit.html.haml +16 -0
  47. data/lib/generators/katapult/clearance/templates/app/views/passwords/new.html.haml +14 -0
  48. data/lib/generators/katapult/clearance/templates/app/views/sessions/new.html.haml +19 -0
  49. data/lib/generators/katapult/clearance/templates/config/initializers/clearance.rb +15 -0
  50. data/lib/generators/katapult/clearance/templates/config/locales/clearance.en.yml +59 -0
  51. data/lib/generators/katapult/clearance/templates/features/authentication.feature +94 -0
  52. data/lib/generators/katapult/clearance/templates/features/step_definitions/authentication_steps.rb +4 -0
  53. data/lib/generators/katapult/cucumber_features/templates/feature.feature +11 -7
  54. data/lib/generators/katapult/haml/haml_generator.rb +5 -0
  55. data/lib/generators/katapult/haml/templates/_form.html.haml +4 -4
  56. data/lib/generators/katapult/haml/templates/app/views/layouts/_flashes.html.haml +3 -0
  57. data/lib/generators/katapult/haml/templates/app/views/layouts/application.html.haml +9 -3
  58. data/lib/generators/katapult/haml/templates/index.html.haml +1 -1
  59. data/lib/generators/katapult/haml/templates/show.html.haml +2 -4
  60. data/lib/generators/katapult/install/templates/lib/katapult/application_model.rb +9 -7
  61. data/lib/generators/katapult/model/model_generator.rb +1 -1
  62. data/lib/generators/katapult/w_u_i/templates/controller.rb +1 -1
  63. data/lib/generators/katapult/w_u_i/w_u_i_generator.rb +4 -2
  64. data/lib/katapult/application_model.rb +8 -1
  65. data/lib/katapult/attribute.rb +10 -11
  66. data/lib/katapult/authentication.rb +25 -0
  67. data/lib/katapult/binary_util.rb +37 -0
  68. data/lib/katapult/element.rb +1 -1
  69. data/lib/katapult/generator.rb +6 -0
  70. data/lib/katapult/model.rb +13 -1
  71. data/lib/katapult/parser.rb +7 -0
  72. data/lib/katapult/version.rb +1 -1
  73. data/lib/katapult/wui.rb +4 -0
  74. data/lib/katapult.rb +2 -0
  75. data/spec/attribute_spec.rb +13 -0
  76. data/spec/element_spec.rb +5 -0
  77. data/spec/model_spec.rb +5 -4
  78. data/spec/util_spec.rb +8 -8
  79. data/spec/wui_spec.rb +19 -0
  80. metadata +44 -8
  81. data/features/katapult.feature +0 -271
  82. data/lib/katapult/util.rb +0 -16
@@ -1,3 +1,5 @@
1
+ require 'katapult/binary_util'
2
+
1
3
  module KatapultRailsHelper
2
4
 
3
5
  def with_aruba_timeout(timeout, &block)
@@ -12,10 +14,9 @@ module KatapultRailsHelper
12
14
 
13
15
  def create_cached_app(name)
14
16
  job = 'Cached Rails app generation'
15
- rails_new_command = "bundle exec rails new #{name} --skip-test-unit --skip-bundle --database mysql"
16
17
 
17
18
  puts "#{job} started (in #{Dir.pwd})"
18
- system(rails_new_command) or raise "#{job} failed"
19
+ Katapult::BinaryUtil.create_rails_app(name)
19
20
  puts "#{job} done."
20
21
  end
21
22
 
data/features/wui.feature CHANGED
@@ -14,9 +14,14 @@ Feature: Web User Interface
14
14
  customer.attr :age, type: :integer
15
15
 
16
16
  customer.attr :email
17
+ customer.attr :password
17
18
  customer.attr :revenue, type: :money
18
19
  customer.attr :homepage, type: :url, default: 'http://www.makandra.de'
19
20
  customer.attr :locked, type: :flag, default: false
21
+ customer.attr :notes, type: :text
22
+ customer.attr :first_visit, type: :datetime
23
+ customer.attr :indexable_data, type: :json
24
+ customer.attr :plain_data, type: :plain_json
20
25
  end
21
26
 
22
27
  wui 'customer', model: 'customer' do |wui|
@@ -107,7 +112,7 @@ Feature: Web User Interface
107
112
 
108
113
  def customer_params
109
114
  customer_params = params[:customer]
110
- customer_params ? customer_params.permit([:name, :age, :email, :revenue, :homepage, :locked]) : {}
115
+ customer_params ? customer_params.permit(%i[name age email password revenue homepage locked notes first_visit indexable_data plain_data]) : {}
111
116
  end
112
117
 
113
118
  def customer_scope
@@ -149,7 +154,7 @@ Feature: Web User Interface
149
154
  %td
150
155
  .items__actions
151
156
  = link_to 'Edit', edit_customer_path(customer), class: 'items__action'
152
- = link_to 'Destroy', customer_path(customer), method: :delete, class: 'items__action', confirm: 'Really destroy?'
157
+ = link_to 'Destroy', customer_path(customer), method: :delete, class: 'items__action', data: { confirm: 'Really destroy?' }, title: "Destroy #{customer.to_s}"
153
158
  = link_to 'Get Member', get_member_customer_path(customer), class: 'items__action'
154
159
  = link_to 'Post Member', post_member_customer_path(customer), class: 'items__action', method: :post
155
160
 
@@ -196,8 +201,19 @@ Feature: Web User Interface
196
201
  = Customer.human_attribute_name(:locked)
197
202
  %dd
198
203
  = @customer.locked ? 'Yes' : 'No'
204
+ %dt
205
+ = Customer.human_attribute_name(:notes)
206
+ %dd
207
+ = simple_format(@customer.notes)
208
+ %dt
209
+ = Customer.human_attribute_name(:first_visit)
210
+ %dd
211
+ = l(@customer.first_visit.to_date) if @customer.first_visit
199
212
 
200
213
  """
214
+ # Note that no views are generated for JSON fields, as they are mainly data
215
+ # storage fields
216
+
201
217
  And the file "app/views/customers/new.html.haml" should contain exactly:
202
218
  """
203
219
  %h1
@@ -231,6 +247,10 @@ Feature: Web User Interface
231
247
  = form.label :email
232
248
  %dd
233
249
  = form.email_field :email
250
+ %dt
251
+ = form.label :password
252
+ %dd
253
+ = form.password_field :password
234
254
  %dt
235
255
  = form.label :revenue
236
256
  %dd
@@ -244,6 +264,14 @@ Feature: Web User Interface
244
264
  = form.label :locked
245
265
  %dd
246
266
  = form.check_box :locked
267
+ %dt
268
+ = form.label :notes
269
+ %dd
270
+ = form.text_area :notes, rows: 5
271
+ %dt
272
+ = form.label :first_visit
273
+ %dd
274
+ = form.date_field :first_visit
247
275
 
248
276
  .tools
249
277
  = form.submit 'Save', class: 'tools__button is_primary'
@@ -283,9 +311,12 @@ Feature: Web User Interface
283
311
  And I fill in "Name" with "name-string"
284
312
  And I fill in "Age" with "778"
285
313
  And I fill in "Email" with "email@example.com"
314
+ And I fill in "Password" with "password-password"
286
315
  And I fill in "Revenue" with "2.21"
287
316
  And I fill in "Homepage" with "homepage.example.com"
288
317
  And I check "Locked"
318
+ And I fill in "Notes" with "notes-text"
319
+ And I fill in "First visit" with "2022-03-25"
289
320
  And I press "Save"
290
321
 
291
322
  # read
@@ -296,6 +327,8 @@ Feature: Web User Interface
296
327
  And I should see "2.21"
297
328
  And I should see "homepage.example.com"
298
329
  And I should see "Locked Yes"
330
+ And I should see "notes-text"
331
+ And I should see "2022-03-25"
299
332
 
300
333
  # update
301
334
  When I follow "Edit"
@@ -306,12 +339,14 @@ Feature: Web User Interface
306
339
  And the "Revenue" field should contain "2.21"
307
340
  And the "Homepage" field should contain "homepage.example.com"
308
341
  And the "Locked" checkbox should be checked
342
+ And the "Notes" field should contain "notes-text"
343
+ And the "First visit" field should contain "2022-03-25"
309
344
 
310
345
  # destroy
311
346
  When I go to the list of customers
312
347
  Then I should see "name-string"
313
348
 
314
- When I follow "Destroy"
349
+ When I follow "Destroy name-string"
315
350
  Then I should be on the list of customers
316
351
  But I should not see "name-string"
317
352
 
@@ -321,7 +356,7 @@ Feature: Web User Interface
321
356
  Then the features should pass
322
357
 
323
358
 
324
- Scenario: Generate layout file with query diet widget
359
+ Scenario: A WUI also generates the application layout file
325
360
  When I overwrite "lib/katapult/application_model.rb" with:
326
361
  """
327
362
  model 'Car'
@@ -332,3 +367,13 @@ Feature: Web User Interface
332
367
  """
333
368
  = query_diet_widget(bad_count: 15) if Rails.env.development?
334
369
  """
370
+ And the file "app/views/layouts/application.html.haml" should contain:
371
+ """
372
+ = render 'layouts/flashes'
373
+ """
374
+ And the file "app/views/layouts/_flashes.html.haml" should contain:
375
+ """
376
+ - flash.each do |level, message|
377
+ .flash.alert.alert-info
378
+ = message
379
+ """
@@ -4,14 +4,14 @@ module Katapult
4
4
  module Generators
5
5
  class BasicsGenerator < Rails::Generators::Base
6
6
 
7
- SKIP_GEMS = %w(sass-rails coffee-rails turbolinks sdoc uglifier mysql2)
7
+ SKIP_GEMS = %w(sass-rails coffee-rails turbolinks sdoc uglifier)
8
8
 
9
9
  desc 'Generate basics like test directories and gems'
10
10
  source_root File.expand_path('../templates', __FILE__)
11
11
 
12
- class_option :db_user, type: :string,
12
+ class_option :db_user, type: :string, default: 'root',
13
13
  description: 'The user to set in config/database.yml'
14
- class_option :db_password, type: :string,
14
+ class_option :db_password, type: :string, default: '',
15
15
  description: 'The password to set in config/database.yml'
16
16
 
17
17
 
@@ -24,8 +24,8 @@ module Katapult
24
24
  end
25
25
 
26
26
  def write_database_ymls
27
- @db_user = options.db_user || 'root'
28
- @db_password = options.db_password || ''
27
+ @db_user = options.db_user
28
+ @db_password = options.db_password
29
29
 
30
30
  template 'config/database.yml', force: true
31
31
  template 'config/database.sample.yml'
@@ -45,15 +45,15 @@ module Katapult
45
45
  def bundle_install
46
46
  run 'bundle install'
47
47
 
48
- # There is a bug in the current version of Compass, so we use an older
49
- # one in our Gemfile template. Since its dependencies "sprockets" and
50
- # "sass-rails" are already in the Gemfile.lock (from installing Rails),
51
- # we need to explicitly update them.
52
- run 'bundle update sprockets sass-rails'
48
+ # This is relevant for the server, so it may happen after bundling here.
49
+ # By having Nokogiri use system libraries, it will get automatic updates
50
+ # of the frequently broken libxml (i.e. when the system libxml updates).
51
+ run 'bundle config --local build.nokogiri --use-system-libraries'
53
52
  end
54
53
 
55
54
  def remove_turbolinks_js
56
55
  gsub_file 'app/assets/javascripts/application.js', "//= require turbolinks\n", ''
56
+ gsub_file 'app/views/layouts/application.html.erb', ", 'data-turbolinks-track' => true", ''
57
57
  end
58
58
 
59
59
  def setup_spring
@@ -64,8 +64,38 @@ module Katapult
64
64
  run 'spring stop' # Reload (just in case)
65
65
  end
66
66
 
67
+ def setup_guard
68
+ template 'Guardfile'
69
+ environment 'config.middleware.use Rack::LiveReload', env: :development
70
+ end
71
+
72
+ def setup_staging
73
+ FileUtils.copy 'config/environments/production.rb', 'config/environments/staging.rb'
74
+ secret = `rake secret`.chomp
75
+ # Cheating in the "staging" secret between "test" and "production"
76
+ insert_into_file 'config/secrets.yml', <<~SECRET, after: "test:\n"
77
+ secret_key_base: #{ secret }
78
+
79
+ staging:
80
+ SECRET
81
+ end
82
+
67
83
  def create_databases
68
- run 'rake db:create:all parallel:create'
84
+ run 'rake db:drop:all db:create:all parallel:create'
85
+ end
86
+
87
+ def configure_action_mailer
88
+ app_con = 'app/controllers/application_controller.rb'
89
+ inject_into_file app_con, <<-CONFIG, before: /end\n\z/
90
+ before_filter :make_action_mailer_use_request_host_and_protocol
91
+
92
+ private
93
+
94
+ def make_action_mailer_use_request_host_and_protocol
95
+ ActionMailer::Base.default_url_options[:protocol] = request.protocol
96
+ ActionMailer::Base.default_url_options[:host] = request.host_with_port
97
+ end
98
+ CONFIG
69
99
  end
70
100
 
71
101
  def set_timezone
@@ -74,8 +104,8 @@ module Katapult
74
104
  "config.time_zone = 'Berlin'"
75
105
  end
76
106
 
77
- def make_assets_debuggable
78
- gsub_file 'config/application.rb',
107
+ def disable_asset_debugging # Faster
108
+ gsub_file 'config/environments/development.rb',
79
109
  /config\.assets\.debug =.*$/,
80
110
  'config.assets.debug = false'
81
111
  end
@@ -84,6 +114,10 @@ module Katapult
84
114
  directory 'config/initializers'
85
115
  end
86
116
 
117
+ def install_ext
118
+ directory 'lib/ext'
119
+ end
120
+
87
121
  def add_modularity_load_paths
88
122
  # This results in correct indentation :)
89
123
  application <<-'LOAD_PATHS'
@@ -109,6 +143,22 @@ config.autoload_paths << "#{Rails.root}/app/controllers/shared"
109
143
  gsub_file '.rspec', "--warnings\n", '' # Don't show Ruby warnings
110
144
  uncomment_lines 'spec/rails_helper.rb', /Dir.Rails.root.join.+spec.support/
111
145
  template 'spec/support/shoulda_matchers.rb'
146
+ template 'spec/support/factory_girl.rb'
147
+ directory 'spec/factories'
148
+ end
149
+
150
+ def install_capistrano
151
+ # Create Capfile *before* installing Capistrano to prevent annoying
152
+ # Harrow.io ad
153
+ template 'Capfile', force: true
154
+ run 'cap install'
155
+
156
+ template 'config/deploy.rb', force: true
157
+ template 'config/deploy/staging.rb', force: true
158
+ template 'config/deploy/production.rb', force: true
159
+
160
+ directory 'lib/capistrano/tasks'
161
+ template 'lib/tasks/pending_migrations.rake'
112
162
  end
113
163
 
114
164
  def install_styles
@@ -116,10 +166,6 @@ config.autoload_paths << "#{Rails.root}/app/controllers/shared"
116
166
  directory 'app/assets/stylesheets', force: true
117
167
  end
118
168
 
119
- # def install_capistrano
120
- # capify!
121
- # template 'config/deploy.rb'
122
- # end
123
169
 
124
170
  private
125
171
 
@@ -25,3 +25,4 @@ coverage/*
25
25
  dump_for_download.dump
26
26
  .~lock.*
27
27
  .*.swp
28
+ .byebug_history
@@ -1 +1 @@
1
- 2.1.5
1
+ <%= Katapult::RUBY_VERSION %>
@@ -0,0 +1,25 @@
1
+ # Load DSL and set up stages
2
+ require 'capistrano/setup'
3
+
4
+ # Include default deployment tasks
5
+ require 'capistrano/deploy'
6
+
7
+ # Include tasks from other gems included in your Gemfile
8
+ require 'capistrano/bundler'
9
+ require 'capistrano/maintenance'
10
+ require 'capistrano/rails/assets'
11
+ require 'capistrano/rails/migrations'
12
+ require 'whenever/capistrano'
13
+
14
+ Dir.glob('lib/capistrano/tasks/*.rake').each do |r|
15
+ # `import r` calls Rake.application.add_import(r), which imports the file only
16
+ # *after* this file has been processed, so the imported tasks would not be
17
+ # available to the hooks below.
18
+ Rake.load_rakefile r
19
+ end
20
+
21
+ before 'deploy:updating', 'db:dump'
22
+ after 'deploy:published', 'deploy:restart'
23
+ after 'deploy:published', 'db:warn_if_pending_migrations'
24
+ after 'deploy:published', 'db:show_dump_usage'
25
+ after 'deploy:finished', 'deploy:cleanup' # https://makandracards.com/makandra/1432
@@ -1,15 +1,14 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- # from original Gemfile
4
3
  <%= @original_gems.join %>
5
4
 
6
- # engines
7
- gem 'haml-rails'
8
- gem 'mysql2', '~> 0.3.18' # Work around require-error in Rails 4.2
9
-
10
5
  # internal
11
6
  gem 'exception_notification'
7
+ # gem 'admin_cleaner', git: 'git@code.makandra.de:makandra/admin_cleaner.git'
8
+
9
+ # security
12
10
  gem 'breach-mitigation-rails'
11
+ gem 'safe_cookies'
13
12
 
14
13
  # better coding
15
14
  gem 'modularity'
@@ -33,12 +32,14 @@ gem 'will_paginate'
33
32
  gem 'makandra-navy', require: 'navy'
34
33
 
35
34
  # assets
35
+ gem 'haml-rails'
36
36
  gem 'bootstrap-sass'
37
37
  gem 'sass-rails'
38
38
  gem 'autoprefixer-rails'
39
39
  gem 'coffee-rails'
40
+ gem 'therubyracer', platform: :ruby
40
41
  gem 'uglifier'
41
- gem 'compass-rails', '>= 2.0.4' # fixes "uninitialized constant Sprockets::SassCacheStore"
42
+ gem 'compass-rails'
42
43
  gem 'compass-rgbapng'
43
44
 
44
45
  group :development do
@@ -68,6 +69,7 @@ group :test do
68
69
 
69
70
  gem 'capybara'
70
71
  gem 'capybara-screenshot'
72
+ gem 'cucumber', '< 2' # Incompatible with Cucumber Factory
71
73
  gem 'cucumber-rails', require: false
72
74
  gem 'cucumber_factory'
73
75
  gem 'selenium-webdriver'
@@ -76,3 +78,9 @@ group :test do
76
78
  gem 'rspec'
77
79
  gem 'shoulda-matchers', require: false
78
80
  end
81
+
82
+ group :deploy do
83
+ gem 'capistrano-rails', require: false
84
+ gem 'capistrano-bundler', require: false
85
+ gem 'capistrano-maintenance'
86
+ end
@@ -0,0 +1,44 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ ## Uncomment and set this to only include directories you want to watch
5
+ # directories %w(app lib config test spec features)
6
+
7
+ ## Uncomment to clear the screen before every task
8
+ # clearing :on
9
+
10
+ ## Guard internally checks for changes in the Guardfile and exits.
11
+ ## If you want Guard to automatically start up again, run guard in a
12
+ ## shell loop, e.g.:
13
+ ##
14
+ ## $ while bundle exec guard; do echo "Restarting Guard..."; done
15
+ ##
16
+ ## Note: if you are using the `directories` clause above and you are not
17
+ ## watching the project directory ('.'), then you will want to move
18
+ ## the Guardfile to a watched dir and symlink it back, e.g.
19
+ #
20
+ # $ mkdir config
21
+ # $ mv Guardfile config/
22
+ # $ ln -s config/Guardfile .
23
+ #
24
+ # and, you'll have to watch "config/Guardfile" instead of "Guardfile"
25
+
26
+ guard 'livereload' do
27
+ watch %r{app/views/.+\.(erb|haml)$}
28
+ watch 'app/models/navigation.rb' # Navy
29
+ watch 'app/models/power.rb' # Consul
30
+ watch %r{app/helpers/.+\.rb}
31
+ watch %r{public/.+\.(css|js|html)}
32
+ watch %r{config/locales/.+\.yml}
33
+ watch %r{spec/javascripts/} # Jasmine
34
+
35
+ # Rails Assets Pipeline
36
+ watch(%r{(app|vendor)(/assets/\w+/(.+\.(css|sass|js|coffee|html|png|jpg))).*}) do |m|
37
+ filename = m[3]
38
+ # When a .sass (or .css.sass) file was changed, tell the client to load the .css version.
39
+ # Similarly, for .coffee / .js.coffee files we ask the client to reload the .js file.
40
+ filename.gsub! /(\.css)?\.sass$/, '.css'
41
+ filename.gsub! /(\.js)?\.coffee$/, '.js'
42
+ "/assets/#{filename}"
43
+ end
44
+ end
@@ -1,6 +1,7 @@
1
1
  common: &common
2
- adapter: mysql2
3
- encoding: utf8
2
+ adapter: postgresql
3
+ encoding: unicode
4
+ host: localhost
4
5
  username: root
5
6
  password:
6
7
 
@@ -1,6 +1,7 @@
1
1
  common: &common
2
- adapter: mysql2
3
- encoding: utf8
2
+ adapter: postgresql
3
+ encoding: unicode
4
+ host: localhost
4
5
  username: <%= @db_user %>
5
6
  password: <%= @db_password %>
6
7
 
@@ -0,0 +1,8 @@
1
+ set :stage, :production
2
+
3
+ set :deploy_to, '/var/www/<%= app_name %>'
4
+ set :rails_env, 'production'
5
+ set :branch, 'production'
6
+
7
+ # server 'one.example.com', user: 'deploy-user', roles: %w(app web cron db)
8
+ # server 'two.example.com', user: 'deploy-user', roles: %w(app web)
@@ -0,0 +1,7 @@
1
+ set :stage, :staging
2
+
3
+ set :deploy_to, '/var/www/<%= app_name %>-staging'
4
+ set :rails_env, 'staging'
5
+ set :branch, ENV['DEPLOY_BRANCH'] || 'master'
6
+
7
+ # server 'example.com', user: 'deploy-user', roles: %w(app web cron db)
@@ -0,0 +1,37 @@
1
+ abort 'You must run this using "bundle exec ..."' unless ENV['BUNDLE_BIN_PATH'] || ENV['BUNDLE_GEMFILE']
2
+
3
+ # config valid only for current version of Capistrano
4
+ lock '3.4.0'
5
+
6
+ # Default value for :format is :pretty
7
+ # set :format, :pretty
8
+
9
+ set :log_level, :info # %i(debug info error), default: :debug
10
+
11
+ # Default value for :pty is false
12
+ # set :pty, true
13
+
14
+ # Default value for :linked_files is []
15
+ # set :linked_files, fetch(:linked_files, []).push('config/database.yml', 'config/secrets.yml')
16
+ set :linked_files, %w(config/database.yml)
17
+
18
+ # Default value for linked_dirs is []
19
+ # set :linked_dirs, fetch(:linked_dirs, []).push('log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'vendor/bundle', 'public/system')
20
+ set :linked_dirs, %w(log public/system)
21
+
22
+ # Default value for default_env is {}
23
+ # set :default_env, { path: "/opt/ruby/bin:$PATH" }
24
+
25
+ set :application, '<%= app_name %>'
26
+ set :keep_releases, 10
27
+ set :ssh_options, {
28
+ forward_agent: true
29
+ }
30
+ set :scm, :git
31
+ set :repo_url, 'git@code.makandra.de:makandra/<%= app_name %>.git'
32
+
33
+ # set :whenever_roles, :cron
34
+ # set :whenever_environment, defer { stage }
35
+ # set :whenever_command, 'bundle exec whenever'
36
+
37
+ set :maintenance_template_path, 'public/maintenance.html.erb'
@@ -0,0 +1,3 @@
1
+ Dir.glob(Rails.root.join('lib/ext/**/*.rb')).each do |filename|
2
+ require filename
3
+ end
@@ -0,0 +1 @@
1
+ World(FactoryGirl::Syntax::Methods)
@@ -3,6 +3,9 @@ module NavigationHelpers
3
3
  def path_to(page_name)
4
4
  case page_name
5
5
 
6
+ when 'the homepage'
7
+ root_path
8
+
6
9
  when /^the list of (.*?)$/
7
10
  models_prose = $1
8
11
  route = "#{model_prose_to_route_segment(models_prose)}_path"
@@ -27,6 +30,9 @@ module NavigationHelpers
27
30
  route = "new_#{model_prose_to_route_segment(model_prose)}_path"
28
31
  send(route)
29
32
 
33
+ when /"(.+?)"$/
34
+ $1
35
+
30
36
  end
31
37
  end
32
38
 
@@ -0,0 +1,28 @@
1
+ namespace :db do
2
+ desc 'Warn about pending migrations'
3
+ task :warn_if_pending_migrations do
4
+ on primary :db do
5
+ within current_path do
6
+ with rails_env: fetch(:rails_env, 'production') do
7
+ rake 'db:warn_if_pending_migrations'
8
+ end
9
+ end
10
+ end
11
+ end
12
+
13
+ desc 'Do a dump of the DB on the remote machine using dumple'
14
+ task :dump do
15
+ on primary :db do
16
+ within current_path do
17
+ execute :dumple, '--fail-gently', fetch(:rails_env, 'production')
18
+ end
19
+ end
20
+ end
21
+
22
+ desc 'Show usage of ~/dumps/ on remote host'
23
+ task :show_dump_usage do
24
+ on primary :db do
25
+ info capture :dumple, '-i'
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,15 @@
1
+ namespace :deploy do
2
+ desc 'Restart application'
3
+ task :restart do
4
+ invoke 'passenger:restart'
5
+ end
6
+
7
+ desc 'Show deployed revision'
8
+ task :revision do
9
+ on roles :app do
10
+ within current_path do
11
+ info "Revision: #{ capture :cat, 'REVISION' }"
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,8 @@
1
+ namespace :passenger do
2
+ desc 'Restart Application'
3
+ task :restart do
4
+ on roles :app do
5
+ execute "sudo passenger-config restart-app --ignore-app-not-running #{ fetch(:deploy_to) }"
6
+ end
7
+ end
8
+ end
@@ -33,7 +33,6 @@ if Rails.env == 'development'
33
33
  html << '</style>'.html_safe
34
34
  end
35
35
  html << capture(form, &block)
36
- Rails.version.to_i < 3 ? concat(html) : html
37
36
  end
38
37
  end
39
38
 
@@ -42,4 +41,3 @@ if Rails.env == 'development'
42
41
  end
43
42
 
44
43
  end
45
-
@@ -0,0 +1,46 @@
1
+ ActionView::Helpers::FormBuilder.class_eval do
2
+
3
+ def spec_label(field, text = nil, options = {})
4
+ label_html = label(field)
5
+ element = parse_element(label_html, 'label')
6
+ id = element['for']
7
+ text ||= element.text
8
+ @template.spec_label_tag(id, text, options)
9
+ end
10
+
11
+ private
12
+
13
+ def parse_element(html, tag)
14
+ doc = Nokogiri::XML(html)
15
+ doc.css(tag).first or raise "Could not find CSS #{tag.inspect} in HTML #{html.inspect}"
16
+ end
17
+
18
+ end
19
+
20
+ ActionView::Helpers::FormTagHelper.class_eval do
21
+
22
+ def spec_label_tag(id, text = nil, options = {})
23
+ count = SpecLabelCounter.next(controller, text)
24
+ label = count == 1 ? text : "#{text} (#{count})"
25
+ options.merge!(:class => 'hidden') unless Rails.env.test?
26
+ html = label_tag(id, label, options)
27
+ html
28
+ end
29
+
30
+ end
31
+
32
+ class SpecLabelCounter
33
+ class << self
34
+
35
+ def next(controller, text)
36
+ counter(controller)[text] ||= 0
37
+ counter(controller)[text] += 1
38
+ end
39
+
40
+ def counter(controller)
41
+ ivar = :"@_spec_label_counter"
42
+ controller.instance_variable_get(ivar) || controller.instance_variable_set(ivar, {})
43
+ end
44
+
45
+ end
46
+ end
@@ -0,0 +1,7 @@
1
+ ActiveRecord::Base.class_eval do
2
+
3
+ def self.these(arg)
4
+ where(id: arg.collect_ids)
5
+ end
6
+
7
+ end