katapult 0.1.2 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.ruby-version +1 -1
- data/README.md +61 -35
- data/bin/katapult +24 -34
- data/features/authenticate.feature +344 -0
- data/features/basics.feature +590 -0
- data/features/binary.feature +33 -1
- data/features/model.feature +9 -13
- data/features/step_definitions/rails_steps.rb +3 -2
- data/features/wui.feature +49 -4
- data/lib/generators/katapult/basics/basics_generator.rb +63 -17
- data/lib/generators/katapult/basics/templates/.gitignore +1 -0
- data/lib/generators/katapult/basics/templates/.ruby-version +1 -1
- data/lib/generators/katapult/basics/templates/Capfile +25 -0
- data/lib/generators/katapult/basics/templates/Gemfile +14 -6
- data/lib/generators/katapult/basics/templates/Guardfile +44 -0
- data/lib/generators/katapult/basics/templates/config/database.sample.yml +3 -2
- data/lib/generators/katapult/basics/templates/config/database.yml +3 -2
- data/lib/generators/katapult/basics/templates/config/deploy/production.rb +8 -0
- data/lib/generators/katapult/basics/templates/config/deploy/staging.rb +7 -0
- data/lib/generators/katapult/basics/templates/config/deploy.rb +37 -0
- data/lib/generators/katapult/basics/templates/config/initializers/ext.rb +3 -0
- data/lib/generators/katapult/basics/templates/features/support/factory_girl.rb +1 -0
- data/lib/generators/katapult/basics/templates/features/support/paths.rb +6 -0
- data/lib/generators/katapult/basics/templates/lib/capistrano/tasks/db.rake +28 -0
- data/lib/generators/katapult/basics/templates/lib/capistrano/tasks/deploy.rake +15 -0
- data/lib/generators/katapult/basics/templates/lib/capistrano/tasks/passenger.rake +8 -0
- data/lib/generators/katapult/basics/templates/{config/initializers → lib/ext/action_view}/form_for_with_development_errors.rb +0 -2
- data/lib/generators/katapult/basics/templates/lib/ext/action_view/spec_label.rb +46 -0
- data/lib/generators/katapult/basics/templates/{config/initializers → lib/ext/active_record}/find_by_anything.rb +0 -0
- data/lib/generators/katapult/basics/templates/lib/ext/active_record/these.rb +7 -0
- data/lib/generators/katapult/basics/templates/lib/ext/array/xss_aware_join.rb +10 -0
- data/lib/generators/katapult/basics/templates/lib/ext/enumerable/natural_sort.rb +15 -0
- data/lib/generators/katapult/basics/templates/lib/ext/hash/infinite.rb +7 -0
- data/lib/generators/katapult/basics/templates/lib/ext/string/html_entities.rb +11 -0
- data/lib/generators/katapult/basics/templates/lib/ext/string/to_sort_atoms.rb +52 -0
- data/lib/generators/katapult/basics/templates/lib/tasks/pending_migrations.rake +24 -0
- data/lib/generators/katapult/basics/templates/spec/factories/factories.rb +9 -0
- data/lib/generators/katapult/basics/templates/spec/support/factory_girl.rb +3 -0
- data/lib/generators/katapult/clearance/clearance_generator.rb +125 -0
- data/lib/generators/katapult/clearance/templates/app/controllers/passwords_controller.rb +16 -0
- data/lib/generators/katapult/clearance/templates/app/views/clearance_mailer/change_password.html.haml +6 -0
- data/lib/generators/katapult/clearance/templates/app/views/clearance_mailer/change_password.text.erb +3 -0
- data/lib/generators/katapult/clearance/templates/app/views/passwords/create.html.haml +5 -0
- data/lib/generators/katapult/clearance/templates/app/views/passwords/edit.html.haml +16 -0
- data/lib/generators/katapult/clearance/templates/app/views/passwords/new.html.haml +14 -0
- data/lib/generators/katapult/clearance/templates/app/views/sessions/new.html.haml +19 -0
- data/lib/generators/katapult/clearance/templates/config/initializers/clearance.rb +15 -0
- data/lib/generators/katapult/clearance/templates/config/locales/clearance.en.yml +59 -0
- data/lib/generators/katapult/clearance/templates/features/authentication.feature +94 -0
- data/lib/generators/katapult/clearance/templates/features/step_definitions/authentication_steps.rb +4 -0
- data/lib/generators/katapult/cucumber_features/templates/feature.feature +11 -7
- data/lib/generators/katapult/haml/haml_generator.rb +5 -0
- data/lib/generators/katapult/haml/templates/_form.html.haml +4 -4
- data/lib/generators/katapult/haml/templates/app/views/layouts/_flashes.html.haml +3 -0
- data/lib/generators/katapult/haml/templates/app/views/layouts/application.html.haml +9 -3
- data/lib/generators/katapult/haml/templates/index.html.haml +1 -1
- data/lib/generators/katapult/haml/templates/show.html.haml +2 -4
- data/lib/generators/katapult/install/templates/lib/katapult/application_model.rb +9 -7
- data/lib/generators/katapult/model/model_generator.rb +1 -1
- data/lib/generators/katapult/w_u_i/templates/controller.rb +1 -1
- data/lib/generators/katapult/w_u_i/w_u_i_generator.rb +4 -2
- data/lib/katapult/application_model.rb +8 -1
- data/lib/katapult/attribute.rb +10 -11
- data/lib/katapult/authentication.rb +25 -0
- data/lib/katapult/binary_util.rb +37 -0
- data/lib/katapult/element.rb +1 -1
- data/lib/katapult/generator.rb +6 -0
- data/lib/katapult/model.rb +13 -1
- data/lib/katapult/parser.rb +7 -0
- data/lib/katapult/version.rb +1 -1
- data/lib/katapult/wui.rb +4 -0
- data/lib/katapult.rb +2 -0
- data/spec/attribute_spec.rb +13 -0
- data/spec/element_spec.rb +5 -0
- data/spec/model_spec.rb +5 -4
- data/spec/util_spec.rb +8 -8
- data/spec/wui_spec.rb +19 -0
- metadata +44 -8
- data/features/katapult.feature +0 -271
- 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
|
-
|
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([
|
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:
|
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
|
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
|
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
|
-
#
|
49
|
-
#
|
50
|
-
#
|
51
|
-
|
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
|
78
|
-
gsub_file 'config/
|
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
|
|
@@ -1 +1 @@
|
|
1
|
-
|
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'
|
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
|
@@ -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,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 @@
|
|
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,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
|
File without changes
|