Module: Vers::GentooVersion

Extended by:
GentooVersion
Included in:
GentooVersion
Defined in:
lib/vers/distribution_version.rb

Constant Summary collapse

PATTERN =
/\A\d+(?:\.\d+)*[A-Za-z]?(?:_(?:p(?:re)?|beta|alpha|rc)\d*)*(?:-r\d+)?\z/
SUFFIX_RANKS =
{
  "alpha" => -4,
  "beta" => -3,
  "pre" => -2,
  "rc" => -1,
  "p" => 1
}.freeze

Instance Method Summary collapse

Instance Method Details

#compare(left, right) ⇒ Object



376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
# File 'lib/vers/distribution_version.rb', line 376

def compare(left, right)
  left_version, left_revision = split_revision(left)
  right_version, right_revision = split_revision(right)
  return VersionComparison.compare_numbers(left_revision, right_revision) if left_version == right_version

  left_base, left_suffixes = split_base(left_version)
  right_base, right_suffixes = split_base(right_version)
  comparison = compare_base(left_base, right_base)
  return comparison unless comparison.zero?

  comparison = compare_suffixes(left_suffixes, right_suffixes)
  return comparison unless comparison.zero?

  VersionComparison.compare_numbers(left_revision, right_revision)
end

#compare_base(left, right) ⇒ Object



416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
# File 'lib/vers/distribution_version.rb', line 416

def compare_base(left, right)
  left_value, left_letter = split_letter(left)
  right_value, right_letter = split_letter(right)
  left_parts = left_value.split(".", -1)
  right_parts = right_value.split(".", -1)

  [left_parts.length, right_parts.length].min.times do |index|
    comparison = compare_component(index, left_parts[index], right_parts[index])
    return comparison unless comparison.zero?
  end

  comparison = left_parts.length <=> right_parts.length
  return comparison unless comparison.zero?

  left_letter <=> right_letter
end

#compare_component(index, left, right) ⇒ Object



439
440
441
442
443
444
# File 'lib/vers/distribution_version.rb', line 439

def compare_component(index, left, right)
  return 0 if left == right
  return VersionComparison.compare_numbers(left, right) if index.zero? || (!left.start_with?("0") && !right.start_with?("0"))

  left.sub(/0+\z/, "") <=> right.sub(/0+\z/, "")
end

#compare_suffixes(left, right) ⇒ Object



446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
# File 'lib/vers/distribution_version.rb', line 446

def compare_suffixes(left, right)
  index = 0
  loop do
    left_suffix = left&.[](index)
    right_suffix = right&.[](index)
    return 0 unless left_suffix || right_suffix
    unless left_suffix
      kind, number = parse_suffix(right_suffix)
      rank = SUFFIX_RANKS.fetch(kind, 0)
      return 0 <=> rank unless rank.zero?
      return VersionComparison.compare_numbers("0", number)
    end
    unless right_suffix
      kind, number = parse_suffix(left_suffix)
      rank = SUFFIX_RANKS.fetch(kind, 0)
      return rank <=> 0 unless rank.zero?
      return VersionComparison.compare_numbers(number, "0")
    end

    left_kind, left_number = parse_suffix(left_suffix)
    right_kind, right_number = parse_suffix(right_suffix)
    comparison = SUFFIX_RANKS.fetch(left_kind, 0) <=> SUFFIX_RANKS.fetch(right_kind, 0)
    return comparison unless comparison.zero?

    comparison = VersionComparison.compare_numbers(left_number, right_number)
    return comparison unless comparison.zero?

    index += 1
  end
end

#normalize(value) ⇒ Object



396
397
398
# File 'lib/vers/distribution_version.rb', line 396

def normalize(value)
  value.to_s.strip
end

#parse_suffix(value) ⇒ Object



477
478
479
480
# File 'lib/vers/distribution_version.rb', line 477

def parse_suffix(value)
  match = /(\d*)\z/.match(value.to_s)
  [value.to_s[0...match.begin(0)], match[1]]
end

#prerelease?(value) ⇒ Boolean

Returns:

  • (Boolean)


400
401
402
403
404
# File 'lib/vers/distribution_version.rb', line 400

def prerelease?(value)
  version, = split_revision(value.to_s.strip)
  _, suffixes = split_base(version)
  suffixes&.any? { |suffix| SUFFIX_RANKS.fetch(parse_suffix(suffix).first, 0).negative? } || false
end

#split_base(value) ⇒ Object



411
412
413
414
# File 'lib/vers/distribution_version.rb', line 411

def split_base(value)
  base, suffixes = value.split("_", 2)
  [base, suffixes&.split("_", -1)]
end

#split_letter(value) ⇒ Object



433
434
435
436
437
# File 'lib/vers/distribution_version.rb', line 433

def split_letter(value)
  return [value[0...-1], value.getbyte(-1)] if value.match?(/[A-Za-z]\z/)

  [value, -1]
end

#split_revision(value) ⇒ Object



406
407
408
409
# File 'lib/vers/distribution_version.rb', line 406

def split_revision(value)
  match = /-r(\d+)\z/.match(value.to_s)
  match ? [value[0...match.begin(0)], match[1]] : [value.to_s, ""]
end

#valid?(value) ⇒ Boolean

Returns:

  • (Boolean)


392
393
394
# File 'lib/vers/distribution_version.rb', line 392

def valid?(value)
  value.to_s.strip.match?(PATTERN)
end