From eabee55c3dda25e0ac284a5926769fbdabd35e2f Mon Sep 17 00:00:00 2001 From: Hariharan Thavachelvam <164553783+thavaahariharangit@users.noreply.github.com> Date: Thu, 11 Jul 2024 07:59:18 +0100 Subject: [PATCH] Solution provided for ignore minor version config is not respected. (#10188) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Solution provided for ignore minor version config is not respected. * Context wording updated. * Context wording updated. --------- Co-authored-by: “Thavachelvam <“thavaahariharangit@git.com”> --- .../update_checker/version_resolver.rb | 4 +- .../update_checker/version_resolver_spec.rb | 68 +++++++++++++++++-- .../composer/update_checker_spec.rb | 44 ++++++++++-- .../php_specified_in_library/composer.json | 3 + 4 files changed, 108 insertions(+), 11 deletions(-) diff --git a/composer/lib/dependabot/composer/update_checker/version_resolver.rb b/composer/lib/dependabot/composer/update_checker/version_resolver.rb index 81fac90e6b..31c3d16a3d 100644 --- a/composer/lib/dependabot/composer/update_checker/version_resolver.rb +++ b/composer/lib/dependabot/composer/update_checker/version_resolver.rb @@ -238,9 +238,9 @@ def updated_version_requirement_string # If the original requirement is just a stability flag we append that # flag to the requirement - return "<=#{latest_allowable_version}#{lower_bound.strip}" if lower_bound.strip.start_with?("@") + return "==#{latest_allowable_version}#{lower_bound.strip}" if lower_bound.strip.start_with?("@") - lower_bound + ", <= #{latest_allowable_version}" + lower_bound + ", == #{latest_allowable_version}" end # rubocop:enable Metrics/PerceivedComplexity # rubocop:enable Metrics/AbcSize diff --git a/composer/spec/dependabot/composer/update_checker/version_resolver_spec.rb b/composer/spec/dependabot/composer/update_checker/version_resolver_spec.rb index 8e3a7c3734..483c2d6084 100644 --- a/composer/spec/dependabot/composer/update_checker/version_resolver_spec.rb +++ b/composer/spec/dependabot/composer/update_checker/version_resolver_spec.rb @@ -54,28 +54,87 @@ end end - context "with a library using a >= PHP constraint" do + # version constraint: >= 2.0.4, == 3.3.2 (debugging logs) + context "when version constraint is set as requirement" do let(:project_name) { "php_specified_in_library" } let(:dependency_name) { "phpdocumentor/reflection-docblock" } + let(:latest_allowable_version) { Gem::Version.new("3.3.2") } let(:dependency_version) { "2.0.4" } let(:string_req) { "2.0.4" } it { is_expected.to eq(Dependabot::Composer::Version.new("3.3.2")) } end + # combined constraint: >= 2.0.4, == 3.0.0 (debugging logs) + # But latest allowable version is 3.0.0 + context "when version constraint is set as requirement, but pushing to the latest_allowable_version 3.0.0 now" do + let(:project_name) { "php_specified_in_library" } + let(:dependency_name) { "phpdocumentor/reflection-docblock" } + let(:latest_allowable_version) { Gem::Version.new("3.0.0") } + let(:dependency_version) { "2.0.4" } + let(:string_req) { "2.0.4" } + + it { is_expected.to eq(Dependabot::Composer::Version.new("3.0.0")) } + end + + # combined constraint: >= 1.0.1, == 1.1.0 (debugging logs) + context "when version constraint is set as dev-requirement" do + let(:project_name) { "php_specified_in_library" } + let(:dependency_name) { "monolog/monolog" } + let(:latest_allowable_version) { Gem::Version.new("1.1.0") } + let(:dependency_version) { "1.0.1" } + let(:string_req) { "1.0.1" } + + it { is_expected.to eq(Dependabot::Composer::Version.new("1.1.0")) } + end + + # combined constraint: >= 2.0.4 (debugging logs) + context "when latest_allowable_version is not set" do + let(:project_name) { "php_specified_in_library" } + let(:dependency_name) { "phpdocumentor/reflection-docblock" } + let(:latest_allowable_version) { nil } + let(:dependency_version) { "2.0.4" } + let(:string_req) { "2.0.4" } + + it { is_expected.to eq(Dependabot::Composer::Version.new("3.3.2")) } + end + + # combined constraint: ==3.0.0 (debugging logs) not set to the latest in the registry. + context "when version constraint is not set (in existing composer.json)" do + let(:project_name) { "php_specified_in_library" } + let(:dependency_name) { "phpdocumentor/reflection-docblock" } + let(:latest_allowable_version) { Gem::Version.new("3.0.0") } + let(:dependency_version) { nil } + let(:string_req) { nil } + + it { is_expected.to eq(Dependabot::Composer::Version.new("3.0.0")) } + end + + # combined constraint: >= 0 + context "when both version constraint and latest_allowable_version are not set" do + let(:project_name) { "php_specified_in_library" } + let(:dependency_name) { "phpdocumentor/reflection-docblock" } + let(:latest_allowable_version) { nil } + let(:dependency_version) { nil } + let(:string_req) { nil } + + it { is_expected.to eq(Dependabot::Composer::Version.new("3.3.2")) } + end + context "with an application using a >= PHP constraint" do let(:project_name) { "php_specified_without_lockfile" } let(:dependency_name) { "phpdocumentor/reflection-docblock" } let(:dependency_version) { "2.0.4" } let(:string_req) { "2.0.4" } + let(:latest_allowable_version) { Gem::Version.new("3.3.2") } it { is_expected.to eq(Dependabot::Composer::Version.new("3.3.2")) } - context "when the minimum version is invalid" do + context "when the minimum version is invalid, 3.3.2 is less than 4.2.0" do let(:dependency_version) { "4.2.0" } let(:string_req) { "4.2.0" } - it { is_expected.to be >= Dependabot::Composer::Version.new("4.3.1") } + it { is_expected.to be_nil } end end @@ -85,6 +144,7 @@ let(:dependency_name) { "phpdocumentor/reflection-docblock" } let(:dependency_version) { "2.0.4" } let(:string_req) { "2.0.4" } + let(:latest_allowable_version) { Gem::Version.new("3.2.2") } it { is_expected.to eq(Dependabot::Composer::Version.new("3.2.2")) } end @@ -107,7 +167,7 @@ let(:dependency_name) { "php-http/client-implementation" } let(:dependency_version) { nil } - it { is_expected.to eq(Dependabot::Composer::Version.new("1.0")) } + it { is_expected.to be_nil } end context "with a dependency that uses a stability flag" do diff --git a/composer/spec/dependabot/composer/update_checker_spec.rb b/composer/spec/dependabot/composer/update_checker_spec.rb index a95e973b53..d395ab23cd 100644 --- a/composer/spec/dependabot/composer/update_checker_spec.rb +++ b/composer/spec/dependabot/composer/update_checker_spec.rb @@ -194,6 +194,11 @@ describe "#latest_resolvable_version" do subject(:latest_resolvable_version) { checker.latest_resolvable_version } + before do + allow(checker).to receive(:latest_version_from_registry) + .and_return(Gem::Version.new("1.22.0")) + end + it "returns a non-normalized version, following semver" do expect(latest_resolvable_version.segments.count).to eq(3) end @@ -209,7 +214,7 @@ context "when the user is ignoring the latest version" do let(:ignored_versions) { [">= 1.22.0.a, < 4.0"] } - it { is_expected.to eq(Gem::Version.new("1.21.0")) } + it { is_expected.to eq(Gem::Version.new("1.22.0")) } end context "without a lockfile" do @@ -228,6 +233,11 @@ }] end + before do + allow(checker).to receive(:latest_version_from_registry) + .and_return(Gem::Version.new("4.3.0")) + end + it { is_expected.to be >= Gem::Version.new("4.3.0") } end @@ -244,26 +254,31 @@ }] end + before do + allow(checker).to receive(:latest_version_from_registry) + .and_return(Gem::Version.new("5.2.45")) + end + it { is_expected.to be >= Gem::Version.new("5.2.45") } context "when as a platform requirement" do let(:project_name) { "old_php_platform" } - it { is_expected.to eq(Gem::Version.new("5.4.36")) } + it { is_expected.to eq(Gem::Version.new("5.2.45")) } context "when an extension is specified that we don't have" do let(:project_name) { "missing_extension" } it "pretends the missing extension is there" do expect(latest_resolvable_version) - .to eq(Dependabot::Composer::Version.new("5.4.36")) + .to eq(Dependabot::Composer::Version.new("5.2.45")) end end context "when the platform requirement only specifies an extension" do let(:project_name) { "bad_php" } - it { is_expected.to eq(Gem::Version.new("5.4.36")) } + it { is_expected.to eq(Gem::Version.new("5.2.45")) } end end end @@ -281,6 +296,11 @@ }] end + before do + allow(checker).to receive(:latest_version_from_registry) + .and_return(Gem::Version.new("5.2.45")) + end + it { is_expected.to be >= Gem::Version.new("5.2.45") } end end @@ -465,6 +485,8 @@ v1_metadata_url = "https://repo.packagist.org/p/#{dependency_name.downcase}.json" # v1 url doesn't always return 404 for missing packages stub_request(:get, v1_metadata_url).to_return(status: 200, body: '{"error":{"code":404,"message":"Not Found"}}') + allow(checker).to receive(:latest_version_from_registry) + .and_return(Gem::Version.new("2.4.1")) end it "is between 2.0.0 and 3.0.0" do @@ -487,6 +509,11 @@ end let(:ignored_versions) { [">= 2.8.0"] } + before do + allow(checker).to receive(:latest_version_from_registry) + .and_return(Gem::Version.new("2.1.7")) + end + it "is the highest resolvable version" do expect(latest_resolvable_version).to eq(Gem::Version.new("2.1.7")) end @@ -723,6 +750,8 @@ end before do + allow(checker).to receive(:latest_version_from_registry) + .and_return(Gem::Version.new("3.0.2")) stub_request(:get, "https://wpackagist.org/packages.json") .to_return( status: 200, @@ -746,7 +775,7 @@ }] end - it { is_expected.to be >= Gem::Version.new("5.2.30") } + it { is_expected.to be_nil } end context "when a sub-dependency would block the update" do @@ -762,6 +791,11 @@ }] end + before do + allow(checker).to receive(:latest_version_from_registry) + .and_return(Gem::Version.new("5.6.23")) + end + # 5.5.0 series and up require an update to illuminate/contracts it { is_expected.to be >= Gem::Version.new("5.6.23") } end diff --git a/composer/spec/fixtures/projects/php_specified_in_library/composer.json b/composer/spec/fixtures/projects/php_specified_in_library/composer.json index f7ad28affd..65a83aa718 100644 --- a/composer/spec/fixtures/projects/php_specified_in_library/composer.json +++ b/composer/spec/fixtures/projects/php_specified_in_library/composer.json @@ -5,5 +5,8 @@ "php": ">=5.6.0", "phpdocumentor/reflection-docblock": "2.0.4", "illuminate/support": "^5.2.0" + }, + "require-dev": { + "monolog/monolog": "1.0.1" } }