Skip to content

Commit

Permalink
More exact version checking
Browse files Browse the repository at this point in the history
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
  • Loading branch information
justin808 committed Apr 21, 2018
1 parent 4682d4f commit ea76d76
Show file tree
Hide file tree
Showing 9 changed files with 97 additions and 18 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion lib/generators/react_on_rails/base_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
40 changes: 29 additions & 11 deletions lib/react_on_rails/version_checker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -75,6 +89,10 @@ def raw
end
end

def semver_wildcard?
raw.match(/[~^]/)
end

def relative_path?
raw.match(%r{(\.\.|\Afile:///)}).present?
end
Expand Down
2 changes: 1 addition & 1 deletion rakelib/release.rake
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion spec/dummy/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
10 changes: 10 additions & 0 deletions spec/react_on_rails/fixtures/semver_caret_package.json
Original file line number Diff line number Diff line change
@@ -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"
}
}
10 changes: 10 additions & 0 deletions spec/react_on_rails/fixtures/semver_tilde_package.json
Original file line number Diff line number Diff line change
@@ -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"
}
}
38 changes: 36 additions & 2 deletions spec/react_on_rails/version_checker_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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") }

Expand All @@ -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])
Expand Down Expand Up @@ -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
Expand All @@ -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__) }

Expand Down

0 comments on commit ea76d76

Please sign in to comment.