Class: Dependabot::Maven::FileParser::WrapperMojo

Inherits:
Object
  • Object
show all
Extended by:
T::Sig
Defined in:
lib/dependabot/maven/file_parser/wrapper_mojo.rb

Overview

Model of the Maven Wrapper plugin's WrapperMojo goal. Mirrors the properties recognized by the upstream plugin: https://github.com/apache/maven-wrapper/blob/master/maven-wrapper-plugin/src/main/java/org/apache/maven/plugins/wrapper/WrapperMojo.java

Defined Under Namespace

Classes: UnparseableDistributionUrl, WrapperProperties

Constant Summary collapse

DIST_URL_VERSION_REGEX =

Extracts the version from a distributionUrl value (the resolved URL, not the raw properties line). Match the standard artifact filename so custom mirrors do not need to preserve Maven Central's directory layout.

%r{
  /apache-maven-(?<version>[^/?#]+)-(?:bin|src)\.(?:zip|tar\.gz)(?:[?#].*)?\z
}x
SCRIPT_VERSION_REGEX =

Matches the human-readable banner embedded in mvnw / mvnw.cmd, e.g.:

"Apache Maven Wrapper startup script, version 3.3.2"
"Apache Maven Wrapper startup batch script, version 3.3.2"
/
  Apache \s Maven \s Wrapper \s startup \s (?:batch \s)?
  script, \s version \s
  (?<version>\d+\.\d+(?:\.\d+)?)
/x

Class Method Summary collapse

Class Method Details

.debug_scripts?(script_files) ⇒ Boolean

Returns:

  • (Boolean)


250
251
252
253
# File 'lib/dependabot/maven/file_parser/wrapper_mojo.rb', line 250

def self.debug_scripts?(script_files)
  debug_scripts = %w(mvnwDebug mvnwDebug.cmd)
  script_files.any? { |f| debug_scripts.any? { |s| f.name.end_with?(s) } }
end

.extract_distribution_version(content) ⇒ Object



277
278
279
280
281
282
283
284
# File 'lib/dependabot/maven/file_parser/wrapper_mojo.rb', line 277

def self.extract_distribution_version(content)
  match = content.match(DIST_URL_VERSION_REGEX)
  unless match && match[:version]
    raise UnparseableDistributionUrl, "Could not extract Maven version from distributionUrl"
  end

  T.must(match[:version])
end

.get_property_value(content, target_key) ⇒ Object



287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
# File 'lib/dependabot/maven/file_parser/wrapper_mojo.rb', line 287

def self.get_property_value(content, target_key)
  # 1. Handle Java line continuations (the backslash edge case)
  # We join lines ending in \ before splitting into an array
  normalized_content = content.gsub(/\\\n\s*/, "")

  # 2. Escape the key for Regex safety
  escaped_key = Regexp.escape(target_key)

  # Start of line -> Key -> optional space -> delimiter (= or :) -> value.
  # Bounded to spaces/tabs (not \s) so the per-line match can't backtrack polynomially.
  pattern = /^[ \t]*#{escaped_key}[ \t]*[=:][ \t]*(.*)$/

  normalized_content.lines.each do |line|
    next if line.start_with?("#", "!") # Skip Java comments

    if (match = line.match(pattern))
      return decode_property_value(T.must(match[1]).strip)
    end
  end
  nil
end

.get_property_value!(content, target_key) ⇒ Object



328
329
330
331
332
333
334
# File 'lib/dependabot/maven/file_parser/wrapper_mojo.rb', line 328

def self.get_property_value!(content, target_key)
  value = get_property_value(content, target_key)

  raise "Missing mandatory property: #{target_key}" if value.nil?

  value
end

.load_properties(content, script_files: []) ⇒ Object



256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
# File 'lib/dependabot/maven/file_parser/wrapper_mojo.rb', line 256

def self.load_properties(content, script_files: [])
  distribution_url = get_property_value!(content, "distributionUrl")
  distribution_version = extract_distribution_version(distribution_url)
  distribution_sha256_sum = get_property_value(content, "distributionSha256Sum")
  wrapper_url = get_property_value(content, "wrapperUrl")
  wrapper_sha256_sum = get_property_value(content, "wrapperSha256Sum")
  distribution_type = resolve_distribution_type(content, wrapper_url)
  wrapper_version = resolve_wrapper_version(content, wrapper_url, script_files)

  WrapperProperties.new(
    distribution_url: distribution_url,
    distribution_version: distribution_version,
    distribution_sha256_sum: distribution_sha256_sum,
    wrapper_sha256_sum: wrapper_sha256_sum,
    wrapper_version: wrapper_version,
    wrapper_url: wrapper_url,
    distribution_type: distribution_type
  )
end

.resolve_dependencies(properties_file, script_files: []) ⇒ Object



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/dependabot/maven/file_parser/wrapper_mojo.rb', line 76

def self.resolve_dependencies(properties_file, script_files: [])
  content = properties_file.content
  return [] unless content

  distribution_url = get_property_value(content, "distributionUrl")
  if distribution_url&.include?("mvnd")
    Dependabot.logger.warn("Maven daemon (mvnd) distribution is not supported, skipping wrapper update")
    return []
  end

  begin
    props = load_properties(content, script_files: script_files)
  rescue UnparseableDistributionUrl => e
    Dependabot.logger.warn("#{e.message}, skipping wrapper update")
    return []
  end

  if props.wrapper_url&.include?("takari")
    Dependabot.logger.warn("The Takari distribution is not supported, skipping wrapper update")
    return []
  end

  file_name = properties_file.name
  has_debug_scripts = debug_scripts?(script_files)
  deps = [build_distribution_dependency(file_name, props, props.distribution_version, has_debug_scripts)]
  deps << build_wrapper_dependency(
    file_name, props, props.distribution_version, props.wrapper_version, has_debug_scripts
  )
  deps.compact
end

.resolve_distribution_type(content, wrapper_url) ⇒ Object



242
243
244
245
246
247
# File 'lib/dependabot/maven/file_parser/wrapper_mojo.rb', line 242

def self.resolve_distribution_type(content, wrapper_url)
  explicit = get_property_value(content, "distributionType")
  return explicit if explicit

  wrapper_url ? "bin" : "only-script"
end