From 4cdbfd0c007f5e56aad0ded0e390eac87b39bd17 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 7 Sep 2026 11:55:15 +0000 Subject: [PATCH] Detect Yarn the same way the installer does MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two implementations decided whether Yarn installs an application's dependencies, and they disagreed. `EmberCli::App#yarn_enabled?` read the `yarn` option alone, while `EmberCli::PathSet#yarn?` — which `Shell#install` reaches through `PathSet#yarn` — also treated `yarn_path` as a request for Yarn. The Heroku generator asked the first one. An application configured with `yarn_path` alone therefore installed with Yarn everywhere the gem runs the installer, but got no root `yarn.lock` from `rails generate ember:heroku`, so Heroku's NodeJS buildpack — which picks the package manager by the lockfile it finds — fell back to npm for the same project. `App#yarn?` now delegates to `PathSet#yarn?`, leaving the installer as the single source of truth and the generator as one of its readers. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_014rAfkAVGVifbaEoTVeT66u --- CHANGELOG.md | 1 + lib/ember_cli/app.rb | 4 ++-- lib/ember_cli/path_set.rb | 8 +++---- .../ember/heroku/heroku_generator.rb | 2 +- spec/lib/ember_cli/app_spec.rb | 24 ++++++++++++++----- spec/lib/ember_cli/path_set_spec.rb | 22 +++++++++++++++++ 6 files changed, 48 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a3a8d31..b7860353 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ main ember:heroku`. Rails serves the twelve-factor behaviour the gem backported natively since `5.0`, and every Rails version this gem supports is `>= 5.2`. To upgrade, remove `rails_12factor` from your project's `Gemfile` +* Replace `EmberCli::App#yarn_enabled?` with `EmberCli::App#yarn?` 0.13.2 ------ diff --git a/lib/ember_cli/app.rb b/lib/ember_cli/app.rb index 23dff264..0349f3a2 100644 --- a/lib/ember_cli/app.rb +++ b/lib/ember_cli/app.rb @@ -91,8 +91,8 @@ def mountable? deploy.mountable? end - def yarn_enabled? - options.fetch(:yarn, false) + def yarn? + paths.yarn? end def bower? diff --git a/lib/ember_cli/path_set.rb b/lib/ember_cli/path_set.rb index 3a553d97..b14a2c5b 100644 --- a/lib/ember_cli/path_set.rb +++ b/lib/ember_cli/path_set.rb @@ -134,6 +134,10 @@ def node_modules @node_modules ||= root.join("node_modules") end + def yarn? + app_options[:yarn].present? || app_options[:yarn_path].present? + end + def tee @tee ||= path_for_executable("tee") end @@ -169,10 +173,6 @@ def package_manager end end - def yarn? - app_options[:yarn] || app_options[:yarn_path] - end - def app_name app.name end diff --git a/lib/generators/ember/heroku/heroku_generator.rb b/lib/generators/ember/heroku/heroku_generator.rb index cfcab36f..36717e35 100644 --- a/lib/generators/ember/heroku/heroku_generator.rb +++ b/lib/generators/ember/heroku/heroku_generator.rb @@ -9,7 +9,7 @@ def copy_package_json_file end def identify_as_yarn_project - if EmberCli.any?(&:yarn_enabled?) + if EmberCli.any?(&:yarn?) template "yarn.lock.erb", "yarn.lock" end end diff --git a/spec/lib/ember_cli/app_spec.rb b/spec/lib/ember_cli/app_spec.rb index a243fb68..3d906ab6 100644 --- a/spec/lib/ember_cli/app_spec.rb +++ b/spec/lib/ember_cli/app_spec.rb @@ -33,14 +33,12 @@ end end - describe "yarn_enabled?" do + describe "#yarn?" do context "when configured with yarn: true" do it "returns true" do app = EmberCli::App.new("with-yarn", yarn: true) - yarn_enabled = app.yarn_enabled? - - expect(yarn_enabled).to be true + expect(app.yarn?).to be true end end @@ -48,9 +46,23 @@ it "returns false" do app = EmberCli::App.new("without-yarn", yarn: false) - yarn_enabled = app.yarn_enabled? + expect(app.yarn?).to be false + end + end + + context "when configured with yarn_path alone" do + it "returns true, matching the executable the installer runs" do + app = EmberCli::App.new("with-yarn-path", yarn_path: "/usr/bin/yarn") + + expect(app.yarn?).to be true + end + end + + context "when configured with neither" do + it "returns false" do + app = EmberCli::App.new("without-yarn") - expect(yarn_enabled).to be false + expect(app.yarn?).to be false end end end diff --git a/spec/lib/ember_cli/path_set_spec.rb b/spec/lib/ember_cli/path_set_spec.rb index 2ca3eeaa..92d76ac6 100644 --- a/spec/lib/ember_cli/path_set_spec.rb +++ b/spec/lib/ember_cli/path_set_spec.rb @@ -212,6 +212,28 @@ end end + describe "#yarn?" do + it "is true when yarn is requested" do + app = build_app(options: { yarn: true }) + path_set = build_path_set(app: app) + + expect(path_set).to be_yarn + end + + it "is true when only the yarn executable is named" do + app = build_app(options: { yarn_path: "/usr/bin/yarn" }) + path_set = build_path_set(app: app) + + expect(path_set).to be_yarn + end + + it "is false when yarn is neither requested nor named" do + path_set = build_path_set + + expect(path_set).not_to be_yarn + end + end + describe "#yarn" do it "can be overridden" do fake_yarn = create_executable(ember_cli_root.join("yarn"))