diff --git a/railties/lib/rails/generators/actions.rb b/railties/lib/rails/generators/actions.rb index 406a5b8fc7..c3a43d5398 100644 --- a/railties/lib/rails/generators/actions.rb +++ b/railties/lib/rails/generators/actions.rb @@ -40,8 +40,7 @@ module Rails in_root do str = "gem #{parts.join(", ")}" str = indentation + str - str = "\n" + str - append_file "Gemfile", str, verbose: false + append_file_with_newline "Gemfile", str, verbose: false end end @@ -58,9 +57,9 @@ module Rails log :gemfile, "group #{str}" in_root do - append_file "Gemfile", "\ngroup #{str} do", force: true + append_file_with_newline "Gemfile", "group #{str} do", force: true with_indentation(&block) - append_file "Gemfile", "\nend\n", force: true + append_file_with_newline "Gemfile", "end", force: true end end @@ -71,9 +70,9 @@ module Rails log :github, "github #{str}" in_root do - append_file "Gemfile", "\n#{indentation}github #{str} do", force: true + append_file_with_newline "Gemfile", "#{indentation}github #{str} do", force: true with_indentation(&block) - append_file "Gemfile", "\n#{indentation}end", force: true + append_file_with_newline "Gemfile", "#{indentation}end", force: true end end @@ -91,9 +90,9 @@ module Rails in_root do if block - append_file "Gemfile", "\nsource #{quote(source)} do", force: true + append_file_with_newline "Gemfile", "source #{quote(source)} do", force: true with_indentation(&block) - append_file "Gemfile", "\nend\n", force: true + append_file_with_newline "Gemfile", "end", force: true else prepend_file "Gemfile", "source #{quote(source)}\n", verbose: false end @@ -344,6 +343,13 @@ module Rails ensure @indentation -= 1 end + + # Append string to a file with a newline if necessary + def append_file_with_newline(path, str, options = {}) + gsub_file path, /\n?\z/, options do |match| + match.end_with?("\n") ? "" : "\n#{str}\n" + end + end end end end diff --git a/railties/test/generators/actions_test.rb b/railties/test/generators/actions_test.rb index 150836d4ce..607d35e023 100644 --- a/railties/test/generators/actions_test.rb +++ b/railties/test/generators/actions_test.rb @@ -43,7 +43,7 @@ class ActionsTest < Rails::Generators::TestCase def test_add_source_adds_source_to_gemfile run_generator action :add_source, "http://gems.github.com" - assert_file "Gemfile", /source 'http:\/\/gems\.github\.com'/ + assert_file "Gemfile", /source 'http:\/\/gems\.github\.com'\n/ end def test_add_source_with_block_adds_source_to_gemfile_with_gem @@ -51,7 +51,7 @@ class ActionsTest < Rails::Generators::TestCase action :add_source, "http://gems.github.com" do gem "rspec-rails" end - assert_file "Gemfile", /source 'http:\/\/gems\.github\.com' do\n gem 'rspec-rails'\nend/ + assert_file "Gemfile", /source 'http:\/\/gems\.github\.com' do\n gem 'rspec-rails'\nend\n\z/ end def test_add_source_with_block_adds_source_to_gemfile_after_gem @@ -60,13 +60,13 @@ class ActionsTest < Rails::Generators::TestCase action :add_source, "http://gems.github.com" do gem "rspec-rails" end - assert_file "Gemfile", /gem 'will-paginate'\nsource 'http:\/\/gems\.github\.com' do\n gem 'rspec-rails'\nend/ + assert_file "Gemfile", /gem 'will-paginate'\nsource 'http:\/\/gems\.github\.com' do\n gem 'rspec-rails'\nend\n\z/ end def test_gem_should_put_gem_dependency_in_gemfile run_generator action :gem, "will-paginate" - assert_file "Gemfile", /gem 'will\-paginate'/ + assert_file "Gemfile", /gem 'will\-paginate'\n\z/ end def test_gem_with_version_should_include_version_in_gemfile @@ -141,7 +141,7 @@ class ActionsTest < Rails::Generators::TestCase gem "fakeweb" end - assert_file "Gemfile", /\ngroup :development, :test do\n gem 'rspec-rails'\nend\n\ngroup :test do\n gem 'fakeweb'\nend/ + assert_file "Gemfile", /^group :development, :test do\n gem 'rspec-rails'\nend\ngroup :test do\n gem 'fakeweb'\nend\n\z/ end def test_github_should_create_an_indented_block @@ -153,7 +153,7 @@ class ActionsTest < Rails::Generators::TestCase gem "baz" end - assert_file "Gemfile", /\ngithub 'user\/repo' do\n gem 'foo'\n gem 'bar'\n gem 'baz'\nend/ + assert_file "Gemfile", /^github 'user\/repo' do\n gem 'foo'\n gem 'bar'\n gem 'baz'\nend\n\z/ end def test_github_should_create_an_indented_block_with_options @@ -165,7 +165,7 @@ class ActionsTest < Rails::Generators::TestCase gem "baz" end - assert_file "Gemfile", /\ngithub 'user\/repo', a: 'correct', other: true do\n gem 'foo'\n gem 'bar'\n gem 'baz'\nend/ + assert_file "Gemfile", /^github 'user\/repo', a: 'correct', other: true do\n gem 'foo'\n gem 'bar'\n gem 'baz'\nend\n\z/ end def test_github_should_create_an_indented_block_within_a_group @@ -179,7 +179,48 @@ class ActionsTest < Rails::Generators::TestCase end end - assert_file "Gemfile", /\ngroup :magic do\n github 'user\/repo', a: 'correct', other: true do\n gem 'foo'\n gem 'bar'\n gem 'baz'\n end\nend\n/ + assert_file "Gemfile", /^group :magic do\n github 'user\/repo', a: 'correct', other: true do\n gem 'foo'\n gem 'bar'\n gem 'baz'\n end\nend\n\z/ + end + + def test_gem_with_gemfile_without_newline_at_the_end + run_generator + File.open("Gemfile", "a") { |f| f.write("gem 'rspec-rails'") } + + action :gem, "will-paginate" + assert_file "Gemfile", /gem 'rspec-rails'\ngem 'will-paginate'\n\z/ + end + + def test_gem_group_with_gemfile_without_newline_at_the_end + run_generator + File.open("Gemfile", "a") { |f| f.write("gem 'rspec-rails'") } + + action :gem_group, :test do + gem "fakeweb" + end + + assert_file "Gemfile", /gem 'rspec-rails'\ngroup :test do\n gem 'fakeweb'\nend\n\z/ + end + + def test_add_source_with_gemfile_without_newline_at_the_end + run_generator + File.open("Gemfile", "a") { |f| f.write("gem 'rspec-rails'") } + + action :add_source, "http://gems.github.com" do + gem "fakeweb" + end + + assert_file "Gemfile", /gem 'rspec-rails'\nsource 'http:\/\/gems\.github\.com' do\n gem 'fakeweb'\nend\n\z/ + end + + def test_github_with_gemfile_without_newline_at_the_end + run_generator + File.open("Gemfile", "a") { |f| f.write("gem 'rspec-rails'") } + + action :github, "user/repo" do + gem "fakeweb" + end + + assert_file "Gemfile", /gem 'rspec-rails'\ngithub 'user\/repo' do\n gem 'fakeweb'\nend\n\z/ end def test_environment_should_include_data_in_environment_initializer_block