diff --git a/CHANGELOG.md b/CHANGELOG.md index c83d1cb21d..2a912da5ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,13 @@ Changes since last non-beta release. - Removed ReactOnRails::Utils.server_bundle_file_name and ReactOnRails::Utils.bundle_file_name. - No longer logging the `railsContext` when server logging. +#### Fixes +- More exact version checking. We keep the react_on_rails gem and the react-on-rails node package at +the same exact versions so that we can be sure that the interaction between them is precise. +This is so that if a bug is detected after some update, it's critical that +both the gem and the node package get the updates. This change ensures that the package.json specification does not use a +~ or ^ as reported in [#1062](https://github.com/shakacode/react_on_rails/issues/1062). [PR 1063](https://github.com/shakacode/react_on_rails/pull/1063) by [justin808](https://github.com/justin808). + ### [10.1.4] - 2018-04-11 #### Fixed diff --git a/README.md b/README.md index 96e8df2a11..7d090fe61e 100644 --- a/README.md +++ b/README.md @@ -343,10 +343,10 @@ Rails will start creating the app and will skip the files you have already creat All JavaScript in React On Rails is loaded from npm: [react-on-rails](https://www.npmjs.com/package/react-on-rails). To manually install this (you did not use the generator), assuming you have a standard configuration, run this command (assuming you are in the directory where you have your `node_modules`): ```bash -yarn add react-on-rails +yarn add react-on-rails --exact ``` -That will install the latest version and update your package.json. +That will install the latest version and update your package.json. **NOTE:** the `--exact` flag will ensure that you do not have a "~" or "^" for your react-on-rails version in your package.json. ### Webpacker Configuration diff --git a/lib/generators/react_on_rails/base_generator.rb b/lib/generators/react_on_rails/base_generator.rb index f4f49e4b7f..9297558273 100644 --- a/lib/generators/react_on_rails/base_generator.rb +++ b/lib/generators/react_on_rails/base_generator.rb @@ -43,7 +43,7 @@ def add_base_gems_to_gemfile end def add_yarn_dependencies - run "yarn add react-on-rails" + run "yarn add react-on-rails --exact" end def append_to_spec_rails_helper diff --git a/lib/react_on_rails/version_checker.rb b/lib/react_on_rails/version_checker.rb index 1bd26b7840..589e4a4c62 100644 --- a/lib/react_on_rails/version_checker.rb +++ b/lib/react_on_rails/version_checker.rb @@ -22,23 +22,37 @@ def raise_if_gem_and_node_package_versions_differ return if node_package_version.relative_path? node_major_minor_patch = node_package_version.major_minor_patch gem_major_minor_patch = gem_major_minor_patch_version - return if node_major_minor_patch[0] == gem_major_minor_patch[0] && - node_major_minor_patch[1] == gem_major_minor_patch[1] && - node_major_minor_patch[2] == gem_major_minor_patch[2] + versions_match = node_major_minor_patch[0] == gem_major_minor_patch[0] && + node_major_minor_patch[1] == gem_major_minor_patch[1] && + node_major_minor_patch[2] == gem_major_minor_patch[2] - raise_differing_versions_warning + raise_differing_versions_warning unless versions_match + + raise_node_semver_version_warning if node_package_version.semver_wildcard? end private + def common_error_msg + <<-MSG.strip_heredoc + Detected: #{node_package_version.raw} + gem: #{gem_version} + Ensure the installed version of the gem is the same as the version of + your installed node package. Do not use >= or ~> in your Gemfile for react_on_rails. + Do not use ^ or ~ in your package.json for react-on-rails. + Run `yarn add react-on-rails --exact` in the directory containing folder node_modules. + MSG + end + def raise_differing_versions_warning - msg = "**ERROR** ReactOnRails: ReactOnRails gem and node package versions do not match\n" \ - " gem: #{gem_version}\n" \ - " node package: #{node_package_version.raw}\n" \ - "Ensure the installed version of the gem is the same as the version of \n"\ - "your installed node package.\n"\ - "Run `#{ReactOnRails::Utils.prepend_cd_node_modules_directory('yarn add react-on-rails')}`" - raise msg + msg = "**ERROR** ReactOnRails: ReactOnRails gem and node package versions do not match\n#{common_error_msg}" + raise ReactOnRails::Error, msg + end + + def raise_node_semver_version_warning + msg = "**ERROR** ReactOnRails: Your node package version for react-on-rails contains a "\ + "^ or ~\n#{common_error_msg}" + raise ReactOnRails::Error, msg end def gem_version @@ -75,6 +89,10 @@ def raw end end + def semver_wildcard? + raw.match(/[~^]/) + end + def relative_path? raw.match(%r{(\.\.|\Afile:///)}).present? end diff --git a/rakelib/release.rake b/rakelib/release.rake index 4ced9e48e4..d28de5aad2 100644 --- a/rakelib/release.rake +++ b/rakelib/release.rake @@ -70,7 +70,7 @@ task :release, %i[gem_version dry_run tools_install] do |_t, args| sh_in_dir(gem_root, "gem release") # Update master with new npm version - sh_in_dir(File.join(gem_root, "spec", "dummy", "client"), "yarn add react-on-rails@#{npm_version}") + sh_in_dir(File.join(gem_root, "spec", "dummy", "client"), "yarn add react-on-rails@#{npm_version} --exact") sh_in_dir(gem_root, "git commit -am 'Updated spec/dummy/client/package.json latest version'") sh_in_dir(gem_root, "git push") end diff --git a/spec/dummy/Gemfile.lock b/spec/dummy/Gemfile.lock index a6dbd8bb47..4b3dfaca96 100644 --- a/spec/dummy/Gemfile.lock +++ b/spec/dummy/Gemfile.lock @@ -7,7 +7,7 @@ GIT PATH remote: ../.. specs: - react_on_rails (10.1.4) + react_on_rails (11.0.0.beta.1) addressable connection_pool execjs (~> 2.5) diff --git a/spec/react_on_rails/fixtures/semver_caret_package.json b/spec/react_on_rails/fixtures/semver_caret_package.json new file mode 100644 index 0000000000..546f499da9 --- /dev/null +++ b/spec/react_on_rails/fixtures/semver_caret_package.json @@ -0,0 +1,10 @@ +{ + "dependencies": { + "babel": "^6.3.26", + "react-on-rails": "^1.2.3", + "webpack": "^1.12.8" + }, + "devDependencies": { + "babel-eslint": "^5.0.0-beta6" + } +} diff --git a/spec/react_on_rails/fixtures/semver_tilde_package.json b/spec/react_on_rails/fixtures/semver_tilde_package.json new file mode 100644 index 0000000000..3ca755922f --- /dev/null +++ b/spec/react_on_rails/fixtures/semver_tilde_package.json @@ -0,0 +1,10 @@ +{ + "dependencies": { + "babel": "^6.3.26", + "react-on-rails": "~1.2.3", + "webpack": "^1.12.8" + }, + "devDependencies": { + "babel-eslint": "^5.0.0-beta6" + } +} diff --git a/spec/react_on_rails/version_checker_spec.rb b/spec/react_on_rails/version_checker_spec.rb index cf3baa37d6..06f01a59cb 100644 --- a/spec/react_on_rails/version_checker_spec.rb +++ b/spec/react_on_rails/version_checker_spec.rb @@ -18,7 +18,7 @@ module ReactOnRails context "when gem and node package major and minor versions are equal" do let(:node_package_version) do - double_package_version(raw: "^2.2.5-beta.2", major_minor_patch: %w[2 2 5]) + double_package_version(raw: "2.2.5-beta.2", major_minor_patch: %w[2 2 5]) end before { stub_gem_version("2.2.5.beta.2") } @@ -27,6 +27,18 @@ module ReactOnRails end end + context "when major and minor versions are equal BUT node uses semver wildcard" do + let(:node_package_version) do + double_package_version(raw: "^2.2.5", semver_wildcard: true, major_minor_patch: %w[2 2 5]) + end + before { stub_gem_version("2.2.5") } + + it "does raise" do + error = /ReactOnRails: Your node package version for react-on-rails contains a \^ or ~/ + expect { check_version(node_package_version) }.to raise_error(error) + end + end + context "when gem and node package major versions differ" do let(:node_package_version) do double_package_version(raw: "13.0.0.beta-2", major_minor_patch: %w[13 0 0]) @@ -75,9 +87,11 @@ module ReactOnRails end end - def double_package_version(raw: nil, major_minor_patch: nil, relative_path: false) + def double_package_version(raw: nil, semver_wildcard: false, + major_minor_patch: nil, relative_path: false) instance_double(VersionChecker::NodePackageVersion, raw: raw, + semver_wildcard?: semver_wildcard, major_minor_patch: major_minor_patch, relative_path?: relative_path) end @@ -90,6 +104,26 @@ def check_version(node_package_version) describe VersionChecker::NodePackageVersion do subject(:node_package_version) { VersionChecker::NodePackageVersion.new(package_json) } + describe "#semver_wildcard?" do + context "when package json lists an exact version of '0.0.2'" do + let(:package_json) { File.expand_path("fixtures/normal_package.json", __dir__) } + + specify { expect(node_package_version.semver_wildcard?).to be false } + end + + context "when package json lists a semver caret version of '^1.2.3'" do + let(:package_json) { File.expand_path("fixtures/semver_caret_package.json", __dir__) } + + specify { expect(node_package_version.semver_wildcard?).to be true } + end + + context "when package json lists a semver tilde version of '~1.2.3'" do + let(:package_json) { File.expand_path("fixtures/semver_tilde_package.json", __dir__) } + + specify { expect(node_package_version.semver_wildcard?).to be true } + end + end + context "when package json lists a version of '0.0.2'" do let(:package_json) { File.expand_path("fixtures/normal_package.json", __dir__) }