Skip to content

Commit

Permalink
Prerequisites: Use system version of Node
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 where 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 committed May 7, 2024
1 parent 4def0ae commit dd27fec
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 dd27fec

Please sign in to comment.