suspenders 1.50.0 → 1.54.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.ruby-version +1 -1
- data/.travis.yml +6 -4
- data/CONTRIBUTING.md +15 -15
- data/GOALS.md +65 -0
- data/NEWS.md +55 -0
- data/README.md +7 -4
- data/docs/heroku_deploy.md +19 -0
- data/lib/suspenders.rb +10 -0
- data/lib/suspenders/actions.rb +2 -2
- data/lib/suspenders/adapters/heroku.rb +14 -5
- data/lib/suspenders/app_builder.rb +3 -91
- data/lib/suspenders/generators/advisories_generator.rb +15 -0
- data/lib/suspenders/generators/analytics_generator.rb +2 -7
- data/lib/suspenders/generators/app_generator.rb +14 -41
- data/lib/suspenders/generators/base.rb +59 -0
- data/lib/suspenders/generators/ci_generator.rb +20 -14
- data/lib/suspenders/generators/db_optimizations_generator.rb +6 -18
- data/lib/suspenders/generators/factories_generator.rb +3 -8
- data/lib/suspenders/generators/forms_generator.rb +3 -3
- data/lib/suspenders/generators/inline_svg_generator.rb +14 -0
- data/lib/suspenders/generators/jobs_generator.rb +3 -13
- data/lib/suspenders/generators/js_driver_generator.rb +9 -11
- data/lib/suspenders/generators/json_generator.rb +3 -3
- data/lib/suspenders/generators/lint_generator.rb +2 -7
- data/lib/suspenders/generators/preloader_generator.rb +122 -0
- data/lib/suspenders/generators/production/compression_generator.rb +14 -0
- data/lib/suspenders/generators/production/deployment_generator.rb +16 -0
- data/lib/suspenders/generators/production/email_generator.rb +7 -18
- data/lib/suspenders/generators/production/force_tls_generator.rb +2 -5
- data/lib/suspenders/generators/production/manifest_generator.rb +25 -0
- data/lib/suspenders/generators/production/single_redirect.rb +15 -0
- data/lib/suspenders/generators/production/timeout_generator.rb +3 -2
- data/lib/suspenders/generators/profiler_generator.rb +35 -0
- data/lib/suspenders/generators/runner_generator.rb +48 -0
- data/lib/suspenders/generators/staging/pull_requests_generator.rb +4 -26
- data/lib/suspenders/generators/static_generator.rb +7 -3
- data/lib/suspenders/generators/stylelint_generator.rb +70 -0
- data/lib/suspenders/generators/stylesheet_base_generator.rb +8 -13
- data/lib/suspenders/generators/testing_generator.rb +6 -22
- data/lib/suspenders/generators/views_generator.rb +2 -7
- data/lib/suspenders/version.rb +2 -2
- data/spec/adapters/heroku_spec.rb +28 -2
- data/spec/expand_json_spec.rb +89 -0
- data/spec/features/advisories_spec.rb +24 -0
- data/spec/features/api_spec.rb +1 -1
- data/spec/features/ci_spec.rb +31 -0
- data/spec/features/db_optimizations_spec.rb +19 -0
- data/spec/features/heroku_spec.rb +7 -14
- data/spec/features/inline_svg_spec.rb +10 -0
- data/spec/features/json_spec.rb +1 -1
- data/spec/features/new_project_spec.rb +17 -35
- data/spec/features/preloader_spec.rb +25 -0
- data/spec/features/production/compression_spec.rb +23 -0
- data/spec/features/production/deployment_spec.rb +22 -0
- data/spec/features/production/email_spec.rb +1 -1
- data/spec/features/production/manifest_spec.rb +37 -0
- data/spec/features/production/single_redirect_spec.rb +25 -0
- data/spec/features/profiler_spec.rb +20 -0
- data/spec/features/runner_spec.rb +30 -0
- data/spec/features/staging/pull_requests_spec.rb +1 -1
- data/spec/features/static_spec.rb +17 -0
- data/spec/features/stylelint_spec.rb +60 -0
- data/spec/spec_helper.rb +1 -0
- data/spec/support/be_executable_matcher.rb +7 -0
- data/spec/support/contain_json_matcher.rb +16 -10
- data/spec/support/generators.rb +5 -0
- data/spec/support/project_files.rb +25 -0
- data/spec/support/rails_template.rb +1 -0
- data/spec/support/suspenders.rb +18 -15
- data/suspenders.gemspec +1 -1
- data/templates/Gemfile.erb +5 -11
- data/templates/_javascript.html.erb +1 -1
- data/templates/application.scss +0 -1
- data/templates/bin_auto_migrate +5 -0
- data/templates/bin_deploy +0 -2
- data/templates/bin_setup +2 -2
- data/templates/bin_setup_review_app.erb +0 -1
- data/templates/capybara_silence_puma.rb +1 -0
- data/templates/chromedriver.rb +14 -4
- data/templates/descriptions/advisories.md +5 -0
- data/templates/descriptions/analytics.md +4 -0
- data/templates/descriptions/ci.md +4 -0
- data/templates/descriptions/compression.md +4 -0
- data/templates/descriptions/db_optimizations.md +2 -0
- data/templates/descriptions/deployment.md +5 -0
- data/templates/descriptions/email.md +9 -0
- data/templates/descriptions/factories.md +12 -0
- data/templates/descriptions/force_tls.md +1 -0
- data/templates/descriptions/forms.md +1 -0
- data/templates/descriptions/inline_svg.md +2 -0
- data/templates/descriptions/jobs.md +3 -0
- data/templates/descriptions/js_driver.md +4 -0
- data/templates/descriptions/json.md +1 -0
- data/templates/descriptions/lint.md +3 -0
- data/templates/descriptions/manifest.md +2 -0
- data/templates/descriptions/preloader.md +3 -0
- data/templates/descriptions/profiler.md +7 -0
- data/templates/descriptions/pull_requests.md +4 -0
- data/templates/descriptions/runner.md +10 -0
- data/templates/descriptions/single_redirect.md +1 -0
- data/templates/descriptions/static.md +5 -0
- data/templates/descriptions/stylelint.md +3 -0
- data/templates/descriptions/stylesheet_base.md +4 -0
- data/templates/descriptions/testing.md +9 -0
- data/templates/descriptions/timeout.md +4 -0
- data/templates/descriptions/views.md +8 -0
- data/templates/hound.yml +3 -1
- data/templates/inline_svg.rb +3 -0
- data/templates/partials/ci_simplecov.rb +16 -0
- data/templates/partials/db_optimizations_configuration.rb +7 -0
- data/templates/partials/deployment_readme.md +8 -0
- data/templates/partials/email_smtp.rb +3 -0
- data/templates/partials/profiler_readme.md +8 -0
- data/templates/partials/pull_requests_config.rb +5 -0
- data/templates/partials/runner_readme.md +31 -0
- data/templates/partials/runner_setup.rb +3 -0
- data/templates/rack_mini_profiler.rb +2 -0
- data/templates/rails_helper.rb +7 -4
- data/templates/{dotfiles/.env → sample_env} +0 -2
- data/templates/spec_helper.rb +4 -7
- data/templates/spring.rb +6 -0
- data/templates/stylelintrc.json +3 -0
- data/templates/suspenders_gitignore +1 -1
- metadata +119 -17
- data/templates/app.json.erb +0 -27
- data/templates/browserslist +0 -3
- data/templates/dotfiles/.ctags +0 -2
- data/templates/puma.rb +0 -28
@@ -0,0 +1,14 @@
|
|
1
|
+
require_relative "../base"
|
2
|
+
|
3
|
+
module Suspenders
|
4
|
+
module Production
|
5
|
+
class CompressionGenerator < Generators::Base
|
6
|
+
def add_rack_deflater
|
7
|
+
configure_environment(
|
8
|
+
:production,
|
9
|
+
%{config.middleware.use Rack::Deflater},
|
10
|
+
)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require_relative "../base"
|
2
|
+
|
3
|
+
module Suspenders
|
4
|
+
module Production
|
5
|
+
class DeploymentGenerator < Generators::Base
|
6
|
+
def copy_script
|
7
|
+
copy_file "bin_deploy", "bin/deploy"
|
8
|
+
chmod "bin/deploy", 0o755
|
9
|
+
end
|
10
|
+
|
11
|
+
def inform_user
|
12
|
+
append_template_to_file "README.md", "partials/deployment_readme.md"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -1,16 +1,8 @@
|
|
1
|
-
|
2
|
-
require_relative "../../actions"
|
1
|
+
require_relative "../base"
|
3
2
|
|
4
3
|
module Suspenders
|
5
4
|
module Production
|
6
|
-
class EmailGenerator <
|
7
|
-
include Suspenders::Actions
|
8
|
-
|
9
|
-
source_root File.expand_path(
|
10
|
-
File.join("..", "..", "..", "..", "templates"),
|
11
|
-
File.dirname(__FILE__),
|
12
|
-
)
|
13
|
-
|
5
|
+
class EmailGenerator < Generators::Base
|
14
6
|
def smtp_configuration
|
15
7
|
copy_file "smtp.rb", "config/smtp.rb"
|
16
8
|
|
@@ -19,14 +11,11 @@ module Suspenders
|
|
19
11
|
end
|
20
12
|
|
21
13
|
def use_smtp
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
inject_into_file "config/environments/production.rb", config,
|
29
|
-
after: "config.action_mailer.perform_caching = false"
|
14
|
+
inject_template_into_file(
|
15
|
+
"config/environments/production.rb",
|
16
|
+
"partials/email_smtp.rb",
|
17
|
+
after: "config.action_mailer.perform_caching = false",
|
18
|
+
)
|
30
19
|
end
|
31
20
|
|
32
21
|
def env_vars
|
@@ -1,11 +1,8 @@
|
|
1
|
-
|
2
|
-
require_relative "../../actions"
|
1
|
+
require_relative "../base"
|
3
2
|
|
4
3
|
module Suspenders
|
5
4
|
module Production
|
6
|
-
class ForceTlsGenerator <
|
7
|
-
include Suspenders::Actions
|
8
|
-
|
5
|
+
class ForceTlsGenerator < Generators::Base
|
9
6
|
def config_enforce_ssl
|
10
7
|
configure_environment "production", "config.force_ssl = true"
|
11
8
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require_relative "../base"
|
2
|
+
|
3
|
+
module Suspenders
|
4
|
+
module Production
|
5
|
+
class ManifestGenerator < Generators::Base
|
6
|
+
def render_manifest
|
7
|
+
expand_json(
|
8
|
+
"app.json",
|
9
|
+
name: app_name.dasherize,
|
10
|
+
scripts: {},
|
11
|
+
env: {
|
12
|
+
APPLICATION_HOST: { required: true },
|
13
|
+
AUTO_MIGRATE_DB: { value: true },
|
14
|
+
EMAIL_RECIPIENTS: { required: true },
|
15
|
+
HEROKU_APP_NAME: { required: true },
|
16
|
+
HEROKU_PARENT_APP_NAME: { required: true },
|
17
|
+
RACK_ENV: { required: true },
|
18
|
+
SECRET_KEY_BASE: { generator: "secret" },
|
19
|
+
},
|
20
|
+
addons: ["heroku-postgresql"],
|
21
|
+
)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require_relative "../base"
|
2
|
+
|
3
|
+
module Suspenders
|
4
|
+
module Production
|
5
|
+
class SingleRedirect < Generators::Base
|
6
|
+
def add_rack_canonical_host
|
7
|
+
inject_into_file(
|
8
|
+
"config/environments/production.rb",
|
9
|
+
%{\n config.middleware.use Rack::CanonicalHost, ENV.fetch("APPLICATION_HOST")},
|
10
|
+
before: "\nend",
|
11
|
+
)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -1,10 +1,11 @@
|
|
1
|
-
|
1
|
+
require_relative "../base"
|
2
2
|
|
3
3
|
module Suspenders
|
4
4
|
module Production
|
5
|
-
class TimeoutGenerator <
|
5
|
+
class TimeoutGenerator < Generators::Base
|
6
6
|
def add_gem
|
7
7
|
gem "rack-timeout", group: :production
|
8
|
+
Bundler.with_unbundled_env { run "bundle install" }
|
8
9
|
end
|
9
10
|
|
10
11
|
def configure_rack_timeout
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require_relative "base"
|
2
|
+
|
3
|
+
module Suspenders
|
4
|
+
class ProfilerGenerator < Generators::Base
|
5
|
+
def augment_default_env
|
6
|
+
append_to_file ".env", "RACK_MINI_PROFILER=0\n"
|
7
|
+
rescue Errno::ENOENT
|
8
|
+
create_file ".env", "RACK_MINI_PROFILER=0\n"
|
9
|
+
rescue Thor::Error => e
|
10
|
+
if e.message.match?(/does not appear to exist/)
|
11
|
+
create_file ".env", "RACK_MINI_PROFILER=0\n"
|
12
|
+
else
|
13
|
+
raise
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def add_gem
|
18
|
+
gem "rack-mini-profiler", require: false
|
19
|
+
Bundler.with_unbundled_env { run "bundle install" }
|
20
|
+
end
|
21
|
+
|
22
|
+
def configure_rack_mini_profiler
|
23
|
+
copy_file(
|
24
|
+
"rack_mini_profiler.rb",
|
25
|
+
"config/initializers/rack_mini_profiler.rb",
|
26
|
+
force: false,
|
27
|
+
skip: true,
|
28
|
+
)
|
29
|
+
end
|
30
|
+
|
31
|
+
def update_readme
|
32
|
+
append_template_to_file "README.md", "partials/profiler_readme.md"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require_relative "base"
|
2
|
+
|
3
|
+
module Suspenders
|
4
|
+
class RunnerGenerator < Generators::Base
|
5
|
+
def procfile
|
6
|
+
copy_file "Procfile", "Procfile"
|
7
|
+
end
|
8
|
+
|
9
|
+
def sample_env
|
10
|
+
copy_file "sample_env", ".sample.env"
|
11
|
+
end
|
12
|
+
|
13
|
+
def copy_sample_env
|
14
|
+
if bin_setup_is_ruby?
|
15
|
+
inject_template_into_file(
|
16
|
+
"bin/setup",
|
17
|
+
"partials/runner_setup.rb",
|
18
|
+
before: %{ puts "\\n== Preparing database =="},
|
19
|
+
)
|
20
|
+
elsif bin_setup_mentions_ci?
|
21
|
+
inject_into_file(
|
22
|
+
"bin/setup",
|
23
|
+
%{ cp -i .sample.env .env\n},
|
24
|
+
after: %{if [ -z "$CI" ]; then\n},
|
25
|
+
)
|
26
|
+
else
|
27
|
+
append_to_file(
|
28
|
+
"bin/setup",
|
29
|
+
%{\nif [ -z "$CI" ]; then\n cp -i .sample.env .env\nfi},
|
30
|
+
)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def update_readme
|
35
|
+
append_template_to_file "README.md", "partials/runner_readme.md"
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def bin_setup_is_ruby?
|
41
|
+
File.read("bin/setup", 20).match?(%r{#!/usr/bin/env ruby})
|
42
|
+
end
|
43
|
+
|
44
|
+
def bin_setup_mentions_ci?
|
45
|
+
File.read("bin/setup").match?(/if \[ -z "\$CI" \]/)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -1,28 +1,12 @@
|
|
1
|
-
|
2
|
-
require_relative "../../actions"
|
1
|
+
require_relative "../base"
|
3
2
|
|
4
3
|
module Suspenders
|
5
4
|
module Staging
|
6
|
-
class PullRequestsGenerator <
|
7
|
-
include Suspenders::Actions
|
8
|
-
|
9
|
-
source_root File.expand_path(
|
10
|
-
File.join("..", "..", "..", "..", "templates"),
|
11
|
-
File.dirname(__FILE__),
|
12
|
-
)
|
13
|
-
|
5
|
+
class PullRequestsGenerator < Generators::Base
|
14
6
|
def configure_heroku_staging_pr_pipeline_host
|
15
|
-
|
16
|
-
|
17
|
-
if ENV.fetch("HEROKU_APP_NAME", "").include?("staging-pr-")
|
18
|
-
ENV["APPLICATION_HOST"] = ENV["HEROKU_APP_NAME"] + ".herokuapp.com"
|
19
|
-
ENV["ASSET_HOST"] = ENV["HEROKU_APP_NAME"] + ".herokuapp.com"
|
20
|
-
end
|
21
|
-
RUBY
|
22
|
-
|
23
|
-
inject_into_file(
|
7
|
+
inject_template_into_file(
|
24
8
|
"config/environments/production.rb",
|
25
|
-
|
9
|
+
"partials/pull_requests_config.rb",
|
26
10
|
after: "Rails.application.configure do\n",
|
27
11
|
)
|
28
12
|
end
|
@@ -36,12 +20,6 @@ module Suspenders
|
|
36
20
|
|
37
21
|
run "chmod a+x bin/setup_review_app"
|
38
22
|
end
|
39
|
-
|
40
|
-
private
|
41
|
-
|
42
|
-
def app_name
|
43
|
-
Rails.application.class.parent_name.demodulize.underscore.dasherize
|
44
|
-
end
|
45
23
|
end
|
46
24
|
end
|
47
25
|
end
|
@@ -1,10 +1,14 @@
|
|
1
|
-
|
1
|
+
require_relative "base"
|
2
2
|
|
3
3
|
module Suspenders
|
4
|
-
class StaticGenerator <
|
4
|
+
class StaticGenerator < Generators::Base
|
5
5
|
def add_high_voltage
|
6
6
|
gem "high_voltage"
|
7
|
-
Bundler.
|
7
|
+
Bundler.with_unbundled_env { run "bundle install" }
|
8
|
+
end
|
9
|
+
|
10
|
+
def make_placeholder_directory
|
11
|
+
empty_directory_with_keep_file "app/views/pages"
|
8
12
|
end
|
9
13
|
end
|
10
14
|
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require_relative "base"
|
2
|
+
|
3
|
+
module Suspenders
|
4
|
+
class StylelintGenerator < Generators::Base
|
5
|
+
def setup_hound
|
6
|
+
action InvokeGenerator.new(self, "suspenders:lint")
|
7
|
+
action ToggleComments.new(self, ".hound.yml", /stylelintrc/)
|
8
|
+
end
|
9
|
+
|
10
|
+
def install_stylelint
|
11
|
+
dependencies = ["stylelint", "@thoughtbot/stylelint-config"]
|
12
|
+
action YarnInstall.new(self, dependencies, "--dev")
|
13
|
+
end
|
14
|
+
|
15
|
+
def copy_stylelint_config
|
16
|
+
copy_file "stylelintrc.json", ".stylelintrc.json"
|
17
|
+
end
|
18
|
+
|
19
|
+
class InvokeGenerator
|
20
|
+
def initialize(base, generator)
|
21
|
+
@base = base
|
22
|
+
@generator = generator
|
23
|
+
end
|
24
|
+
|
25
|
+
def invoke!
|
26
|
+
@base.invoke @generator
|
27
|
+
end
|
28
|
+
|
29
|
+
def revoke!; end
|
30
|
+
end
|
31
|
+
|
32
|
+
class ToggleComments
|
33
|
+
def initialize(base, filename, pattern)
|
34
|
+
@base = base
|
35
|
+
@filename = filename
|
36
|
+
@pattern = pattern
|
37
|
+
end
|
38
|
+
|
39
|
+
def invoke!
|
40
|
+
@base.uncomment_lines(@filename, @pattern)
|
41
|
+
end
|
42
|
+
|
43
|
+
def revoke!
|
44
|
+
@base.behavior = :invoke
|
45
|
+
@base.comment_lines(@filename, @pattern)
|
46
|
+
ensure
|
47
|
+
@base.behavior = :revoke
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
class YarnInstall
|
52
|
+
def initialize(base, dependencies, flags)
|
53
|
+
@base = base
|
54
|
+
@dependencies = dependencies.join(" ")
|
55
|
+
@flags = flags
|
56
|
+
end
|
57
|
+
|
58
|
+
def invoke!
|
59
|
+
@base.run "bin/yarn add #{@dependencies} #{@flags}"
|
60
|
+
end
|
61
|
+
|
62
|
+
def revoke!
|
63
|
+
@base.behavior = :invoke
|
64
|
+
@base.run "bin/yarn remove #{@dependencies}"
|
65
|
+
ensure
|
66
|
+
@base.behavior = :revoke
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -1,15 +1,14 @@
|
|
1
|
-
|
1
|
+
require_relative "base"
|
2
2
|
|
3
3
|
module Suspenders
|
4
|
-
class StylesheetBaseGenerator <
|
5
|
-
source_root File.expand_path(
|
6
|
-
File.join("..", "..", "..", "templates"),
|
7
|
-
File.dirname(__FILE__))
|
8
|
-
|
4
|
+
class StylesheetBaseGenerator < Generators::Base
|
9
5
|
def add_stylesheet_gems
|
10
|
-
gem "bourbon", "
|
11
|
-
|
12
|
-
|
6
|
+
gem "bourbon", ">= 6.0.0"
|
7
|
+
Bundler.with_unbundled_env { run "bundle install" }
|
8
|
+
end
|
9
|
+
|
10
|
+
def remove_prior_config
|
11
|
+
remove_file "app/assets/stylesheets/application.css"
|
13
12
|
end
|
14
13
|
|
15
14
|
def add_css_config
|
@@ -20,10 +19,6 @@ module Suspenders
|
|
20
19
|
)
|
21
20
|
end
|
22
21
|
|
23
|
-
def remove_prior_config
|
24
|
-
remove_file "app/assets/stylesheets/application.css"
|
25
|
-
end
|
26
|
-
|
27
22
|
def install_bitters
|
28
23
|
run "bitters install --path app/assets/stylesheets"
|
29
24
|
end
|
@@ -1,18 +1,13 @@
|
|
1
|
-
|
1
|
+
require_relative "base"
|
2
2
|
|
3
3
|
module Suspenders
|
4
|
-
class TestingGenerator <
|
5
|
-
source_root File.expand_path(
|
6
|
-
File.join("..", "..", "..", "templates"),
|
7
|
-
File.dirname(__FILE__),
|
8
|
-
)
|
9
|
-
|
4
|
+
class TestingGenerator < Generators::Base
|
10
5
|
def add_testing_gems
|
11
6
|
gem "spring-commands-rspec", group: :development
|
12
7
|
gem "rspec-rails", "~> 3.6", group: %i(development test)
|
13
8
|
gem "shoulda-matchers", group: :test
|
14
9
|
|
15
|
-
Bundler.
|
10
|
+
Bundler.with_unbundled_env { run "bundle install" }
|
16
11
|
end
|
17
12
|
|
18
13
|
def generate_rspec
|
@@ -33,9 +28,9 @@ module Suspenders
|
|
33
28
|
)
|
34
29
|
end
|
35
30
|
|
36
|
-
def
|
37
|
-
empty_directory_with_keep_file "spec/
|
38
|
-
empty_directory_with_keep_file "spec/support/
|
31
|
+
def configure_system_tests
|
32
|
+
empty_directory_with_keep_file "spec/system"
|
33
|
+
empty_directory_with_keep_file "spec/support/system"
|
39
34
|
end
|
40
35
|
|
41
36
|
def configure_i18n_for_test_environment
|
@@ -45,16 +40,5 @@ module Suspenders
|
|
45
40
|
def configure_action_mailer_in_specs
|
46
41
|
copy_file "action_mailer.rb", "spec/support/action_mailer.rb"
|
47
42
|
end
|
48
|
-
|
49
|
-
private
|
50
|
-
|
51
|
-
def empty_directory_with_keep_file(destination)
|
52
|
-
empty_directory(destination, {})
|
53
|
-
keep_file(destination)
|
54
|
-
end
|
55
|
-
|
56
|
-
def keep_file(destination)
|
57
|
-
create_file(File.join(destination, ".keep"))
|
58
|
-
end
|
59
43
|
end
|
60
44
|
end
|