class Dependabot::Maven::FileParser::PropertyValueFinder

Constants

DOT_SEPARATOR_REGEX

Attributes

dependency_files[R]

Public Class Methods

new(dependency_files:) click to toggle source
# File lib/dependabot/maven/file_parser/property_value_finder.rb, line 20
def initialize(dependency_files:)
  @dependency_files = dependency_files
end

Public Instance Methods

property_details(property_name:, callsite_pom:) click to toggle source
# File lib/dependabot/maven/file_parser/property_value_finder.rb, line 24
def property_details(property_name:, callsite_pom:)
  pom = callsite_pom
  doc = Nokogiri::XML(pom.content)
  doc.remove_namespaces!

  # Loop through the paths that would satisfy this property name,
  # looking for one that exists in this POM
  nm = sanitize_property_name(property_name)
  node =
    loop do
      candidate_node =
        doc.at_xpath("/project/#{nm}") ||
        doc.at_xpath("/project/properties/#{nm}") ||
        doc.at_xpath("/project/profiles/profile/properties/#{nm}")
      break candidate_node if candidate_node
      break unless nm.match?(DOT_SEPARATOR_REGEX)

      nm = nm.sub(DOT_SEPARATOR_REGEX, "/")

    rescue Nokogiri::XML::XPath::SyntaxError => e
      raise DependencyFileNotEvaluatable, e.message
    end

  # If we found a property, return it
  return { file: pom.name, node: node, value: node.content.strip } if node

  # Otherwise, look for a value in this pom's parent
  return unless (parent = parent_pom(pom))

  property_details(
    property_name: property_name,
    callsite_pom: parent
  )
end

Private Instance Methods

fetch_remote_parent_pom(group_id, artifact_id, version, pom) click to toggle source
# File lib/dependabot/maven/file_parser/property_value_finder.rb, line 126
def fetch_remote_parent_pom(group_id, artifact_id, version, pom)
  parent_repository_urls(pom).each do |base_url|
    url = remote_pom_url(group_id, artifact_id, version, base_url)

    @maven_responses ||= {}
    @maven_responses[url] ||= Excon.get(
      url,
      idempotent: true,
      **SharedHelpers.excon_defaults
    )
    next unless @maven_responses[url].status == 200
    next unless pom?(@maven_responses[url].body)

    dependency_file = DependencyFile.new(
      name: "remote_pom.xml",
      content: @maven_responses[url].body
    )

    return dependency_file
  rescue Excon::Error::Socket, Excon::Error::Timeout,
         Excon::Error::TooManyRedirects, URI::InvalidURIError
    nil
  end

  # If a parent POM couldn't be found, return `nil`
  nil
end
internal_dependency_poms() click to toggle source
# File lib/dependabot/maven/file_parser/property_value_finder.rb, line 63
def internal_dependency_poms
  return @internal_dependency_poms if @internal_dependency_poms

  @internal_dependency_poms = {}
  dependency_files.each do |pom|
    doc = Nokogiri::XML(pom.content)
    group_id = doc.at_css("project > groupId") ||
               doc.at_css("project > parent > groupId")
    artifact_id = doc.at_css("project > artifactId")

    next unless group_id && artifact_id

    dependency_name = [
      group_id.content.strip,
      artifact_id.content.strip
    ].join(":")

    @internal_dependency_poms[dependency_name] = pom
  end

  @internal_dependency_poms
end
parent_pom(pom) click to toggle source

rubocop:disable Metrics/PerceivedComplexity

# File lib/dependabot/maven/file_parser/property_value_finder.rb, line 91
def parent_pom(pom)
  doc = Nokogiri::XML(pom.content)
  doc.remove_namespaces!
  group_id = doc.at_xpath("/project/parent/groupId")&.content&.strip
  artifact_id =
    doc.at_xpath("/project/parent/artifactId")&.content&.strip
  version = doc.at_xpath("/project/parent/version")&.content&.strip

  return unless group_id && artifact_id

  name = [group_id, artifact_id].join(":")

  return internal_dependency_poms[name] if internal_dependency_poms[name]

  return unless version && !version.include?(",")

  fetch_remote_parent_pom(group_id, artifact_id, version, pom)
end
parent_repository_urls(pom) click to toggle source

rubocop:enable Metrics/PerceivedComplexity

# File lib/dependabot/maven/file_parser/property_value_finder.rb, line 111
def parent_repository_urls(pom)
  repositories_finder.repository_urls(
    pom: pom,
    exclude_inherited: true
  )
end
pom?(content) click to toggle source
# File lib/dependabot/maven/file_parser/property_value_finder.rb, line 160
def pom?(content)
  !Nokogiri::XML(content).at_css("project > artifactId").nil?
end
remote_pom_url(group_id, artifact_id, version, base_repo_url) click to toggle source
# File lib/dependabot/maven/file_parser/property_value_finder.rb, line 154
def remote_pom_url(group_id, artifact_id, version, base_repo_url)
  "#{base_repo_url}/"\
  "#{group_id.tr('.', '/')}/#{artifact_id}/#{version}/"\
  "#{artifact_id}-#{version}.pom"
end
repositories_finder() click to toggle source
# File lib/dependabot/maven/file_parser/property_value_finder.rb, line 118
def repositories_finder
  @repositories_finder ||=
    RepositoriesFinder.new(
      dependency_files: dependency_files,
      evaluate_properties: false
    )
end
sanitize_property_name(property_name) click to toggle source
# File lib/dependabot/maven/file_parser/property_value_finder.rb, line 86
def sanitize_property_name(property_name)
  property_name.sub(/^pom\./, "").sub(/^project\./, "")
end