module Hbc class DSL class Version < ::String DIVIDERS = { "." => :dots, "-" => :hyphens, "_" => :underscores, "/" => :slashes, }.freeze DIVIDER_REGEX = /(#{DIVIDERS.keys.map { |v| Regexp.quote(v) }.join('|')})/ MAJOR_MINOR_PATCH_REGEX = /^(\d+)(?:\.(\d+)(?:\.(\d+))?)?/ class << self private def define_divider_methods(divider) define_divider_deletion_method(divider) define_divider_conversion_methods(divider) end def define_divider_deletion_method(divider) method_name = deletion_method_name(divider) define_method(method_name) do version { delete(divider) } end end def deletion_method_name(divider) "no_#{DIVIDERS[divider]}" end def define_divider_conversion_methods(left_divider) (DIVIDERS.keys - [left_divider]).each do |right_divider| define_divider_conversion_method(left_divider, right_divider) end end def define_divider_conversion_method(left_divider, right_divider) method_name = conversion_method_name(left_divider, right_divider) define_method(method_name) do version { gsub(left_divider, right_divider) } end end def conversion_method_name(left_divider, right_divider) "#{DIVIDERS[left_divider]}_to_#{DIVIDERS[right_divider]}" end end DIVIDERS.each_key do |divider| define_divider_methods(divider) end attr_reader :raw_version def initialize(raw_version) @raw_version = raw_version super(raw_version.to_s) end def latest? to_s == "latest" end def major version { slice(MAJOR_MINOR_PATCH_REGEX, 1) } end def minor version { slice(MAJOR_MINOR_PATCH_REGEX, 2) } end def patch version { slice(MAJOR_MINOR_PATCH_REGEX, 3) } end def major_minor version { [major, minor].reject(&:empty?).join(".") } end def major_minor_patch version { [major, minor, patch].reject(&:empty?).join(".") } end def minor_patch version { [minor, patch].reject(&:empty?).join(".") } end def before_comma version { split(",", 2)[0] } end def after_comma version { split(",", 2)[1] } end def before_colon version { split(":", 2)[0] } end def after_colon version { split(":", 2)[1] } end def no_dividers version { gsub(DIVIDER_REGEX, "") } end private def version return self if empty? || latest? self.class.new(yield) end end end end