diff --git a/Gemfile b/Gemfile index f45829379..8760baf61 100644 --- a/Gemfile +++ b/Gemfile @@ -5,6 +5,7 @@ gemspec gem "rails" gem "rake", ">= 11.1" gem "rack-proxy", require: false +gem "semantic_range", require: false group :test do gem "minitest", "~> 5.0" diff --git a/Gemfile.lock b/Gemfile.lock index 251abf40e..500dae0f2 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -5,6 +5,7 @@ PATH activesupport (>= 4.2) rack-proxy (>= 0.6.1) railties (>= 4.2) + semantic_range (>= 2.3.0) GEM remote: https://rubygems.org/ @@ -136,6 +137,7 @@ GEM rubocop-performance (1.3.0) rubocop (>= 0.68.0) ruby-progressbar (1.10.1) + semantic_range (2.3.0) sprockets (4.0.0) concurrent-ruby (~> 1.0) rack (> 1, < 3) @@ -165,6 +167,7 @@ DEPENDENCIES rake (>= 11.1) rubocop (< 0.69) rubocop-performance + semantic_range webpacker! BUNDLED WITH diff --git a/lib/tasks/webpacker/check_node.rake b/lib/tasks/webpacker/check_node.rake index 63cdd03d4..b6d03c290 100644 --- a/lib/tasks/webpacker/check_node.rake +++ b/lib/tasks/webpacker/check_node.rake @@ -1,3 +1,4 @@ +require "semantic_range" namespace :webpacker do desc "Verifies if Node.js is installed" task :check_node do @@ -6,19 +7,25 @@ namespace :webpacker do raise Errno::ENOENT if node_version.blank? pkg_path = Pathname.new("#{__dir__}/../../../package.json").realpath - node_requirement = JSON.parse(pkg_path.read)["engines"]["node"] + node_range = JSON.parse(pkg_path.read)["engines"]["node"] + is_valid = SemanticRange.satisfies?(node_version, node_range) rescue false + semver_major = node_version[/\d+/] rescue nil + is_unstable = semver_major.to_i.odd? rescue false - requirement = Gem::Requirement.new(node_requirement) - version = Gem::Version.new(node_version.strip.tr("v", "")) + if is_unstable + $stderr.puts "Warning: you are using an unstable release of Node.js (#{node_version}). If you encounter issues with Node.js, consider switching to an Active LTS release. More info: https://docs.npmjs.com/try-the-latest-stable-version-of-node" + end - unless requirement.satisfied_by?(version) - $stderr.puts "Webpacker requires Node.js #{requirement} and you are using #{version}" + unless is_valid + $stderr.puts "Webpacker requires Node.js \"#{node_range}\" and you are using #{node_version}" $stderr.puts "Please upgrade Node.js https://nodejs.org/en/download/" - $stderr.puts "Exiting!" && exit! + $stderr.puts "Exiting!" + exit! end rescue Errno::ENOENT $stderr.puts "Node.js not installed. Please download and install Node.js https://nodejs.org/en/download/" - $stderr.puts "Exiting!" && exit! + $stderr.puts "Exiting!" + exit! end end end diff --git a/lib/tasks/webpacker/check_yarn.rake b/lib/tasks/webpacker/check_yarn.rake index 3445da9e1..d7c863c1b 100644 --- a/lib/tasks/webpacker/check_yarn.rake +++ b/lib/tasks/webpacker/check_yarn.rake @@ -1,3 +1,4 @@ +require "semantic_range" namespace :webpacker do desc "Verifies if Yarn is installed" task :check_yarn do @@ -6,19 +7,25 @@ namespace :webpacker do raise Errno::ENOENT if yarn_version.blank? pkg_path = Pathname.new("#{__dir__}/../../../package.json").realpath - yarn_requirement = JSON.parse(pkg_path.read)["engines"]["yarn"] + yarn_range = JSON.parse(pkg_path.read)["engines"]["yarn"] + is_valid = SemanticRange.satisfies?(yarn_version, yarn_range) rescue false + is_unsupported = SemanticRange.satisfies?(yarn_version, ">=2.0.0") rescue false - requirement = Gem::Requirement.new(yarn_requirement) - version = Gem::Version.new(yarn_version) - - unless requirement.satisfied_by?(version) - $stderr.puts "Webpacker requires Yarn #{requirement} and you are using #{version}" - $stderr.puts "Please upgrade Yarn https://yarnpkg.com/lang/en/docs/install/" - $stderr.puts "Exiting!" && exit! + unless is_valid + $stderr.puts "Webpacker requires Yarn \"#{yarn_range}\" and you are using #{yarn_version}" + if is_unsupported + $stderr.puts "This version of Webpacker does not support Yarn #{yarn_version}. Please downgrade to a supported version of Yarn https://yarnpkg.com/lang/en/docs/install/" + $stderr.puts "For information on using Webpacker with Yarn 2.0, see https://github.com/rails/webpacker/issues/2112" + else + $stderr.puts "Please upgrade Yarn https://yarnpkg.com/lang/en/docs/install/" + end + $stderr.puts "Exiting!" + exit! end rescue Errno::ENOENT $stderr.puts "Yarn not installed. Please download and install Yarn from https://yarnpkg.com/lang/en/docs/install/" - $stderr.puts "Exiting!" && exit! + $stderr.puts "Exiting!" + exit! end end end diff --git a/test/rake_tasks_test.rb b/test/rake_tasks_test.rb index eb6e547bd..bdeec2ad8 100644 --- a/test/rake_tasks_test.rb +++ b/test/rake_tasks_test.rb @@ -28,6 +28,17 @@ def test_rake_task_webpacker_check_binstubs refute_includes output, "webpack binstubs not found." end + def test_check_node_version + output = Dir.chdir(test_app_path) { `rake webpacker:check_node 2>&1` } + refute_includes output, "Webpacker requires Node.js" + end + + def test_check_yarn_version + output = Dir.chdir(test_app_path) { `rake webpacker:check_yarn 2>&1` } + refute_includes output, "Yarn not installed" + refute_includes output, "Webpacker requires Yarn" + end + def test_rake_webpacker_yarn_install_in_non_production_environments assert_includes test_app_dev_dependencies, "right-pad" diff --git a/webpacker.gemspec b/webpacker.gemspec index c056bac1e..6ae568f9d 100644 --- a/webpacker.gemspec +++ b/webpacker.gemspec @@ -17,9 +17,10 @@ Gem::Specification.new do |s| s.required_ruby_version = ">= 2.3.0" - s.add_dependency "activesupport", ">= 4.2" - s.add_dependency "railties", ">= 4.2" - s.add_dependency "rack-proxy", ">= 0.6.1" + s.add_dependency "activesupport", ">= 4.2" + s.add_dependency "railties", ">= 4.2" + s.add_dependency "rack-proxy", ">= 0.6.1" + s.add_dependency "semantic_range", ">= 2.3.0" s.add_development_dependency "bundler", ">= 1.3.0" s.add_development_dependency "rubocop", "< 0.69"