forked from solidusio/solidus
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Deprecate solidus_frontend & allow installing solidus_starter_frontend
We're recommending new stores use solidus_starter_frontend [1] as their storefront. However, we still want to give the option to install solidus_frontend for now, as some extensions rely on it. We're modifying the Solidus installer to allow installing one or the other. Nonetheless, solidus_frontend is part of the solidus meta-gem [2], which is what is usually bundled in a new installation. At this point, we can't remove solidus_frontend from the meta-gem, as users upgrading from old Solidus versions could see their storefronts suddenly gone. As that will be a breaking change, we're deferring it until v4.0. Until that happens, we must prevent users choosing the new frontend from pulling solidus_frontend. Because of that, we're breaking down the solidus gem into solidus_core, solidus_api, solidus_backend & solidus_sample. We leverage Bundler's injector [3] to add dependencies matching the main solidus gem constraints in the Gemfile. We also use it to remove the meta-gem. Still, we need to extend the upstream injector to support the `path:` option, which is required for local testing (e.g., the sandbox application). We also must break down the meta-gem when solidus_frontend is installed until we remove the frontend directory from this repo. That prevents Bundler from resolving it from there when `path:` or `git:` are used as sources. As per the logic to detect which frontend gets installed, the first of the following conditions met wins: - It's explicitly selected with the `FRONTEND` environment variable (useful for sandbox applications). - It's explicitly selected with the `frontend` option. - If `solidus_frontend` is in the Gemfile, that's the one used. - If the `auto_accept` option is given, `solidus_starter_frontend` is chosen. - The user is prompted to select one or the other. Extensions have been modified to explicitly depend on `solidus_frontend` on their Gemfile, so the dummy app generator used for testing will work OOO matching the third condition. As per its sandbox application, they'll default to `solidus_starter_frontend` because they use `auto_accept`, but they can select `solidus_frontend` through the `FRONTEND` variable. [1] - https://github.com/solidusio/solidus_starter_frontend [2] - https://github.com/solidusio/solidus/blob/a22723079f88387f53f72b503db875b9d97aa3f5/solidus.gemspec#L27 [3] - https://github.com/rubygems/bundler/blob/master/lib/bundler/injector.rb
- Loading branch information
1 parent
9398ab9
commit ebfd2ed
Showing
7 changed files
with
255 additions
and
43 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
101 changes: 101 additions & 0 deletions
101
core/lib/generators/solidus/install/install_generator/bundler_context.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
# frozen_string_literal: true | ||
|
||
module Solidus | ||
class InstallGenerator < Rails::Generators::Base | ||
# Bundler context during the install process. | ||
# | ||
# This class gives access to information about the bundler context in which | ||
# the install generator is run. I.e., which solidus components are present | ||
# in the user's Gemfile. It also allows modifying the Gemfile to add or | ||
# remove gems. | ||
# | ||
# @api private | ||
class BundlerContext | ||
# Write and remove into a Gemfile, supporting the `path: ` option. | ||
# | ||
# This custom injector adds support for path sources, which is missing in | ||
# bundler's upstream injector. | ||
# | ||
# @api private | ||
class InjectorWithPathSupport < Bundler::Injector | ||
private def build_gem_lines(conservative_versioning) | ||
@deps.map do |d| | ||
name = d.name.dump | ||
local = d.source.is_a?(Bundler::Source::Path) | ||
|
||
requirement = if local | ||
", path: \"#{d.source.path}\"" | ||
elsif conservative_versioning | ||
", \"#{conservative_version(@definition.specs[d.name][0])}\"" | ||
else | ||
", #{d.requirement.as_list.map(&:dump).join(", ")}" | ||
end | ||
|
||
if d.groups != Array(:default) | ||
group = d.groups.size == 1 ? ", :group => #{d.groups.first.inspect}" : ", :groups => #{d.groups.inspect}" | ||
end | ||
|
||
source = ", :source => \"#{d.source}\"" unless local || d.source.nil? | ||
git = ", :git => \"#{d.git}\"" unless d.git.nil? | ||
branch = ", :branch => \"#{d.branch}\"" unless d.branch.nil? | ||
|
||
%(gem #{name}#{requirement}#{group}#{source}#{git}#{branch}) | ||
end.join("\n") | ||
end | ||
end | ||
|
||
attr_reader :dependencies, :injector | ||
|
||
def self.bundle_cleanly(&block) | ||
Bundler.respond_to?(:with_unbundled_env) ? Bundler.with_unbundled_env(&block) : Bundler.with_clean_env(&block) | ||
end | ||
|
||
def initialize | ||
@dependencies = Bundler.locked_gems.dependencies | ||
@injector = InjectorWithPathSupport | ||
end | ||
|
||
def solidus_in_gemfile? | ||
!solidus_dependency.nil? | ||
end | ||
|
||
def component_in_gemfile?(name) | ||
!@dependencies["solidus_#{name}"].nil? | ||
end | ||
|
||
def break_down_components(components) | ||
raise <<~MSG unless solidus_in_gemfile? | ||
solidus meta gem needs to be present in the Gemfile to build the component dependency | ||
MSG | ||
|
||
@injector.inject( | ||
components.map { |component| dependency_for_component(component) } | ||
) | ||
end | ||
|
||
def remove(*args, **kwargs, &block) | ||
@injector.remove(*args, **kwargs, &block) | ||
end | ||
|
||
private | ||
|
||
def dependency_for_component(component) | ||
Bundler::Dependency.new( | ||
"solidus_#{component}", | ||
solidus_dependency.requirement, | ||
{ | ||
"groups" => solidus_dependency.groups, | ||
"source" => solidus_dependency.source, | ||
"git" => solidus_dependency.git, | ||
"branch" => solidus_dependency.branch, | ||
"autorequire" => solidus_dependency.autorequire | ||
} | ||
) | ||
end | ||
|
||
def solidus_dependency | ||
@dependencies['solidus'] | ||
end | ||
end | ||
end | ||
end |
50 changes: 50 additions & 0 deletions
50
core/lib/generators/solidus/install/install_generator/install_frontend.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
# frozen_string_literal: true | ||
|
||
module Solidus | ||
class InstallGenerator < Rails::Generators::Base | ||
class InstallFrontend | ||
attr_reader :bundler_context, | ||
:generator_context | ||
|
||
def initialize(bundler_context:, generator_context:) | ||
@bundler_context = bundler_context | ||
@generator_context = generator_context | ||
end | ||
|
||
def call(frontend, installer_adds_auth:) | ||
case frontend | ||
when 'solidus_frontend' | ||
install_solidus_frontend | ||
when 'solidus_starter_frontend' | ||
install_solidus_starter_frontend(installer_adds_auth) | ||
end | ||
end | ||
|
||
private | ||
|
||
def install_solidus_frontend | ||
unless @bundler_context.component_in_gemfile?(:frontend) | ||
BundlerContext.bundle_cleanly do | ||
`bundle add solidus_frontend --source=https://rubygems.org` | ||
`bundle install` | ||
end | ||
end | ||
|
||
@generator_context.generate('solidus_frontend:install') | ||
end | ||
|
||
def install_solidus_starter_frontend(installer_adds_auth) | ||
@bundler_context.remove(['solidus_frontend']) if @bundler_context.component_in_gemfile?(:frontend) | ||
|
||
# TODO: Move installation of solidus_auth_devise to the | ||
# solidus_starter_frontend template | ||
BundlerContext.bundle_cleanly { `bundle add solidus_auth_devise` } unless auth_present?(installer_adds_auth) | ||
`LOCATION="https://raw.githubusercontent.com/solidusio/solidus_starter_frontend/main/template.rb" bin/rails app:template` | ||
end | ||
|
||
def auth_present?(installer_adds_auth) | ||
installer_adds_auth || @bundler_context.component_in_gemfile?(:auth_devise) | ||
end | ||
end | ||
end | ||
end |
48 changes: 48 additions & 0 deletions
48
core/lib/generators/solidus/install/install_generator/support_solidus_frontend_extraction.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
# frozen_string_literal: true | ||
|
||
module Solidus | ||
class InstallGenerator < Rails::Generators::Base | ||
# Helper for extracting solidus_frontend from solidus meta-gem | ||
# | ||
# We're recommending users use newer solidus_starter_frontend. However, | ||
# we're still shipping solidus_frontend as part of the solidus meta-gem. The | ||
# reason is that we don't want users updating previous versions to see its | ||
# storefront gone suddenly. | ||
# | ||
# In future solidus releases, solidus_frontend won't be a component anymore. | ||
# However, until that happens: | ||
# | ||
# - For users of the new frontend, we need to prevent pulling | ||
# solidus_frontend. | ||
# - For users of the legacy frontend, we need to prevent Bundler from | ||
# resolving it from the mono-repo while it's still there. | ||
# | ||
# This class is a needed companion during the deprecation | ||
# path. It'll modify the user's Gemfile, breaking the solidus gem down into | ||
# its components but solidus_frontend. | ||
class SupportSolidusFrontendExtraction | ||
attr_reader :bundler_context | ||
|
||
def initialize(bundler_context:) | ||
@bundler_context = bundler_context | ||
end | ||
|
||
def call | ||
return unless needs_to_break_down_solidus_meta_gem? | ||
|
||
break_down_solidus_meta_gem | ||
end | ||
|
||
private | ||
|
||
def break_down_solidus_meta_gem | ||
@bundler_context.break_down_components(%w[core backend api sample]) | ||
@bundler_context.remove(['solidus']) | ||
end | ||
|
||
def needs_to_break_down_solidus_meta_gem? | ||
@bundler_context.solidus_in_gemfile? | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
10 changes: 0 additions & 10 deletions
10
.../lib/generators/solidus/install/templates/vendor/assets/javascripts/spree/frontend/all.js
This file was deleted.
Oops, something went wrong.
9 changes: 0 additions & 9 deletions
9
...lib/generators/solidus/install/templates/vendor/assets/stylesheets/spree/frontend/all.css
This file was deleted.
Oops, something went wrong.