Skip to content

Commit

Permalink
Prerequisites: Use system version of Node (#1201)
Browse files Browse the repository at this point in the history
We were incorrectly assuming consumers had the version of Node installed
that is declared in `Suspenders::NODE_LTS_VERSION`.

Because of this, we were generating a `.node-version` file with a
version that was not installed on the user's system. This was a problem
because when subsequent generators depending on Node were invoked, they
would raise the following:

```
No preset version installed for command node
Please install a version by running one of the following:

asdf install nodejs 20.11.1
```

To account for this, we [borrow][] from Rails, but modify slightly.
First, we look to see if `ENV["NODE_VERSION"]` is set. If not, we then
look to see if Node is installed, and set the version via `node
--version`. If neither of those values are present, we raise. This is
because we can't use a fallback value, since the consumer does not have
Node installed on their system.

Removes `Suspenders::NODE_LTS_VERSION` since it's no longer used as a
fallback.

Introduced [climate_control][] as a development dependency in order to
test this feature.

[borrow]: https://github.com/rails/rails/blob/d65fec4fd2a047533408cbbd4824b248adc0e3fd/railties/lib/rails/generators/app_base.rb#L521-L529
[climate_control]: https://github.com/thoughtbot/climate_control
  • Loading branch information
stevepolitodesign authored May 7, 2024
1 parent 4def0ae commit 7bf6e82
Show file tree
Hide file tree
Showing 12 changed files with 77 additions and 11 deletions.
2 changes: 2 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ GEM
base64 (0.1.1)
bigdecimal (3.1.4)
builder (3.2.4)
climate_control (1.2.0)
concurrent-ruby (1.2.2)
connection_pool (2.4.1)
crass (1.0.6)
Expand Down Expand Up @@ -234,6 +235,7 @@ PLATFORMS
x86_64-linux

DEPENDENCIES
climate_control
mocha
puma
sqlite3
Expand Down
1 change: 1 addition & 0 deletions lib/generators/suspenders/install/web_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ module Install
class WebGenerator < Rails::Generators::Base
include Suspenders::Generators::APIAppUnsupported
include Suspenders::Generators::DatabaseUnsupported
include Suspenders::Generators::NodeNotInstalled

source_root File.expand_path("../../../templates/install/web", __FILE__)
desc <<~MARKDOWN
Expand Down
5 changes: 4 additions & 1 deletion lib/generators/suspenders/prerequisites_generator.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
module Suspenders
module Generators
class PrerequisitesGenerator < Rails::Generators::Base
include Suspenders::Generators::Helpers
include Suspenders::Generators::NodeNotInstalled

source_root File.expand_path("../../templates/prerequisites", __FILE__)

desc <<~MARKDOWN
Creates `.node-version` file set to the current LTS version.
MARKDOWN

def node_version
def set_node_version
template "node-version", ".node-version"
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/generators/templates/prerequisites/node-version.tt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<%= Suspenders::NODE_LTS_VERSION %>
<%= node_version %>
4 changes: 3 additions & 1 deletion lib/suspenders/cleanup/generate_readme.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
module Suspenders
module Cleanup
class GenerateReadme
include Suspenders::Generators::Helpers

def self.perform(readme, app_name)
new(readme, app_name).perform
end
Expand Down Expand Up @@ -153,7 +155,7 @@ def prerequisites

@file.write <<~MARKDOWN
Ruby: `#{Suspenders::MINIMUM_RUBY_VERSION}`
Node: `#{Suspenders::NODE_LTS_VERSION}`
Node: `#{node_version}`
MARKDOWN

new_line
Expand Down
27 changes: 27 additions & 0 deletions lib/suspenders/generators.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ def default_test_helper_present?
def rspec_test_helper_present?
File.exist? Rails.root.join("spec/rails_helper.rb")
end

def node_version
ENV["NODE_VERSION"] || `node --version`[/\d+\.\d+\.\d+/]
end
end

module APIAppUnsupported
Expand Down Expand Up @@ -46,6 +50,8 @@ def api_only_app?
end

module DatabaseUnsupported
include Helpers

class Error < StandardError
def message
"This generator requires PostgreSQL"
Expand All @@ -72,5 +78,26 @@ def database_unsupported?
end
end
end

module NodeNotInstalled
class Error < StandardError
end

extend ActiveSupport::Concern

included do
def raise_if_node_not_installed
if node_not_installed?
raise Suspenders::Generators::NodeNotInstalled::Error
end
end
end

private

def node_not_installed?
!node_version.present?
end
end
end
end
1 change: 0 additions & 1 deletion lib/suspenders/version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,4 @@ module Suspenders
VERSION = "3.0.0".freeze
RAILS_VERSION = "~> 7.0".freeze
MINIMUM_RUBY_VERSION = ">= 3.1".freeze
NODE_LTS_VERSION = "20.11.1".freeze
end
1 change: 1 addition & 0 deletions suspenders.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Gem::Specification.new do |spec|

spec.add_dependency "rails", Suspenders::RAILS_VERSION

spec.add_development_dependency "climate_control"
spec.add_development_dependency "mocha"
spec.add_development_dependency "standard"
end
10 changes: 10 additions & 0 deletions test/generators/suspenders/install/web_generator_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,16 @@ class WebGeneratorTest < Rails::Generators::TestCase
end
end

test "raises if Node is not installed" do
Object.any_instance.stubs(:`).returns("")

with_database "postgresql" do
assert_raises Suspenders::Generators::NodeNotInstalled::Error do
run_generator
end
end
end

private

def prepare_destination
Expand Down
27 changes: 25 additions & 2 deletions test/generators/suspenders/prerequisites_generator_test.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require "test_helper"
require "climate_control"
require "generators/suspenders/prerequisites_generator"

module Suspenders
Expand All @@ -10,14 +11,36 @@ class PrerequisitesGeneratorTest < Rails::Generators::TestCase
destination Rails.root
teardown :restore_destination

test "generates .node-version file" do
test "generates .node-version file (from ENV)" do
ClimateControl.modify NODE_VERSION: "1.2.3" do
run_generator

assert_file app_root(".node-version") do |file|
assert_match(/1\.2\.3/, file)
end
end
end

test "generates .node-version file (from system)" do
Object.any_instance.stubs(:`).returns("v1.2.3\n")

run_generator

assert_file app_root(".node-version") do |file|
assert_match(/20\.11\.1/, file)
assert_match(/1\.2\.3/, file)
end
end

test "raises if Node is not installed" do
Object.any_instance.stubs(:`).returns("")

assert_raises Suspenders::Generators::NodeNotInstalled::Error do
run_generator
end

assert_no_file app_root(".node-version")
end

private

def restore_destination
Expand Down
4 changes: 3 additions & 1 deletion test/suspenders/cleanup/generate_readme_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ module Suspenders
module Cleanup
class GenerateReadmeTest < ActiveSupport::TestCase
test "generates README using generator descriptions" do
Object.any_instance.stubs(:`).returns("v1.2.3\n")

Tempfile.create "README.md" do |readme|
path = readme.path

Expand All @@ -18,7 +20,7 @@ class GenerateReadmeTest < ActiveSupport::TestCase

assert_match "## Prerequisites", readme
assert_match Suspenders::MINIMUM_RUBY_VERSION, readme
assert_match Suspenders::NODE_LTS_VERSION, readme
assert_match "Node: `1.2.3`", readme

assert_match "## Configuration", readme
assert_match "### Test", readme
Expand Down
4 changes: 0 additions & 4 deletions test/suspenders_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,4 @@ class SuspendersTest < ActiveSupport::TestCase
test "it has a Minimum Ruby version number" do
assert Suspenders::MINIMUM_RUBY_VERSION
end

test "it has a Node LTS version number" do
assert Suspenders::NODE_LTS_VERSION
end
end

0 comments on commit 7bf6e82

Please sign in to comment.