From 7fd6ffb0c58f13c1a2616f90be563ea0c181f1a8 Mon Sep 17 00:00:00 2001 From: Tim Van Holder Date: Sat, 12 Dec 2020 16:00:26 +0100 Subject: [PATCH 1/6] Add parsing of MSBuild SDK dependencies (NuGet) This adds the three ways to specify an MSBuild SDK reference inside a project file, including test cases for each. --- .../nuget/file_parser/project_file_parser.rb | 62 ++++++++++ .../file_parser/project_file_parser_spec.rb | 116 ++++++++++++++++++ .../csproj/sdk_reference_via_import.csproj | 11 ++ .../csproj/sdk_reference_via_project.csproj | 7 ++ .../csproj/sdk_reference_via_sdk.csproj | 11 ++ 5 files changed, 207 insertions(+) create mode 100644 nuget/spec/fixtures/csproj/sdk_reference_via_import.csproj create mode 100644 nuget/spec/fixtures/csproj/sdk_reference_via_project.csproj create mode 100644 nuget/spec/fixtures/csproj/sdk_reference_via_sdk.csproj diff --git a/nuget/lib/dependabot/nuget/file_parser/project_file_parser.rb b/nuget/lib/dependabot/nuget/file_parser/project_file_parser.rb index f3cc707ed62..715e43cb793 100644 --- a/nuget/lib/dependabot/nuget/file_parser/project_file_parser.rb +++ b/nuget/lib/dependabot/nuget/file_parser/project_file_parser.rb @@ -20,6 +20,7 @@ class ProjectFileParser "ItemGroup > Dependency, "\ "ItemGroup > DevelopmentDependency" + PROJECT_SDK_REGEX = %r{^([^/]+)/(\d+(?:[.]\d+(?:[.]\d+)?)?(?:[+-].*)?)$}.freeze PROPERTY_REGEX = /\$\((?.*?)\)/.freeze ITEM_REGEX = /\@\((?.*?)\)/.freeze @@ -32,6 +33,7 @@ def dependency_set(project_file:) doc = Nokogiri::XML(project_file.content) doc.remove_namespaces! + # Look for regular package references doc.css(DEPENDENCY_SELECTOR).each do |dependency_node| name = dependency_name(dependency_node, project_file) req = dependency_requirement(dependency_node, project_file) @@ -42,6 +44,9 @@ def dependency_set(project_file:) build_dependency(name, req, version, prop_name, project_file) dependency_set << dependency if dependency end + # Look for SDK references; see: + # https://docs.microsoft.com/en-us/visualstudio/msbuild/how-to-use-project-sdk + add_sdk_references(doc, dependency_set, project_file) dependency_set end @@ -50,6 +55,63 @@ def dependency_set(project_file:) attr_reader :dependency_files + def add_sdk_references(doc, dependency_set, project_file) + # These come in 3 flavours: + # - + # - + # - + # None of these support the use of properties, nor do they allow child + # elements instead of attributes. + add_sdk_refs_from_project(doc, dependency_set, project_file) + add_sdk_refs_from_sdk_tags(doc, dependency_set, project_file) + add_sdk_refs_from_import_tags(doc, dependency_set, project_file) + end + + def add_sdk_ref_from_project(sdk_references, dependency_set, project_file) + sdk_references.split(";")&.each do |sdk_reference| + m = sdk_reference.match(PROJECT_SDK_REGEX) + if m + dependency = build_dependency(m[1], m[2], m[2], nil, project_file) + dependency_set << dependency if dependency + end + end + end + + def add_sdk_refs_from_import_tags(doc, dependency_set, project_file) + doc.xpath("/Project/Import").each do |import_node| + next unless import_node.attribute("Sdk") && import_node.attribute("Version") + + name = import_node.attribute("Sdk")&.value&.strip + version = import_node.attribute("Version")&.value&.strip + + dependency = + build_dependency(name, version, version, nil, project_file) + dependency_set << dependency if dependency + end + end + + def add_sdk_refs_from_project(doc, dependency_set, project_file) + doc.xpath("/Project").each do |project_node| + sdk_references = project_node.attribute("Sdk")&.value&.strip + next unless sdk_references + + add_sdk_ref_from_project(sdk_references, dependency_set, project_file) + end + end + + def add_sdk_refs_from_sdk_tags(doc, dependency_set, project_file) + doc.xpath("/Project/Sdk").each do |sdk_node| + next unless sdk_node.attribute("Version") + + name = sdk_node.attribute("Name")&.value&.strip + version = sdk_node.attribute("Version")&.value&.strip + + dependency = + build_dependency(name, version, version, nil, project_file) + dependency_set << dependency if dependency + end + end + def build_dependency(name, req, version, prop_name, project_file) return unless name diff --git a/nuget/spec/dependabot/nuget/file_parser/project_file_parser_spec.rb b/nuget/spec/dependabot/nuget/file_parser/project_file_parser_spec.rb index 6b2c1178c75..36ea025aa78 100644 --- a/nuget/spec/dependabot/nuget/file_parser/project_file_parser_spec.rb +++ b/nuget/spec/dependabot/nuget/file_parser/project_file_parser_spec.rb @@ -244,6 +244,122 @@ expect(dependencies.count).to eq(0) end end + + context "with a versioned sdk reference" do + context "specified in the Project tag" do + let(:file_body) { fixture("csproj", "sdk_reference_via_project.csproj") } + + its(:length) { is_expected.to eq(2) } + + describe "the first dependency" do + subject(:dependency) { dependencies.first } + + it "has the right details" do + expect(dependency).to be_a(Dependabot::Dependency) + expect(dependency.name).to eq("Awesome.Sdk") + expect(dependency.version).to eq("1.2.3") + expect(dependency.requirements).to eq([{ + requirement: "1.2.3", + file: "my.csproj", + groups: [], + source: nil + }]) + end + end + + describe "the second dependency" do + subject(:dependency) { dependencies[1] } + + it "has the right details" do + expect(dependency).to be_a(Dependabot::Dependency) + expect(dependency.name).to eq("Prototype.Sdk") + expect(dependency.version).to eq("0.1.0-beta") + expect(dependency.requirements).to eq([{ + requirement: "0.1.0-beta", + file: "my.csproj", + groups: [], + source: nil + }]) + end + end + end + + context "specified via an Sdk tag" do + let(:file_body) { fixture("csproj", "sdk_reference_via_sdk.csproj") } + + its(:length) { is_expected.to eq(2) } + + describe "the first dependency" do + subject(:dependency) { dependencies.first } + + it "has the right details" do + expect(dependency).to be_a(Dependabot::Dependency) + expect(dependency.name).to eq("Awesome.Sdk") + expect(dependency.version).to eq("1.2.3") + expect(dependency.requirements).to eq([{ + requirement: "1.2.3", + file: "my.csproj", + groups: [], + source: nil + }]) + end + end + + describe "the second dependency" do + subject(:dependency) { dependencies[1] } + + it "has the right details" do + expect(dependency).to be_a(Dependabot::Dependency) + expect(dependency.name).to eq("Prototype.Sdk") + expect(dependency.version).to eq("0.1.0-beta") + expect(dependency.requirements).to eq([{ + requirement: "0.1.0-beta", + file: "my.csproj", + groups: [], + source: nil + }]) + end + end + end + + context "specified via an Import tag" do + let(:file_body) { fixture("csproj", "sdk_reference_via_import.csproj") } + + its(:length) { is_expected.to eq(2) } + + describe "the first dependency" do + subject(:dependency) { dependencies.first } + + it "has the right details" do + expect(dependency).to be_a(Dependabot::Dependency) + expect(dependency.name).to eq("Awesome.Sdk") + expect(dependency.version).to eq("1.2.3") + expect(dependency.requirements).to eq([{ + requirement: "1.2.3", + file: "my.csproj", + groups: [], + source: nil + }]) + end + end + + describe "the second dependency" do + subject(:dependency) { dependencies[1] } + + it "has the right details" do + expect(dependency).to be_a(Dependabot::Dependency) + expect(dependency.name).to eq("Prototype.Sdk") + expect(dependency.version).to eq("0.1.0-beta") + expect(dependency.requirements).to eq([{ + requirement: "0.1.0-beta", + file: "my.csproj", + groups: [], + source: nil + }]) + end + end + end + end end end end diff --git a/nuget/spec/fixtures/csproj/sdk_reference_via_import.csproj b/nuget/spec/fixtures/csproj/sdk_reference_via_import.csproj new file mode 100644 index 00000000000..eb353e4959c --- /dev/null +++ b/nuget/spec/fixtures/csproj/sdk_reference_via_import.csproj @@ -0,0 +1,11 @@ + + + + + + Very simple project using a custom SDK. + + + + + diff --git a/nuget/spec/fixtures/csproj/sdk_reference_via_project.csproj b/nuget/spec/fixtures/csproj/sdk_reference_via_project.csproj new file mode 100644 index 00000000000..054fdb003f5 --- /dev/null +++ b/nuget/spec/fixtures/csproj/sdk_reference_via_project.csproj @@ -0,0 +1,7 @@ + + + + Very simple project using a custom SDK. + + + diff --git a/nuget/spec/fixtures/csproj/sdk_reference_via_sdk.csproj b/nuget/spec/fixtures/csproj/sdk_reference_via_sdk.csproj new file mode 100644 index 00000000000..8359f9ccc55 --- /dev/null +++ b/nuget/spec/fixtures/csproj/sdk_reference_via_sdk.csproj @@ -0,0 +1,11 @@ + + + + + + Very simple project using a custom SDK. + + + + + From a7452c69c30f2641e60817cb65d93c8ebbb5606a Mon Sep 17 00:00:00 2001 From: Tim Van Holder Date: Sun, 13 Dec 2020 02:13:18 +0100 Subject: [PATCH 2/6] Implement updating of MSBuild SDK references This should cover all three forms and complete #2839. Tests are included. For the specification in the Sdk attribute of the Project element, this results in replacements like "Foo.Bar/1.1.1" -> "Foo.Bar/1.2.3". There are short/generic enough to have the potential for false positives. Perhaps this case needs to be handled at the file_updater level instead, so that it can register a change of 'Sdk="Number.One/1.0.0;Number.Two/1.0.0"' to 'Sdk="Number.One/1.1.1;Number.Two/2.2.2"' in one go. --- .../project_file_declaration_finder.rb | 90 +++++++++++++++++++ .../dependabot/nuget/file_updater_spec.rb | 43 +++++++++ .../csproj/sdk_references_of_all_kinds.csproj | 13 +++ 3 files changed, 146 insertions(+) create mode 100644 nuget/spec/fixtures/csproj/sdk_references_of_all_kinds.csproj diff --git a/nuget/lib/dependabot/nuget/file_updater/project_file_declaration_finder.rb b/nuget/lib/dependabot/nuget/file_updater/project_file_declaration_finder.rb index 2dd9f782dfa..725af953d52 100644 --- a/nuget/lib/dependabot/nuget/file_updater/project_file_declaration_finder.rb +++ b/nuget/lib/dependabot/nuget/file_updater/project_file_declaration_finder.rb @@ -20,6 +20,17 @@ class ProjectFileDeclarationFinder ]*?/>| ]*?[^/]>.*? }mx.freeze + SDK_IMPORT_REGEX = + / ]*?Sdk="[^"]*?"[^>]*?Version="[^"]*?"[^>]*?> + | ]*?Version="[^"]*?"[^>]*?Sdk="[^"]*?"[^>]*?> + /mx.freeze + SDK_PROJECT_REGEX = + / ]*?Sdk="[^"]*?"[^>]*?> + /mx.freeze + SDK_SDK_REGEX = + / ]*?Name="[^"]*?"[^>]*?Version="[^"]*?"[^>]*?> + | ]*?Version="[^"]*?"[^>]*?Name="[^"]*?"[^>]*?> + /mx.freeze attr_reader :dependency_name, :declaring_requirement, :dependency_files @@ -33,6 +44,7 @@ def initialize(dependency_name:, dependency_files:, def declaration_strings @declaration_strings ||= fetch_declaration_strings + @declaration_strings += fetch_sdk_strings end def declaration_nodes @@ -72,6 +84,10 @@ def fetch_declaration_strings # rubocop:enable Metrics/PerceivedComplexity # rubocop:enable Metrics/CyclomaticComplexity + def fetch_sdk_strings + sdk_project_strings + sdk_sdk_strings + sdk_import_strings + end + # rubocop:disable Metrics/PerceivedComplexity def get_node_version_value(node) attribute = "Version" @@ -95,6 +111,80 @@ def declaring_file raise "No file found with name #{filename}!" end + + def sdk_import_strings + sdk_strings(SDK_IMPORT_REGEX, "Import", "Sdk", "Version") + end + + # rubocop:disable Metrics/PerceivedComplexity + def sdk_project_strings + dep_name = dependency_name&.downcase + dep_version = declaring_requirement.fetch(:requirement) + strings = [] + declaring_file.content.scan(SDK_PROJECT_REGEX).each do |string| + xml = string + xml += "" unless string.end_with?("/>") + node = Nokogiri::XML(xml) + node.remove_namespaces! + element = node.at_xpath("/Project") + next unless element + + sdk_references = element.attribute("Sdk")&.value || + element.attribute("sdk")&.value + sdk_references = sdk_references&.strip + next unless sdk_references&.include?("/") + + sdk_references.split(";").each do |sdk_reference| + parts = sdk_reference.split("/") + next unless parts.length == 2 + next unless parts[0]&.downcase == dep_name + next unless parts[1] == dep_version + + strings << sdk_reference + end + end + # Drop duplicates, to avoid potential issues with repeated replacements (e.g. upgrading Foo/1.0.0-beta to + # Foo/1.0.0-beta.2). However, that turns the empty array into nil. + strings.uniq! || [] + end + # rubocop:enable Metrics/PerceivedComplexity + + def sdk_sdk_strings + sdk_strings(SDK_SDK_REGEX, "Sdk", "Name", "Version") + end + + # rubocop:disable Metrics/CyclomaticComplexity + # rubocop:disable Metrics/PerceivedComplexity + def sdk_strings(regex, element_name, name_attribute, version_attribute) + dep_name = dependency_name&.downcase + dep_version = declaring_requirement.fetch(:requirement) + strings = [] + declaring_file.content.scan(regex).each do |string| + xml = string + xml += "" unless string.end_with?("/>") + node = Nokogiri::XML(xml) + node.remove_namespaces! + element = node.at_xpath("/#{element_name}") + next unless element + + node_name = + element.attribute(name_attribute)&.value || + element.attribute(name_attribute.downcase)&.value + node_name = node_name&.strip&.downcase + next unless node_name == dep_name + + node_version = + element.attribute(version_attribute)&.value || + element.attribute(version_attribute.downcase)&.value + node_version = node_version&.strip + next unless node_version == dep_version + + strings << string + end + strings + end + # rubocop:enable Metrics/CyclomaticComplexity + # rubocop:enable Metrics/PerceivedComplexity end end end diff --git a/nuget/spec/dependabot/nuget/file_updater_spec.rb b/nuget/spec/dependabot/nuget/file_updater_spec.rb index 33d48547d37..32d69ea67dd 100644 --- a/nuget/spec/dependabot/nuget/file_updater_spec.rb +++ b/nuget/spec/dependabot/nuget/file_updater_spec.rb @@ -135,6 +135,49 @@ ) end end + + context "with MSBuild SDKs" do + let(:csproj_body) do + fixture("csproj", "sdk_references_of_all_kinds.csproj") + end + let(:dependency_name) { "Foo.Bar" } + let(:version) { "1.2.3" } + let(:previous_version) { "1.1.1" } + let(:requirements) do + [{ + requirement: "1.2.3", + file: "my.csproj", + groups: [], + source: nil + }] + end + let(:previous_requirements) do + [{ + requirement: "1.1.1", + file: "my.csproj", + groups: [], + source: nil + }] + end + + it "updates the project correctly" do + content = updated_csproj_file.content + # Sdk attribute on Project (front, middle, back) + expect(content).to include(%(Sdk="Foo.Bar/1.2.3;)) + expect(content).to include(%(X;Foo.Bar/1.2.3;Y)) + expect(content).to include(%(Y;Foo.Bar/1.2.3">)) + # Sdk tag (name/version and version/name) + expect(content).to include(%( + + + + + + MSBuild SDKs Galore! + + + + + + From e298bf41c697e7cf80d495f8a20a78c42fe7b5be Mon Sep 17 00:00:00 2001 From: Tim Van Holder Date: Thu, 11 Nov 2021 22:42:56 +0100 Subject: [PATCH 3/6] Apply suggested code tweaks --- .../nuget/file_parser/project_file_parser.rb | 9 +++------ .../file_updater/project_file_declaration_finder.rb | 10 +++------- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/nuget/lib/dependabot/nuget/file_parser/project_file_parser.rb b/nuget/lib/dependabot/nuget/file_parser/project_file_parser.rb index 715e43cb793..8e53432a5cb 100644 --- a/nuget/lib/dependabot/nuget/file_parser/project_file_parser.rb +++ b/nuget/lib/dependabot/nuget/file_parser/project_file_parser.rb @@ -40,8 +40,7 @@ def dependency_set(project_file:) version = dependency_version(dependency_node, project_file) prop_name = req_property_name(dependency_node) - dependency = - build_dependency(name, req, version, prop_name, project_file) + dependency = build_dependency(name, req, version, prop_name, project_file) dependency_set << dependency if dependency end # Look for SDK references; see: @@ -84,8 +83,7 @@ def add_sdk_refs_from_import_tags(doc, dependency_set, project_file) name = import_node.attribute("Sdk")&.value&.strip version = import_node.attribute("Version")&.value&.strip - dependency = - build_dependency(name, version, version, nil, project_file) + dependency = build_dependency(name, version, version, nil, project_file) dependency_set << dependency if dependency end end @@ -106,8 +104,7 @@ def add_sdk_refs_from_sdk_tags(doc, dependency_set, project_file) name = sdk_node.attribute("Name")&.value&.strip version = sdk_node.attribute("Version")&.value&.strip - dependency = - build_dependency(name, version, version, nil, project_file) + dependency = build_dependency(name, version, version, nil, project_file) dependency_set << dependency if dependency end end diff --git a/nuget/lib/dependabot/nuget/file_updater/project_file_declaration_finder.rb b/nuget/lib/dependabot/nuget/file_updater/project_file_declaration_finder.rb index 725af953d52..38a562f34f2 100644 --- a/nuget/lib/dependabot/nuget/file_updater/project_file_declaration_finder.rb +++ b/nuget/lib/dependabot/nuget/file_updater/project_file_declaration_finder.rb @@ -121,8 +121,7 @@ def sdk_project_strings dep_name = dependency_name&.downcase dep_version = declaring_requirement.fetch(:requirement) strings = [] - declaring_file.content.scan(SDK_PROJECT_REGEX).each do |string| - xml = string + declaring_file.content.scan(SDK_PROJECT_REGEX).each do |xml| xml += "" unless string.end_with?("/>") node = Nokogiri::XML(xml) node.remove_namespaces! @@ -143,9 +142,7 @@ def sdk_project_strings strings << sdk_reference end end - # Drop duplicates, to avoid potential issues with repeated replacements (e.g. upgrading Foo/1.0.0-beta to - # Foo/1.0.0-beta.2). However, that turns the empty array into nil. - strings.uniq! || [] + strings.uniq end # rubocop:enable Metrics/PerceivedComplexity @@ -159,8 +156,7 @@ def sdk_strings(regex, element_name, name_attribute, version_attribute) dep_name = dependency_name&.downcase dep_version = declaring_requirement.fetch(:requirement) strings = [] - declaring_file.content.scan(regex).each do |string| - xml = string + declaring_file.content.scan(regex).each do |xml| xml += "" unless string.end_with?("/>") node = Nokogiri::XML(xml) node.remove_namespaces! From 8f0bf71b0067ad31cddd73aa343991c6a2f6f5c7 Mon Sep 17 00:00:00 2001 From: Tim Van Holder Date: Thu, 11 Nov 2021 22:50:01 +0100 Subject: [PATCH 4/6] Fix variable references --- .../nuget/file_updater/project_file_declaration_finder.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nuget/lib/dependabot/nuget/file_updater/project_file_declaration_finder.rb b/nuget/lib/dependabot/nuget/file_updater/project_file_declaration_finder.rb index 38a562f34f2..d5e2e206162 100644 --- a/nuget/lib/dependabot/nuget/file_updater/project_file_declaration_finder.rb +++ b/nuget/lib/dependabot/nuget/file_updater/project_file_declaration_finder.rb @@ -122,7 +122,7 @@ def sdk_project_strings dep_version = declaring_requirement.fetch(:requirement) strings = [] declaring_file.content.scan(SDK_PROJECT_REGEX).each do |xml| - xml += "" unless string.end_with?("/>") + xml += "" unless xml.end_with?("/>") node = Nokogiri::XML(xml) node.remove_namespaces! element = node.at_xpath("/Project") @@ -157,7 +157,7 @@ def sdk_strings(regex, element_name, name_attribute, version_attribute) dep_version = declaring_requirement.fetch(:requirement) strings = [] declaring_file.content.scan(regex).each do |xml| - xml += "" unless string.end_with?("/>") + xml += "" unless xml.end_with?("/>") node = Nokogiri::XML(xml) node.remove_namespaces! element = node.at_xpath("/#{element_name}") @@ -175,7 +175,7 @@ def sdk_strings(regex, element_name, name_attribute, version_attribute) node_version = node_version&.strip next unless node_version == dep_version - strings << string + strings << xml end strings end From bfa52c4fac41682b09553679f2521cc2f2fd039a Mon Sep 17 00:00:00 2001 From: Tim Van Holder Date: Thu, 11 Nov 2021 23:56:14 +0100 Subject: [PATCH 5/6] Refactor code to reduce complexity This also reverts a previous incorrect change. With this, rubocop is happy and the tests still pass. --- .../project_file_declaration_finder.rb | 63 +++++++++---------- 1 file changed, 29 insertions(+), 34 deletions(-) diff --git a/nuget/lib/dependabot/nuget/file_updater/project_file_declaration_finder.rb b/nuget/lib/dependabot/nuget/file_updater/project_file_declaration_finder.rb index d5e2e206162..ff27195e775 100644 --- a/nuget/lib/dependabot/nuget/file_updater/project_file_declaration_finder.rb +++ b/nuget/lib/dependabot/nuget/file_updater/project_file_declaration_finder.rb @@ -116,71 +116,66 @@ def sdk_import_strings sdk_strings(SDK_IMPORT_REGEX, "Import", "Sdk", "Version") end - # rubocop:disable Metrics/PerceivedComplexity + def parse_element(string, name) + xml = string + xml += "" unless string.end_with?("/>") + node = Nokogiri::XML(xml) + node.remove_namespaces! + node.at_xpath("/#{name}") + end + + def get_attribute_value_nocase(element, name) + value = element.attribute(name)&.value || + element.attribute(name.downcase)&.value || + element.attribute(name.upcase)&.value + value&.strip + end + + def desired_sdk_reference?(sdk_reference, dep_name, dep_version) + parts = sdk_reference.split("/") + parts.length == 2 && parts[0]&.downcase == dep_name && parts[1] == dep_version + end + def sdk_project_strings dep_name = dependency_name&.downcase dep_version = declaring_requirement.fetch(:requirement) strings = [] - declaring_file.content.scan(SDK_PROJECT_REGEX).each do |xml| - xml += "" unless xml.end_with?("/>") - node = Nokogiri::XML(xml) - node.remove_namespaces! - element = node.at_xpath("/Project") + declaring_file.content.scan(SDK_PROJECT_REGEX).each do |string| + element = parse_element(string, "Project") next unless element - sdk_references = element.attribute("Sdk")&.value || - element.attribute("sdk")&.value - sdk_references = sdk_references&.strip + sdk_references = get_attribute_value_nocase(element, "Sdk") next unless sdk_references&.include?("/") sdk_references.split(";").each do |sdk_reference| - parts = sdk_reference.split("/") - next unless parts.length == 2 - next unless parts[0]&.downcase == dep_name - next unless parts[1] == dep_version - - strings << sdk_reference + strings << sdk_reference if desired_sdk_reference?(sdk_reference, dep_name, dep_version) end end strings.uniq end - # rubocop:enable Metrics/PerceivedComplexity def sdk_sdk_strings sdk_strings(SDK_SDK_REGEX, "Sdk", "Name", "Version") end - # rubocop:disable Metrics/CyclomaticComplexity - # rubocop:disable Metrics/PerceivedComplexity def sdk_strings(regex, element_name, name_attribute, version_attribute) dep_name = dependency_name&.downcase dep_version = declaring_requirement.fetch(:requirement) strings = [] - declaring_file.content.scan(regex).each do |xml| - xml += "" unless xml.end_with?("/>") - node = Nokogiri::XML(xml) - node.remove_namespaces! - element = node.at_xpath("/#{element_name}") + declaring_file.content.scan(regex).each do |string| + element = parse_element(string, element_name) next unless element - node_name = - element.attribute(name_attribute)&.value || - element.attribute(name_attribute.downcase)&.value - node_name = node_name&.strip&.downcase + node_name = get_attribute_value_nocase(element, name_attribute)&.downcase next unless node_name == dep_name - node_version = - element.attribute(version_attribute)&.value || - element.attribute(version_attribute.downcase)&.value - node_version = node_version&.strip + node_version = get_attribute_value_nocase(element, version_attribute) next unless node_version == dep_version - strings << xml + strings << string end strings end - # rubocop:enable Metrics/CyclomaticComplexity - # rubocop:enable Metrics/PerceivedComplexity end end end From a97dc626f27d74fa39418e52994d343a7d956b22 Mon Sep 17 00:00:00 2001 From: Tim Van Holder Date: Mon, 15 Nov 2021 20:27:20 +0100 Subject: [PATCH 6/6] Adjust indentation to please rubocop --- .../file_parser/project_file_parser_spec.rb | 60 +++++++++---------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/nuget/spec/dependabot/nuget/file_parser/project_file_parser_spec.rb b/nuget/spec/dependabot/nuget/file_parser/project_file_parser_spec.rb index 36ea025aa78..8c43fb2c3fb 100644 --- a/nuget/spec/dependabot/nuget/file_parser/project_file_parser_spec.rb +++ b/nuget/spec/dependabot/nuget/file_parser/project_file_parser_spec.rb @@ -259,11 +259,11 @@ expect(dependency.name).to eq("Awesome.Sdk") expect(dependency.version).to eq("1.2.3") expect(dependency.requirements).to eq([{ - requirement: "1.2.3", - file: "my.csproj", - groups: [], - source: nil - }]) + requirement: "1.2.3", + file: "my.csproj", + groups: [], + source: nil + }]) end end @@ -275,11 +275,11 @@ expect(dependency.name).to eq("Prototype.Sdk") expect(dependency.version).to eq("0.1.0-beta") expect(dependency.requirements).to eq([{ - requirement: "0.1.0-beta", - file: "my.csproj", - groups: [], - source: nil - }]) + requirement: "0.1.0-beta", + file: "my.csproj", + groups: [], + source: nil + }]) end end end @@ -297,11 +297,11 @@ expect(dependency.name).to eq("Awesome.Sdk") expect(dependency.version).to eq("1.2.3") expect(dependency.requirements).to eq([{ - requirement: "1.2.3", - file: "my.csproj", - groups: [], - source: nil - }]) + requirement: "1.2.3", + file: "my.csproj", + groups: [], + source: nil + }]) end end @@ -313,11 +313,11 @@ expect(dependency.name).to eq("Prototype.Sdk") expect(dependency.version).to eq("0.1.0-beta") expect(dependency.requirements).to eq([{ - requirement: "0.1.0-beta", - file: "my.csproj", - groups: [], - source: nil - }]) + requirement: "0.1.0-beta", + file: "my.csproj", + groups: [], + source: nil + }]) end end end @@ -335,11 +335,11 @@ expect(dependency.name).to eq("Awesome.Sdk") expect(dependency.version).to eq("1.2.3") expect(dependency.requirements).to eq([{ - requirement: "1.2.3", - file: "my.csproj", - groups: [], - source: nil - }]) + requirement: "1.2.3", + file: "my.csproj", + groups: [], + source: nil + }]) end end @@ -351,11 +351,11 @@ expect(dependency.name).to eq("Prototype.Sdk") expect(dependency.version).to eq("0.1.0-beta") expect(dependency.requirements).to eq([{ - requirement: "0.1.0-beta", - file: "my.csproj", - groups: [], - source: nil - }]) + requirement: "0.1.0-beta", + file: "my.csproj", + groups: [], + source: nil + }]) end end end