module Versionomy

Versionomy

The Versionomy module contains some convenience methods for creating and parsing version numbers.

Constants

Formats

Version number format.

A format controls the parsing and unparsing of a version number. Any time a version number is parsed from a string, a format is provided to parse it. Similarly, every version number value references a format that is used to unparse it back into a string.

A format is always tied to a particular schema and knows how to parse only that schema's version numbers.

Under many circumstances, you should use the standard format, which can be retrieved by calling Versionomy::Format#standard. This format understands most common version numbers, including prerelease (e.g. alpha, beta, release candidate, etc.) forms and patchlevels.

You may also create your own formats, either by implementing the format contract (see Versionomy::Format::Base), or by using the Versionomy::Format::Delimiter tool, which can be used to construct parsers for many version number formats.

Format registry

Formats may be registered with Versionomy and given a name using the methods of this module. This allows version numbers to be serialized with their format. When a version number is serialized, its format name is written to the stream, along with the version number's string representation. When the version number is reconstructed, its format is looked up by name so versionomy can determine how to parse the string.

Format names are strings that may include letters, numerals, dashes, underscores, and periods. By convention, periods are used as namespace delimiters. Format names without a namespace (that is, with no periods) are considered reserved for standard versionomy formats. If you define your own format, you should use a name that includes a namespace (e.g. “mycompany.LibraryVersion”) to reduce the chance of name collisions.

You may register formats directly using the register method, or set it up to be autoloaded on demand. When a format is requested, if it has not been registered explicitly, Versionomy looks for a format definition file for that format. Such a file has the name of the format, with the “.rb” extension for ruby (e.g. “mycompany.LibraryVersion.rb”) and must be located in a directory in versionomy's format lookup path. By default, the directory containing versionomy's predefined formats (such as “standard”) is in this path. However, you may add your own directories using the add_directory method. This lets you autoload your own formats. A format definition file itself must contain ruby code that defines the format and registers it using the correct name. See the files in the “lib/versionomy/format_definitions/” directory for examples.

VERSION

Current gem version, as a Versionomy::Value.

VERSION_STRING

Current gem version, as a frozen string.

Public Class Methods

create(values_=nil, format_=nil, unparse_params_=nil) click to toggle source

Create a new version number given a hash or array of values, and an optional format.

The values should either be a hash of field names and values, or an array of values that will be interpreted in field order.

The format can be specified as a format object or the name of a format registered with Versionomy::Format. If the format is omitted or set to nil, the ::default_format will be used.

You can also optionally provide default parameters to be used when unparsing this value or any derived from it.

Raises Versionomy::Errors::UnknownFormatError if a name is given that is not registered.

# File lib/versionomy/interface.rb, line 93
def create(values_=nil, format_=nil, unparse_params_=nil)
  if format_.kind_of?(::Hash) && unparse_params_.nil?
    unparse_params_ = format_
    format_ = nil
  end
  if format_.kind_of?(::String) || format_.kind_of?(::Symbol)
    format_ = Format.get(format_, true)
  end
  format_ ||= default_format
  Value.new(values_ || [], format_, unparse_params_)
end
default_format() click to toggle source

Gets the current default format. Usually this is the “standard” format returned by Versionomy::Format.standard.

# File lib/versionomy/interface.rb, line 53
def default_format
  @default_format ||= Format.standard
end
default_format=(format_) click to toggle source

Sets the default format used by other methods of this convenience interface. Usually, this is set to the “standard” format returned by Versionomy::Format.standard and should not be changed.

The format can be specified as a format object or the name of a format registered with Versionomy::Format. If the format is set to nil, the ::default_format will be reset to the “standard” format.

Raises Versionomy::Errors::UnknownFormatError if a name is given that is not registered.

# File lib/versionomy/interface.rb, line 69
def default_format=(format_)
  if format_.kind_of?(::String) || format_.kind_of?(::Symbol)
    format_ = Format.get(format_, true)
  end
  @default_format = format_
end
parse(str_, format_=nil, parse_params_=nil) click to toggle source

Create a new version number given a string to parse, and an optional format.

The format can be specified as a format object or the name of a format registered with Versionomy::Format. If the format is omitted or set to nil, the ::default_format will be used.

The parameter hash, if present, will be passed as parsing parameters to the format.

Raises Versionomy::Errors::UnknownFormatError if a name is given that is not registered.

May raise Versionomy::Errors::ParseError if parsing failed.

# File lib/versionomy/interface.rb, line 121
def parse(str_, format_=nil, parse_params_=nil)
  if format_.kind_of?(::Hash) && parse_params_.nil?
    parse_params_ = format_
    format_ = nil
  end
  if format_.kind_of?(::String) || format_.kind_of?(::Symbol)
    format_ = Format.get(format_, true)
  end
  format_ ||= default_format
  format_.parse(str_, parse_params_)
end
ruby_version() click to toggle source

Get the ruby version as a Versionomy::Value, using the builtin constants RUBY_VERSION and RUBY_PATCHLEVEL.

# File lib/versionomy/interface.rb, line 205
def ruby_version
  @ruby_version ||= begin
    version_ = parse(::RUBY_VERSION, :standard)
    if version_.release_type == :final
      version_ = version_.change({:patchlevel => ::RUBY_PATCHLEVEL},
        :patchlevel_required => true, :patchlevel_delim => '-p')
    end
    version_
  end
end
semver(input_) click to toggle source

Convenience method for creating a version number using the Semantic Versioning format (see semver.org/).

You may pass a string to parse, or a hash with the following keys, all of which are optional:

:major

Major version number

:minor

Minor version number

:patch

Patch version number

:prerelease_suffix

A prerelease suffix (e.g. “b2”)

May raise Versionomy::Errors::ParseError if parsing failed.

# File lib/versionomy/interface.rb, line 150
def semver(input_)
  if input_.kind_of?(::Hash)
    create(input_, :semver)
  else
    parse(input_.to_s, :semver)
  end
end
version_of(mod_) click to toggle source

Get the version of the given module as a Versionomy::Value. Tries a number of common approaches to embedding version numbers into modules, such as string or array constants, submodules containing constants, or module method calls. Returns the version number, or nil if it wasn't found or couldn't be interpreted.

# File lib/versionomy/interface.rb, line 166
def version_of(mod_)
  version_ = nil
  [:VERSION, :VERSION_STRING, :GemVersion].each do |sym_|
    if mod_.const_defined?(sym_)
      version_ = mod_.const_get(sym_)
      break
    end
  end
  if version_.kind_of?(::Module)
    if version_.const_defined?(:STRING)
      version_ = version_.const_get(:STRING)
    elsif version_.const_defined?(:VERSION)
      version_ = version_.const_get(:VERSION)
    elsif version_.const_defined?(:MAJOR) && version_.const_defined?(:MINOR) && version_.const_defined?(:TINY)
      version_ = Value.new([version_.const_get(:MAJOR), version_.const_get(:MINOR), version_.const_get(:TINY)], :standard)
    end
  end
  unless version_.kind_of?(::String) || version_.kind_of?(::Array) || version_.kind_of?(Value)
    [:version, :release].each do |sym_|
      if mod_.respond_to?(sym_)
        version_ = mod_.send(sym_)
        break
      end
    end
  end
  if version_.kind_of?(::String)
    version_ = parse(version_, :standard) rescue nil
  elsif version_.kind_of?(::Array)
    version_ = create(version_, :standard) rescue nil
  elsif !version_.kind_of?(Value)
    version_ = nil
  end
  version_
end