diff --git a/bundler/lib/bundler/cli/common.rb b/bundler/lib/bundler/cli/common.rb index cec7bcadb433..23ac78a103b8 100644 --- a/bundler/lib/bundler/cli/common.rb +++ b/bundler/lib/bundler/cli/common.rb @@ -14,6 +14,20 @@ def self.print_post_install_message(name, msg) Bundler.ui.info msg end + def self.output_fund_metadata_summary + definition = Bundler.definition + current_dependencies = definition.requested_dependencies + current_specs = definition.specs + + count = current_dependencies.count {|dep| current_specs[dep.name].first.metadata.key?("funding_uri") } + + return if count.zero? + + intro = count > 1 ? "#{count} installed gems you directly depend on are" : "#{count} installed gem you directly depend on is" + message = "#{intro} looking for funding.\n Run `bundle fund` for details" + Bundler.ui.info message + end + def self.output_without_groups_message(command) return if Bundler.settings[:without].empty? Bundler.ui.confirm without_groups_message(command) diff --git a/bundler/lib/bundler/cli/install.rb b/bundler/lib/bundler/cli/install.rb index 95066f53fac0..edf86fe1ba77 100644 --- a/bundler/lib/bundler/cli/install.rb +++ b/bundler/lib/bundler/cli/install.rb @@ -82,6 +82,8 @@ def run require_relative "clean" Bundler::CLI::Clean.new(options).run end + + Bundler::CLI::Common.output_fund_metadata_summary rescue GemNotFound, VersionConflict => e if options[:local] && Bundler.app_cache.exist? Bundler.ui.warn "Some gems seem to be missing from your #{Bundler.settings.app_cache_path} directory." diff --git a/bundler/lib/bundler/cli/update.rb b/bundler/lib/bundler/cli/update.rb index 529dd9c94d1c..ae908be65e95 100644 --- a/bundler/lib/bundler/cli/update.rb +++ b/bundler/lib/bundler/cli/update.rb @@ -106,6 +106,8 @@ def run Bundler.ui.confirm "Bundle updated!" Bundler::CLI::Common.output_without_groups_message(:update) Bundler::CLI::Common.output_post_install_messages installer.post_install_messages + + Bundler::CLI::Common.output_fund_metadata_summary end end end diff --git a/bundler/lib/bundler/definition.rb b/bundler/lib/bundler/definition.rb index dd7efd7565b9..fc35f31be16c 100644 --- a/bundler/lib/bundler/definition.rb +++ b/bundler/lib/bundler/definition.rb @@ -233,6 +233,12 @@ def requested_specs end end + def requested_dependencies + groups = requested_groups + groups.map!(&:to_sym) + dependencies_for(groups) + end + def current_dependencies dependencies.select do |d| d.should_include? && !d.gem_platforms(@platforms).empty? @@ -904,12 +910,6 @@ def expand_dependency_with_platforms(dep, platforms) end end - def requested_dependencies - groups = requested_groups - groups.map!(&:to_sym) - dependencies_for(groups) - end - def source_requirements # Load all specs from remote sources index diff --git a/bundler/spec/install/gems/fund_spec.rb b/bundler/spec/install/gems/fund_spec.rb new file mode 100644 index 000000000000..57e7c3aed393 --- /dev/null +++ b/bundler/spec/install/gems/fund_spec.rb @@ -0,0 +1,110 @@ +# frozen_string_literal: true + +RSpec.describe "bundle install" do + context "with gem sources" do + context "when gems include a fund URI" do + it "displays the plural fund message after installing" do + install_gemfile <<-G + source "#{file_uri_for(gem_repo1)}" + gem 'has_metadata' + gem 'has_funding' + gem 'rack-obama' + G + + expect(out).to include("2 installed gems you directly depend on are looking for funding.") + end + + it "displays the singular fund message after installing" do + install_gemfile <<-G + source "#{file_uri_for(gem_repo1)}" + gem 'has_funding' + gem 'rack-obama' + G + + expect(out).to include("1 installed gem you directly depend on is looking for funding.") + end + end + + context "when gems do not include fund messages" do + it "does not display any fund messages" do + install_gemfile <<-G + source "#{file_uri_for(gem_repo1)}" + gem "activesupport" + G + + expect(out).not_to include("gem you depend on") + end + end + + context "when a dependency includes a fund message" do + it "does not display the fund message" do + install_gemfile <<-G + source "#{file_uri_for(gem_repo1)}" + gem 'gem_with_dependent_funding' + G + + expect(out).not_to include("gem you depend on") + end + end + end + + context "with git sources" do + context "when gems include fund URI" do + it "displays the fund message after installing" do + build_git "also_has_funding" do |s| + s.metadata = { + "funding_uri" => "https://example.com/also_has_funding/funding", + } + end + install_gemfile <<-G + source "#{file_uri_for(gem_repo1)}" + gem 'also_has_funding', :git => '#{lib_path("also_has_funding-1.0")}' + G + + expect(out).to include("1 installed gem you directly depend on is looking for funding.") + end + + it "displays the fund message if repo is updated" do + build_git "also_has_funding" do |s| + s.metadata = { + "funding_uri" => "https://example.com/also_has_funding/funding", + } + end + install_gemfile <<-G + source "#{file_uri_for(gem_repo1)}" + gem 'also_has_funding', :git => '#{lib_path("also_has_funding-1.0")}' + G + + build_git "also_has_funding", "1.1" do |s| + s.metadata = { + "funding_uri" => "https://example.com/also_has_funding/funding", + } + end + install_gemfile <<-G + source "#{file_uri_for(gem_repo1)}" + gem 'also_has_funding', :git => '#{lib_path("also_has_funding-1.1")}' + G + + expect(out).to include("1 installed gem you directly depend on is looking for funding.") + end + + it "displays the fund message if repo is not updated" do + build_git "also_has_funding" do |s| + s.metadata = { + "funding_uri" => "https://example.com/also_has_funding/funding", + } + end + gemfile <<-G + source "#{file_uri_for(gem_repo1)}" + gem 'also_has_funding', :git => '#{lib_path("also_has_funding-1.0")}' + G + + bundle :install + expect(out).to include("1 installed gem you directly depend on is looking for funding.") + + bundle :install + expect(out).to include("1 installed gem you directly depend on is looking for funding.") + end + end + end +end diff --git a/bundler/spec/update/gems/fund_spec.rb b/bundler/spec/update/gems/fund_spec.rb new file mode 100644 index 000000000000..6d7075b42412 --- /dev/null +++ b/bundler/spec/update/gems/fund_spec.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +RSpec.describe "bundle update" do + before do + gemfile <<-G + source "#{file_uri_for(gem_repo1)}" + gem 'has_metadata' + gem 'has_funding', '< 2.0' + G + + bundle :install + end + + context "when listed gems are updated" do + before do + gemfile <<-G + source "#{file_uri_for(gem_repo1)}" + gem 'has_metadata' + gem 'has_funding' + G + + bundle :update, :all => true + end + + it "displays fund message" do + expect(out).to include("2 installed gems you directly depend on are looking for funding.") + end + end +end