├── .gitignore ├── .rspec ├── .travis.yml ├── Gemfile ├── LICENSE.txt ├── README.md ├── Rakefile ├── lib ├── rails4_upgrade.rb └── rails4_upgrade │ ├── formatters.rb │ ├── formatters │ └── incompatible_gems_formatter.rb │ ├── gem.rb │ ├── gem_dependency.rb │ ├── gemfile.rb │ ├── incompatibility.rb │ ├── incompatible_gems.rb │ ├── lockfile.rb │ ├── railtie.rb │ ├── tasks │ └── upgrade.rake │ └── version.rb ├── rails4_upgrade.gemspec └── spec ├── fixtures └── gemfiles │ ├── Gemfile_with_devise.lock │ ├── Gemfile_with_ransack.lock │ └── Gemfile_with_recursive_dependency.lock ├── gemfile_spec.rb ├── incompatible_gems_spec.rb ├── lockfile_spec.rb └── spec_helper.rb /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | *.rbc 3 | .bundle 4 | .config 5 | .yardoc 6 | Gemfile.lock 7 | InstalledFiles 8 | _yardoc 9 | coverage 10 | doc/ 11 | lib/bundler/man 12 | pkg 13 | rdoc 14 | spec/reports 15 | test/tmp 16 | test/version_tmp 17 | tmp 18 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --color 2 | --format progress 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: ruby 2 | before_install: 3 | - gem install bundler -v 1.2.2 4 | rvm: 5 | - 1.9.3 6 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # Specify your gem's dependencies in rails4_upgrade.gemspec 4 | gemspec 5 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 Andy Lindeman 2 | 3 | MIT License 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # rails4\_upgrade [![Build Status](https://secure.travis-ci.org/alindeman/rails4_upgrade.png?branch=master)](http://travis-ci.org/alindeman/rails4_upgrade) 2 | 3 | Helps you more easily upgrade to Rails 4. A work in progress, I'm simply 4 | shipping something of a minimum viable product to attract others to 5 | contribute. 6 | 7 | Inspired by [rails_upgrade](https://github.com/rails/rails_upgrade) which 8 | helped upgrade applications from Rails 2 to Rails 3. 9 | 10 | Written in part to complement the book [Upgrading to Rails 11 | 4](http://upgradingtorails4.com). 12 | 13 | ## Installation 14 | 15 | Upgrade to Ruby 1.9.3 if your application does not already use it. Rails 4 16 | requires Ruby 1.9.3, and `rails4_upgrade` uses 1.9-only syntax and semantics. 17 | 18 | Add to `Gemfile`: 19 | 20 | ```ruby 21 | gem 'rails4_upgrade', github: 'alindeman/rails4_upgrade' 22 | ``` 23 | 24 | ## Usage 25 | 26 | Run `rake rails4:check`: 27 | 28 | ``` 29 | $ rake rails4:check 30 | 31 | ** GEM COMPATIBILITY CHECK ** 32 | +--------------------+----------------------+ 33 | | Dependency Path | Rails Requirement | 34 | +--------------------+----------------------+ 35 | | draper 0.18.0 | actionpack ~> 3.2 | 36 | | draper 0.18.0 | activesupport ~> 3.2 | 37 | | simple_form 2.0.4 | actionpack ~> 3.0 | 38 | | simple_form 2.0.4 | activemodel ~> 3.0 | 39 | +--------------------+----------------------+ 40 | ``` 41 | 42 | ## Contributing 43 | 44 | I'm open to accepting pull requests that improve the functionality of the gem. 45 | 46 | If there's an upgrade procedure that can be automated or semi-automated, let's 47 | discuss it. Open an 48 | [issue](https://github.com/alindeman/rails4_upgrade/issues). 49 | 50 | Ideas: 51 | 52 | * Recommending versions of gems that may be compatible with Rails 4 53 | * Removing deprecated configuration options 54 | * Adding newly required or recommended configuration options 55 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require "bundler/gem_tasks" 2 | 3 | require 'rspec/core/rake_task' 4 | RSpec::Core::RakeTask.new(:spec) 5 | task :default => :spec 6 | -------------------------------------------------------------------------------- /lib/rails4_upgrade.rb: -------------------------------------------------------------------------------- 1 | require "rails4_upgrade/version" 2 | require "rails4_upgrade/gemfile" 3 | require "rails4_upgrade/incompatible_gems" 4 | require "rails4_upgrade/formatters" 5 | require "rails4_upgrade/railtie" if defined?(::Rails) 6 | 7 | module Rails4Upgrade 8 | end 9 | -------------------------------------------------------------------------------- /lib/rails4_upgrade/formatters.rb: -------------------------------------------------------------------------------- 1 | require "rails4_upgrade/formatters/incompatible_gems_formatter" 2 | -------------------------------------------------------------------------------- /lib/rails4_upgrade/formatters/incompatible_gems_formatter.rb: -------------------------------------------------------------------------------- 1 | require "terminal-table" 2 | 3 | module Rails4Upgrade 4 | module Formatters 5 | class IncompatibleGemsFormatter 6 | def initialize(incompatible_gems) 7 | @incompatible_gems = incompatible_gems 8 | end 9 | 10 | def output(stream = STDOUT) 11 | incompatibilities = @incompatible_gems.incompatibilities 12 | if incompatibilities.empty? 13 | stream.puts "No gem incompatibilities found" 14 | else 15 | rows = [] 16 | incompatibilities.each do |incompatibility| 17 | rows << [ 18 | human_readable_dependency_path(incompatibility.path), 19 | human_readable_dependency(incompatibility.dependency) 20 | ] 21 | end 22 | 23 | stream.puts Terminal::Table.new( 24 | headings: ["Dependency Path", "Rails Requirement"], 25 | rows: rows 26 | ) 27 | end 28 | end 29 | 30 | private 31 | 32 | def human_readable_dependency_path(path) 33 | path.map { |dependency| "#{dependency.name} #{dependency.version}" }.join(" -> ") 34 | end 35 | 36 | def human_readable_dependency(dependency) 37 | "#{dependency.name} #{dependency.requirement}" 38 | end 39 | end 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /lib/rails4_upgrade/gem.rb: -------------------------------------------------------------------------------- 1 | require "set" 2 | require "rails4_upgrade/incompatibility" 3 | 4 | module Rails4Upgrade 5 | class Gem < Struct.new(:name, :version, :dependencies) 6 | RAILS_GEMS = Set.new( 7 | %w(actionmailer actionpack activemodel activerecord activesupport railties rails coffee-rails sass-rails) 8 | ).freeze 9 | 10 | def initialize(name, version, dependencies) 11 | version = version.is_a?(::Gem::Version) ? version : ::Gem::Version.new(version) 12 | super 13 | end 14 | 15 | def rails? 16 | RAILS_GEMS.include?(name) 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /lib/rails4_upgrade/gem_dependency.rb: -------------------------------------------------------------------------------- 1 | module Rails4Upgrade 2 | class GemDependency < Struct.new(:name, :requirement) 3 | RAILS_GEMS = Set.new( 4 | %w(actionmailer actionpack activemodel activerecord activesupport railties rails) 5 | ).freeze 6 | 7 | def initialize(name, requirement) 8 | requirement = requirement.is_a?(::Gem::Requirement) ? requirement : ::Gem::Requirement.new(requirement) 9 | super 10 | end 11 | 12 | def rails? 13 | RAILS_GEMS.include?(name) 14 | end 15 | 16 | def satisfied_by_rails4? 17 | requirement.satisfied_by?(::Gem::Version.new("4.0.0")) 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /lib/rails4_upgrade/gemfile.rb: -------------------------------------------------------------------------------- 1 | require "set" 2 | require "rails4_upgrade/gem_dependency" 3 | require "rails4_upgrade/gem" 4 | require "rails4_upgrade/lockfile" 5 | 6 | module Rails4Upgrade 7 | class Gemfile 8 | def initialize(lockfile_io) 9 | @lockfile = Lockfile.new(lockfile_io.read) 10 | 11 | @gems = Hash[@lockfile.specs.map { |spec| 12 | [ 13 | spec.name, 14 | Gem.new( 15 | spec.name, 16 | spec.version, 17 | spec.dependencies.map { |dependency| GemDependency.new(dependency.name, dependency.requirement) } 18 | ) 19 | ] 20 | }] 21 | end 22 | 23 | def dependencies 24 | @dependencies ||= @lockfile.dependencies.map { |dependency| 25 | self[dependency.name] 26 | }.compact 27 | end 28 | 29 | def [](gem_name) 30 | @gems[gem_name] 31 | end 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /lib/rails4_upgrade/incompatibility.rb: -------------------------------------------------------------------------------- 1 | module Rails4Upgrade 2 | class Incompatibility 3 | attr_reader :dependency, :dependency_chain 4 | 5 | def initialize(dependency, dependency_chain) 6 | @dependency = dependency 7 | @dependency_chain = dependency_chain 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /lib/rails4_upgrade/incompatible_gems.rb: -------------------------------------------------------------------------------- 1 | module Rails4Upgrade 2 | GemIncompatibility = Struct.new(:dependency, :path) 3 | 4 | class IncompatibleGems 5 | def initialize(gemfile) 6 | @gemfile = gemfile 7 | end 8 | 9 | def incompatibilities 10 | @gemfile.dependencies.reject(&:rails?).inject([]) { |incompatibilities, dependency| 11 | incompatibilities.concat(incompatibilities_for(dependency)) 12 | incompatibilities 13 | } 14 | end 15 | 16 | private 17 | 18 | def incompatibilities_for(gem, dependency_path = []) 19 | dependency_path += [gem] 20 | 21 | gem.dependencies.inject([]) do |incompatibilities, dependency| 22 | if dependency.rails? 23 | if !dependency.satisfied_by_rails4? 24 | incompatibilities << GemIncompatibility.new(dependency, dependency_path) 25 | end 26 | elsif gem.name != dependency.name 27 | if gem_dependency = @gemfile[dependency.name] 28 | incompatibilities.concat(incompatibilities_for(gem_dependency, dependency_path)) 29 | end 30 | end 31 | 32 | incompatibilities 33 | end 34 | end 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /lib/rails4_upgrade/lockfile.rb: -------------------------------------------------------------------------------- 1 | module Rails4Upgrade 2 | # Encapsulates extraction of specs and dependencies from the Gemfile.lock 3 | # 4 | # This is because in Bundler v1.15.0 Bundler::LockfileParser#dependencies 5 | # changed from an instance of Array to an instance of Hash. 6 | class Lockfile 7 | def initialize(lockfile_content) 8 | @lockfile = Bundler::LockfileParser.new(lockfile_content) 9 | end 10 | 11 | def specs 12 | @lockfile.specs 13 | end 14 | 15 | def dependencies 16 | if bundler_version <= legacy_bundler_version 17 | lockfile_dependencies 18 | else 19 | lockfile_dependencies.values 20 | end 21 | end 22 | 23 | private 24 | 25 | def bundler_version 26 | ::Gem::Version.create(Bundler::VERSION) 27 | end 28 | 29 | def legacy_bundler_version 30 | ::Gem::Version.create('1.14.6') 31 | end 32 | 33 | def lockfile_dependencies 34 | @lockfile.dependencies 35 | end 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /lib/rails4_upgrade/railtie.rb: -------------------------------------------------------------------------------- 1 | module Rails4Upgrade 2 | class Railtie < ::Rails::Railtie 3 | rake_tasks do 4 | load File.join(File.dirname(__FILE__), "tasks", "upgrade.rake") 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /lib/rails4_upgrade/tasks/upgrade.rake: -------------------------------------------------------------------------------- 1 | namespace :rails4 do 2 | desc "Run through each precheck for compatibility with Rails 4" 3 | task :check do 4 | puts "** GEM COMPATIBILITY CHECK **" 5 | Rake::Task["rails4:check_gems"].invoke 6 | end 7 | 8 | desc "Check for gem incompatibilities with Rails 4" 9 | task :check_gems do 10 | gemfile_path = File.join(".", "Gemfile.lock") 11 | gemfile = Rails4Upgrade::Gemfile.new(File.open(gemfile_path)) 12 | incompatibile_gems = Rails4Upgrade::IncompatibleGems.new(gemfile) 13 | 14 | formatter = Rails4Upgrade::Formatters::IncompatibleGemsFormatter.new(incompatibile_gems) 15 | formatter.output 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /lib/rails4_upgrade/version.rb: -------------------------------------------------------------------------------- 1 | module Rails4Upgrade 2 | VERSION = "0.5.0" 3 | end 4 | -------------------------------------------------------------------------------- /rails4_upgrade.gemspec: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | lib = File.expand_path('../lib', __FILE__) 3 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 4 | require 'rails4_upgrade/version' 5 | 6 | Gem::Specification.new do |gem| 7 | gem.name = "rails4_upgrade" 8 | gem.version = Rails4Upgrade::VERSION 9 | gem.authors = ["Andy Lindeman"] 10 | gem.email = ["alindeman@gmail.com"] 11 | gem.description = %q{Upgrade assistant for transitioning applications from Rails 3 to Rails 4} 12 | gem.summary = %q{Upgrade assistant for transitioning applications from Rails 3 to Rails 4} 13 | gem.homepage = "http://www.upgradingtorails4.com/" 14 | 15 | gem.files = `git ls-files`.split($/) 16 | gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) } 17 | gem.test_files = gem.files.grep(%r{^(test|spec|features)/}) 18 | gem.require_paths = ["lib"] 19 | 20 | gem.add_dependency "bundler", ">=1.2.2" 21 | gem.add_dependency "terminal-table", ">=1.4.5" 22 | 23 | gem.add_development_dependency "rake", "~>10.0.0" 24 | gem.add_development_dependency "rspec", "~>2.12.0" 25 | gem.add_development_dependency "vcr", "~>2.3.0" 26 | gem.add_development_dependency "webmock", "~>1.8.0" 27 | end 28 | -------------------------------------------------------------------------------- /spec/fixtures/gemfiles/Gemfile_with_devise.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: http://rubygems.org/ 3 | specs: 4 | actionmailer (3.2.8) 5 | actionpack (= 3.2.8) 6 | mail (~> 2.4.4) 7 | actionpack (3.2.8) 8 | activemodel (= 3.2.8) 9 | activesupport (= 3.2.8) 10 | builder (~> 3.0.0) 11 | erubis (~> 2.7.0) 12 | journey (~> 1.0.4) 13 | rack (~> 1.4.0) 14 | rack-cache (~> 1.2) 15 | rack-test (~> 0.6.1) 16 | sprockets (~> 2.1.3) 17 | activemodel (3.2.8) 18 | activesupport (= 3.2.8) 19 | builder (~> 3.0.0) 20 | activerecord (3.2.8) 21 | activemodel (= 3.2.8) 22 | activesupport (= 3.2.8) 23 | arel (~> 3.0.2) 24 | tzinfo (~> 0.3.29) 25 | activeresource (3.2.8) 26 | activemodel (= 3.2.8) 27 | activesupport (= 3.2.8) 28 | activesupport (3.2.8) 29 | i18n (~> 0.6) 30 | multi_json (~> 1.0) 31 | arel (3.0.2) 32 | bcrypt-ruby (3.0.1) 33 | builder (3.0.4) 34 | devise (2.1.2) 35 | bcrypt-ruby (~> 3.0) 36 | orm_adapter (~> 0.1) 37 | railties (~> 3.1) 38 | warden (~> 1.2.1) 39 | erubis (2.7.0) 40 | hike (1.2.1) 41 | i18n (0.6.1) 42 | journey (1.0.4) 43 | json (1.7.5) 44 | mail (2.4.4) 45 | i18n (>= 0.4.0) 46 | mime-types (~> 1.16) 47 | treetop (~> 1.4.8) 48 | mime-types (1.19) 49 | multi_json (1.3.7) 50 | orm_adapter (0.4.0) 51 | polyglot (0.3.3) 52 | rack (1.4.1) 53 | rack-cache (1.2) 54 | rack (>= 0.4) 55 | rack-ssl (1.3.2) 56 | rack 57 | rack-test (0.6.2) 58 | rack (>= 1.0) 59 | rails (3.2.8) 60 | actionmailer (= 3.2.8) 61 | actionpack (= 3.2.8) 62 | activerecord (= 3.2.8) 63 | activeresource (= 3.2.8) 64 | activesupport (= 3.2.8) 65 | bundler (~> 1.0) 66 | railties (= 3.2.8) 67 | railties (3.2.8) 68 | actionpack (= 3.2.8) 69 | activesupport (= 3.2.8) 70 | rack-ssl (~> 1.3.2) 71 | rake (>= 0.8.7) 72 | rdoc (~> 3.4) 73 | thor (>= 0.14.6, < 2.0) 74 | rake (10.0.1) 75 | rdoc (3.12) 76 | json (~> 1.4) 77 | sprockets (2.1.3) 78 | hike (~> 1.2) 79 | rack (~> 1.0) 80 | tilt (~> 1.1, != 1.3.0) 81 | thor (0.16.0) 82 | tilt (1.3.3) 83 | treetop (1.4.12) 84 | polyglot 85 | polyglot (>= 0.3.1) 86 | tzinfo (0.3.35) 87 | warden (1.2.1) 88 | rack (>= 1.0) 89 | 90 | PLATFORMS 91 | ruby 92 | 93 | DEPENDENCIES 94 | devise 95 | rails (= 3.2.8) 96 | -------------------------------------------------------------------------------- /spec/fixtures/gemfiles/Gemfile_with_ransack.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: http://rubygems.org/ 3 | specs: 4 | actionmailer (3.2.8) 5 | actionpack (= 3.2.8) 6 | mail (~> 2.4.4) 7 | actionpack (3.2.8) 8 | activemodel (= 3.2.8) 9 | activesupport (= 3.2.8) 10 | builder (~> 3.0.0) 11 | erubis (~> 2.7.0) 12 | journey (~> 1.0.4) 13 | rack (~> 1.4.0) 14 | rack-cache (~> 1.2) 15 | rack-test (~> 0.6.1) 16 | sprockets (~> 2.1.3) 17 | activemodel (3.2.8) 18 | activesupport (= 3.2.8) 19 | builder (~> 3.0.0) 20 | activerecord (3.2.8) 21 | activemodel (= 3.2.8) 22 | activesupport (= 3.2.8) 23 | arel (~> 3.0.2) 24 | tzinfo (~> 0.3.29) 25 | activeresource (3.2.8) 26 | activemodel (= 3.2.8) 27 | activesupport (= 3.2.8) 28 | activesupport (3.2.8) 29 | i18n (~> 0.6) 30 | multi_json (~> 1.0) 31 | arel (3.0.2) 32 | builder (3.0.4) 33 | erubis (2.7.0) 34 | hike (1.2.1) 35 | i18n (0.6.1) 36 | journey (1.0.4) 37 | json (1.7.5) 38 | mail (2.4.4) 39 | i18n (>= 0.4.0) 40 | mime-types (~> 1.16) 41 | treetop (~> 1.4.8) 42 | mime-types (1.19) 43 | multi_json (1.3.7) 44 | polyamorous (0.5.0) 45 | activerecord (~> 3.0) 46 | polyglot (0.3.3) 47 | rack (1.4.1) 48 | rack-cache (1.2) 49 | rack (>= 0.4) 50 | rack-ssl (1.3.2) 51 | rack 52 | rack-test (0.6.2) 53 | rack (>= 1.0) 54 | rails (3.2.8) 55 | actionmailer (= 3.2.8) 56 | actionpack (= 3.2.8) 57 | activerecord (= 3.2.8) 58 | activeresource (= 3.2.8) 59 | activesupport (= 3.2.8) 60 | bundler (~> 1.0) 61 | railties (= 3.2.8) 62 | railties (3.2.8) 63 | actionpack (= 3.2.8) 64 | activesupport (= 3.2.8) 65 | rack-ssl (~> 1.3.2) 66 | rake (>= 0.8.7) 67 | rdoc (~> 3.4) 68 | thor (>= 0.14.6, < 2.0) 69 | rake (10.0.1) 70 | ransack (0.7.0) 71 | actionpack (~> 3.0) 72 | activerecord (~> 3.0) 73 | polyamorous (~> 0.5.0) 74 | rdoc (3.12) 75 | json (~> 1.4) 76 | sprockets (2.1.3) 77 | hike (~> 1.2) 78 | rack (~> 1.0) 79 | tilt (~> 1.1, != 1.3.0) 80 | thor (0.16.0) 81 | tilt (1.3.3) 82 | treetop (1.4.12) 83 | polyglot 84 | polyglot (>= 0.3.1) 85 | tzinfo (0.3.35) 86 | 87 | PLATFORMS 88 | ruby 89 | 90 | DEPENDENCIES 91 | rails (= 3.2.8) 92 | ransack 93 | -------------------------------------------------------------------------------- /spec/fixtures/gemfiles/Gemfile_with_recursive_dependency.lock: -------------------------------------------------------------------------------- 1 | GIT 2 | remote: git://github.com/alindeman/rails4_upgrade.git 3 | revision: 2fd7e69c664a7b781c5c0467e69a0824ee2d67b9 4 | specs: 5 | rails4_upgrade (0.0.4) 6 | bundler (>= 1.2.2) 7 | terminal-table (>= 1.4.5) 8 | 9 | GEM 10 | remote: https://rubygems.org/ 11 | specs: 12 | actionmailer (4.0.0.beta1) 13 | actionpack (= 4.0.0.beta1) 14 | mail (~> 2.5.3) 15 | actionpack (4.0.0.beta1) 16 | activesupport (= 4.0.0.beta1) 17 | builder (~> 3.1.0) 18 | erubis (~> 2.7.0) 19 | rack (~> 1.5.2) 20 | rack-test (~> 0.6.2) 21 | activemodel (4.0.0.beta1) 22 | activesupport (= 4.0.0.beta1) 23 | builder (~> 3.1.0) 24 | activerecord (4.0.0.beta1) 25 | activemodel (= 4.0.0.beta1) 26 | activerecord-deprecated_finders (~> 0.0.3) 27 | activesupport (= 4.0.0.beta1) 28 | arel (~> 4.0.0.beta1) 29 | activerecord-deprecated_finders (0.0.3) 30 | activesupport (4.0.0.beta1) 31 | i18n (~> 0.6.2) 32 | minitest (~> 4.2) 33 | multi_json (~> 1.3) 34 | thread_safe (~> 0.1) 35 | tzinfo (~> 0.3.33) 36 | addressable (2.3.3) 37 | arel (4.0.0.beta2) 38 | atomic (1.0.1) 39 | awesome_print (1.1.0) 40 | bcrypt-ruby (3.0.1-x86-mingw32) 41 | better_errors (0.7.2) 42 | coderay (>= 1.0.0) 43 | erubis (>= 2.6.6) 44 | binding_of_caller (0.7.1) 45 | debug_inspector (>= 0.0.1) 46 | bootstrap-datepicker-rails (1.0.0.2) 47 | railties (>= 3.0) 48 | bootstrap-sass (2.3.1.0) 49 | sass (~> 3.2) 50 | builder (3.1.4) 51 | capybara (2.0.3) 52 | mime-types (>= 1.16) 53 | nokogiri (>= 1.3.3) 54 | rack (>= 1.0.0) 55 | rack-test (>= 0.5.4) 56 | selenium-webdriver (~> 2.0) 57 | xpath (~> 1.0.0) 58 | childprocess (0.3.9) 59 | ffi (~> 1.0, >= 1.0.11) 60 | coderay (1.0.9) 61 | coffee-rails (4.0.0.beta1) 62 | coffee-script (>= 2.2.0) 63 | railties (>= 4.0.0.beta, < 5.0) 64 | coffee-script (2.2.0) 65 | coffee-script-source 66 | execjs 67 | coffee-script-source (1.6.2) 68 | columnize (0.3.6) 69 | cucumber (1.2.3) 70 | builder (>= 2.1.2) 71 | diff-lcs (>= 1.1.3) 72 | gherkin (~> 2.11.6) 73 | multi_json (~> 1.3) 74 | cucumber-rails (1.3.0) 75 | capybara (>= 1.1.2) 76 | cucumber (>= 1.1.8) 77 | nokogiri (>= 1.5.0) 78 | database_cleaner (0.9.1) 79 | debug_inspector (0.0.2) 80 | debugger (1.5.0) 81 | columnize (>= 0.3.1) 82 | debugger-linecache (~> 1.2.0) 83 | debugger-ruby_core_source (~> 1.2.0) 84 | debugger-linecache (1.2.0) 85 | debugger-ruby_core_source (1.2.0) 86 | devise (1.5.4) 87 | bcrypt-ruby (~> 3.0) 88 | orm_adapter (~> 0.0.3) 89 | warden (~> 1.1) 90 | diff-lcs (1.2.1) 91 | email_spec (1.4.0) 92 | launchy (~> 2.1) 93 | mail (~> 2.2) 94 | erubis (2.7.0) 95 | execjs (1.4.0) 96 | multi_json (~> 1.0) 97 | factory_girl (4.2.0) 98 | activesupport (>= 3.0.0) 99 | factory_girl_rails (4.2.1) 100 | factory_girl (~> 4.2.0) 101 | railties (>= 3.0.0) 102 | ffi (1.6.0-x86-mingw32) 103 | figaro (0.6.3) 104 | bundler (~> 1.0) 105 | rails (>= 3, < 5) 106 | formtastic (2.2.1) 107 | actionpack (>= 3.0) 108 | formtastic-bootstrap (2.0.0) 109 | formtastic (~> 2.2) 110 | formtastic-bootstrap 111 | gherkin (2.11.6-x86-mingw32) 112 | json (>= 1.7.6) 113 | haml (4.0.1) 114 | tilt 115 | haml-rails (0.4) 116 | actionpack (>= 3.1, < 4.1) 117 | activesupport (>= 3.1, < 4.1) 118 | haml (>= 3.1, < 4.1) 119 | railties (>= 3.1, < 4.1) 120 | hike (1.2.1) 121 | hirb (0.7.1) 122 | i18n (0.6.4) 123 | jbuilder (1.0.2) 124 | activesupport (>= 3.0.0) 125 | jquery-rails (2.2.1) 126 | railties (>= 3.0, < 5.0) 127 | thor (>= 0.14, < 2.0) 128 | json (1.7.7) 129 | launchy (2.2.0) 130 | addressable (~> 2.3) 131 | mail (2.5.3) 132 | i18n (>= 0.4.0) 133 | mime-types (~> 1.16) 134 | treetop (~> 1.4.8) 135 | mime-types (1.21) 136 | minitest (4.7.0) 137 | multi_json (1.7.2) 138 | nokogiri (1.5.9-x86-mingw32) 139 | orm_adapter (0.0.7) 140 | pg (0.15.0-x86-mingw32) 141 | polyglot (0.3.3) 142 | puma (1.6.3) 143 | rack (~> 1.2) 144 | quiet_assets (1.0.2) 145 | railties (>= 3.1, < 5.0) 146 | rack (1.5.2) 147 | rack-test (0.6.2) 148 | rack (>= 1.0) 149 | rails (4.0.0.beta1) 150 | actionmailer (= 4.0.0.beta1) 151 | actionpack (= 4.0.0.beta1) 152 | activerecord (= 4.0.0.beta1) 153 | activesupport (= 4.0.0.beta1) 154 | bundler (>= 1.3.0, < 2.0) 155 | railties (= 4.0.0.beta1) 156 | sprockets-rails (~> 2.0.0.rc3) 157 | railties (4.0.0.beta1) 158 | actionpack (= 4.0.0.beta1) 159 | activesupport (= 4.0.0.beta1) 160 | rake (>= 0.8.7) 161 | rdoc (~> 3.4) 162 | thor (>= 0.17.0, < 2.0) 163 | rake (10.0.4) 164 | rdoc (3.12.2) 165 | json (~> 1.4) 166 | rspec-core (2.13.1) 167 | rspec-expectations (2.13.0) 168 | diff-lcs (>= 1.1.3, < 2.0) 169 | rspec-mocks (2.13.0) 170 | rspec-rails (2.13.0) 171 | actionpack (>= 3.0) 172 | activesupport (>= 3.0) 173 | railties (>= 3.0) 174 | rspec-core (~> 2.13.0) 175 | rspec-expectations (~> 2.13.0) 176 | rspec-mocks (~> 2.13.0) 177 | rubyzip (0.9.9) 178 | sass (3.2.7) 179 | sass-rails (4.0.0.beta1) 180 | railties (>= 4.0.0.beta, < 5.0) 181 | sass (>= 3.1.10) 182 | sprockets-rails (~> 2.0.0.rc0) 183 | tilt (~> 1.3) 184 | selenium-webdriver (2.31.0) 185 | childprocess (>= 0.2.5) 186 | multi_json (~> 1.0) 187 | rubyzip 188 | websocket (~> 1.0.4) 189 | sprockets (2.9.0) 190 | hike (~> 1.2) 191 | multi_json (~> 1.0) 192 | rack (~> 1.0) 193 | tilt (~> 1.1, != 1.3.0) 194 | sprockets-rails (2.0.0.rc3) 195 | actionpack (>= 3.0) 196 | activesupport (>= 3.0) 197 | sprockets (~> 2.8) 198 | sqlite3 (1.3.7-x86-mingw32) 199 | terminal-table (1.4.5) 200 | thor (0.18.0) 201 | thread_safe (0.1.0) 202 | atomic 203 | tilt (1.3.6) 204 | treetop (1.4.12) 205 | polyglot 206 | polyglot (>= 0.3.1) 207 | turbolinks (1.1.0) 208 | coffee-rails 209 | tzinfo (0.3.37) 210 | uglifier (1.3.0) 211 | execjs (>= 0.3.0) 212 | multi_json (~> 1.0, >= 1.0.2) 213 | warden (1.2.1) 214 | rack (>= 1.0) 215 | websocket (1.0.7) 216 | xpath (1.0.0) 217 | nokogiri (~> 1.3) 218 | 219 | PLATFORMS 220 | x86-mingw32 221 | 222 | DEPENDENCIES 223 | awesome_print 224 | better_errors 225 | binding_of_caller 226 | bootstrap-datepicker-rails 227 | bootstrap-sass 228 | capybara 229 | coffee-rails (~> 4.0.0.beta1) 230 | cucumber-rails 231 | database_cleaner 232 | debugger 233 | devise 234 | email_spec 235 | factory_girl_rails 236 | figaro 237 | formtastic 238 | formtastic-bootstrap 239 | haml 240 | haml-rails 241 | hirb 242 | jbuilder (~> 1.0.1) 243 | jquery-rails 244 | launchy 245 | pg 246 | puma 247 | quiet_assets 248 | rails (= 4.0.0.beta1) 249 | rails4_upgrade! 250 | rspec-rails 251 | sass-rails (~> 4.0.0.beta1) 252 | sqlite3 (= 1.3.7) 253 | turbolinks 254 | uglifier (>= 1.0.3) 255 | -------------------------------------------------------------------------------- /spec/gemfile_spec.rb: -------------------------------------------------------------------------------- 1 | require "spec_helper" 2 | 3 | module Rails4Upgrade 4 | describe Gemfile do 5 | let(:gemfile_path) { File.join(File.dirname(__FILE__), "fixtures", "gemfiles", "Gemfile_with_devise.lock") } 6 | let(:gemfile) { Rails4Upgrade::Gemfile.new(File.open(gemfile_path)) } 7 | 8 | it "lists the direct dependencies" do 9 | devise = gemfile.dependencies[0] 10 | expect(devise.name).to eq("devise") 11 | expect(devise.version).to eq(::Gem::Version.new("2.1.2")) 12 | 13 | rails = gemfile.dependencies[1] 14 | expect(rails.name).to eq("rails") 15 | expect(rails.version).to eq(::Gem::Version.new("3.2.8")) 16 | end 17 | 18 | it "returns the specific details about a given gem" do 19 | bcrypt = gemfile["bcrypt-ruby"] 20 | expect(bcrypt.name).to eq("bcrypt-ruby") 21 | expect(bcrypt.version).to eq(::Gem::Version.new("3.0.1")) 22 | end 23 | 24 | it "lists the dependencies of a given gem" do 25 | devise = gemfile["devise"] 26 | expect(devise.dependencies).to match_array([ 27 | GemDependency.new("bcrypt-ruby", "~> 3.0"), 28 | GemDependency.new("orm_adapter", "~> 0.1"), 29 | GemDependency.new("railties", "~> 3.1"), 30 | GemDependency.new("warden", "~> 1.2.1") 31 | ]) 32 | end 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /spec/incompatible_gems_spec.rb: -------------------------------------------------------------------------------- 1 | require "spec_helper" 2 | 3 | module Rails4Upgrade 4 | describe IncompatibleGems do 5 | context "with Devise, a gem that depends on Rails ~> 3.2" do 6 | let(:gemfile_path) { File.join(File.dirname(__FILE__), "fixtures", "gemfiles", "Gemfile_with_devise.lock") } 7 | let(:gemfile) { Rails4Upgrade::Gemfile.new(File.open(gemfile_path)) } 8 | subject(:incompatible_gems) { IncompatibleGems.new(gemfile) } 9 | 10 | it "lists incompatibilities" do 11 | incompatibilities = incompatible_gems.incompatibilities 12 | 13 | expect(incompatibilities.size).to eq(1) 14 | expect(incompatibilities[0].dependency).to eq(GemDependency.new("railties", "~> 3.1")) 15 | 16 | expect(incompatibilities[0].path.size).to eq(1) 17 | expect(incompatibilities[0].path[0].name).to eq("devise") 18 | end 19 | end 20 | 21 | context "with Ransack, a gem with multi-level dependencies on Rails ~> 3.0" do 22 | let(:gemfile_path) { File.join(File.dirname(__FILE__), "fixtures", "gemfiles", "Gemfile_with_ransack.lock") } 23 | let(:gemfile) { Rails4Upgrade::Gemfile.new(File.open(gemfile_path)) } 24 | subject(:incompatible_gems) { IncompatibleGems.new(gemfile) } 25 | 26 | it "lists incompatibilities" do 27 | incompatibilities = incompatible_gems.incompatibilities 28 | 29 | expect(incompatibilities.size).to eq(3) 30 | expect(incompatibilities[2].dependency).to eq(GemDependency.new("activerecord", "~> 3.0")) 31 | end 32 | 33 | it "list incompatibilies from ransack itself" do 34 | incompatibilities = incompatible_gems.incompatibilities 35 | 36 | expect(incompatibilities[0].dependency).to eq(GemDependency.new("actionpack", "~> 3.0")) 37 | expect(incompatibilities[0].path.size).to eq(1) 38 | expect(incompatibilities[0].path[0].name).to eq("ransack") 39 | 40 | expect(incompatibilities[1].dependency).to eq(GemDependency.new("activerecord", "~> 3.0")) 41 | expect(incompatibilities[1].path.size).to eq(1) 42 | expect(incompatibilities[1].path[0].name).to eq("ransack") 43 | end 44 | 45 | it "lists incompatibilities from polyamorous, which ransack depends on" do 46 | incompatibilities = incompatible_gems.incompatibilities 47 | 48 | expect(incompatibilities[2].dependency).to eq(GemDependency.new("activerecord", "~> 3.0")) 49 | expect(incompatibilities[2].path.size).to eq(2) 50 | expect(incompatibilities[2].path[0].name).to eq("ransack") 51 | expect(incompatibilities[2].path[1].name).to eq("polyamorous") 52 | end 53 | end 54 | 55 | context "with a Gemfile that has a recursive dependency" do 56 | let(:gemfile_path) { File.join(File.dirname(__FILE__), "fixtures", "gemfiles", "Gemfile_with_recursive_dependency.lock") } 57 | let(:gemfile) { Rails4Upgrade::Gemfile.new(File.open(gemfile_path)) } 58 | subject(:incompatible_gems) { IncompatibleGems.new(gemfile) } 59 | 60 | it "lists incompatibilities" do 61 | incompatibilities = incompatible_gems.incompatibilities 62 | expect(incompatibilities.size).to eq(0) 63 | end 64 | end 65 | end 66 | end 67 | -------------------------------------------------------------------------------- /spec/lockfile_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | require 'bundler' 3 | 4 | require 'rails4_upgrade/lockfile' 5 | 6 | module Rails4Upgrade 7 | describe Lockfile do 8 | let(:gemfile_path) { File.join(File.dirname(__FILE__), "fixtures", "gemfiles", "Gemfile_with_devise.lock") } 9 | let(:gemfile_content) { File.open(gemfile_path).read } 10 | 11 | let(:bundler_lockfile) { Bundler::LockfileParser.new(gemfile_content) } 12 | 13 | let(:lockfile) { Lockfile.new(gemfile_content) } 14 | 15 | it "returns the same specs as the bundler lockfile" do 16 | expect(lockfile.specs).to eq(bundler_lockfile.specs) 17 | end 18 | 19 | context "when using bundler >= 1.15.0" do 20 | let(:lockfile_dependencies) { double('lockfile_dependencies') } 21 | 22 | before(:each) { 23 | lockfile.stub(:bundler_version => ::Gem::Version.create('1.15.0')) 24 | lockfile.stub(:lockfile_dependencies => lockfile_dependencies) 25 | } 26 | 27 | it "returns the same dependencies as the bundler lockfile dependencies.values" do 28 | lockfile_dependencies.should_receive(:values) 29 | lockfile.dependencies 30 | end 31 | end 32 | 33 | context "when using bundler < 1.15.0" do 34 | let(:lockfile_dependencies) { double('lockfile_dependencies') } 35 | 36 | before(:each) { 37 | lockfile.stub(:bundler_version => ::Gem::Version.create('1.14.6')) 38 | lockfile.stub(:lockfile_dependencies => lockfile_dependencies) 39 | } 40 | 41 | it "returns the same dependencies as the bundler lockfile dependencies" do 42 | lockfile_dependencies.should_not_receive(:values) 43 | lockfile.dependencies 44 | end 45 | end 46 | end 47 | end 48 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | require "vcr" 2 | require_relative "../lib/rails4_upgrade" 3 | 4 | RSpec.configure do |config| 5 | config.treat_symbols_as_metadata_keys_with_true_values = true 6 | config.run_all_when_everything_filtered = true 7 | config.filter_run :focus 8 | config.order = 'random' 9 | end 10 | 11 | VCR.configure do |c| 12 | c.cassette_library_dir = 'spec/fixtures/vcr_cassettes' 13 | c.hook_into :webmock 14 | end 15 | --------------------------------------------------------------------------------