The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Version::Dotted::Semantic - (Adapted) Semantic Versioning

VERSION

Version v0.0.1, released on 2017-01-04 21:35 UTC.

WHAT?

Version::Dotted and its subclasses are authoring time extensions to core version class: they complement version with bump operation and implement alternative trial version criteria.

This is Version::Dotted::Semantic module documentation. However, read Version::Dotted module documentation first, since it contains many relevant details.

General topics like getting source, building, installing, bug reporting and some others are covered in the README.

SYNOPSIS

    use Version::Dotted::Semantic;          # import nothing
    use Version::Dotted::Semantic 'qv';     # import qv

    # Construct:
    $v = Version::Dotted::Semantic->new( v1 );  # v1.0.0 (at least 3 parts)
    $v = qv( v1 );                              # ditto
    $v = qv( 'v1.2.3.4' );                      # v1.2.3.4

    # Get parts by name (indexing also works):
    $int = $v->part( 'major' );     # Always defined.
    $int = $v->part( 'minor' );     # ditto
    $int = $v->part( 'patch' );     # ditto
    $int = $v->part( 'trial' );     # May be undefined.
    $int = $v->major;       # Always defined.
    $int = $v->minor;       # ditto
    $int = $v->patch;       # ditto
    $int = $v->trial;       # May be undefined.

    # Bump the version (indexing also works):
    $v->bump( 'trial' );    # Bump trial part.
    $v->bump( 'patch' );    # Bump patch and drop trial.
    $v->bump( 'minor' );    # Bump minor, reset patch and drop trial.
    $v->bump( 'major' );    # Bump major, reset minor and patch, drop trial.

    # Release status:
    $bool = $v->is_trial;   # true if version has more than 3 parts.

    # See Version::Dotted for other methods.

DESCRIPTION

This is subclass of Version::Dotted. Three features distinct it from the parent:

  • Version object always has at least 3 parts.

        $v = qv( v1 );          # == v1.0.0
        $v->part( 0 ) == 1;     # Parts 0, 1, 2 are always defined.
        $v->part( 1 ) == 0;     # Zero if not specified explicitly.
        $v->part( 2 ) == 0;     # ditto
        $v->part( 3 ) == undef; # But may be defined.
  • First four parts have individual names.

        $v->major = $v->part( 'major' );    # == $v->part( 0 );
        $v->minor = $v->part( 'minor' );    # == $v->part( 1 );
        $v->patch = $v->part( 'patch' );    # == $v->part( 2 );
        $v->trial = $v->part( 'trial' );    # == $v->part( 3 );
    
        $v->bump( 'trial' );  # the same as $v->bump( 3 );
  • The number of parts defines release status: more than 3 parts denotes trial release.

        $v = qv( v1 );          # $v == v1.0.0
        $v->is_trial;           # false
        $v->bump( 'trial' );    # $v == v1.0.0.1
        $v->is_trial;           # true

CLASS ATTRIBUTES

min_len

Minimal number of parts, read-only.

    $int = Version::Dotted::Semantic->min_len;  # == 3

Version::Dotted::Semantic objects always have at least 3 parts.

OBJECT METHODS

major

minor

patch

Returns the first, the second, and the third part of the version, respectively.

    $int = $v->major;   # the first part
    $int = $v->minor;   # the second part
    $int = $v->patch;   # the third part

Since version always has at least 3 parts, these methods never return undef.

trial

Returns the fourth part of the version.

    $int = $v->trial;   # the fourth part

The method returns undef if version has less than 4 parts.

is_trial

Returns true in case of trial version, and false otherwise.

    $bool = $v->is_trial;

A version is considered trial if it has more than 3 parts:

    qv( v1.2.3.4 )->is_trial;   # true
    qv( v1.2.4   )->is_trial;   # false

SEMANTIC VERSIONING

See Semantic Versioning 2.0.0. It sound very reasonable to me.

Unfortunately, Semantic Versioning cannot be applied to Perl modules (maintaining compatibility with version objects) due to wider character set (letters, hyphens, plus signs, e. g. 1.0.0-alpha.3+8daebec8a8e1) and specific precedence rules (1.0.0-alpha < 1.0.0).

DOTTED SEMANTIC VERSIONING

Dotted Semantic Versioning is adaptation of Semantic Versioning for Perl and version.

Summary

Given a version number vmajor.minor.patch, increment the:

  • major version when you make incompatible API changes,

  • minor version when you add functionality in a backwards-compatible manner, and

  • patch version when you make backwards-compatible bug fixes.

Additional labels for trial versions are available as extension to the vmajor.minor.patch format.

Introduction

See Semantic Versioning Introduction.

Dotted Semantic Versioning Specification

The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.

  1. Software using Dotted Semantic Versioning MUST declare a public API. This API could be declared in the code itself or exist strictly in documentation. However it is done, it should be precise and comprehensive.

  2. A normal version number MUST take the form vX.Y.Z where X, Y, and Z are non-negative integers, and MUST NOT contain leading zeroes. X is the major version, Y is the minor version, and Z is the patch version. Each element MUST increase numerically. For instance: v1.9.0 -> v1.10.0 -> v1.11.0.

  3. Once a versioned package has been released, the contents of that version MUST NOT be modified. Any modifications MUST be released as a new version.

  4. Major version zero (v0.y.z) is for initial development. Anything may change at any time. The public API should not be considered stable.

  5. Version v1.0.0 defines the public API. The way in which the version number is incremented after this release is dependent on this public API and how it changes.

  6. Patch version Z (vx.y.Z | x > 0) MUST be incremented if only backwards compatible bug fixes are introduced. A bug fix is defined as an internal change that fixes incorrect behavior.

  7. Minor version Y (vx.Y.z | x > 0) MUST be incremented if new, backwards compatible functionality is introduced to the public API. It MUST be incremented if any public API functionality is marked as deprecated. It MAY be incremented if substantial new functionality or improvements are introduced within the private code. It MAY include patch level changes. Patch version MUST be reset to 0 when minor version is incremented.

  8. Major version X (vX.y.z | X > 0) MUST be incremented if any backwards incompatible changes are introduced to the public API. It MAY include minor and patch level changes. Patch and minor version MUST be reset to 0 when major version is incremented.

  9. A trial version MAY be denoted by appending a dot and a series of dot separated numbers immediately following the patch version. Numbers are non-negative integers and MUST NOT include leading zeroes. A trial version indicates that the version is unstable and might not satisfy the intended compatibility requirements as denoted by its associated normal version. Examples: v1.0.0.1, v1.0.0.1.1, v1.0.0.0.3.7, v1.0.0.7.92.

  10. (Paragraph excluded, build metadata is not used.)

  11. Precedence refers to how versions are compared to each other when ordered. Precedence MUST be calculated by separating the version into numbers in order. Precedence is determined by the first difference when comparing each of these numbers from left to right. Example: v1.0.0 < v2.0.0 < v2.1.0 < v2.1.1. A larger set of parts has a higher precedence than a smaller set, if all of the preceding identifiers are equal. Example: v1.0.0 < v1.0.0.1 < v1.0.0.1.1 < v1.0.0.1.2 < v1.0.0.2 < v1.0.1.

Why Use Dotted Semantic Versioning?

See Why Use Semantic Versioning?.

FAQ

See Semantic Versioning FAQ.

About

The Dotted Semantic Versioning specification is authored by Van de Bugger. It is adaptation of Semantic Versioning 2.0.0 for Perl modules.

Semantic Versioning 2.0.0 is authored by Tom Preston-Werner, inventor of Gravatars and cofounder of GitHub.

ADAPTATION DETAILS

Paragraphs 1..8 of Semantic Versioning define normal version number and establish rules for major, minor and patch. I would say these paragraphs are core of Semantic Versioning. Happily they can be applied for versioning Perl modules with almost no modifications. I just added leading 'v' character to version numbers.

Paragraphs 9..11 define auxiliary stuff (pre-release version, build metadata) and version precedence rules. Unfortunately, these paragraphs cannot be applied as-is for versioning Perl modules, they require adaptation.

Paragraph 9, pre-release version

Semantic Versioning uses term pre-release. Pre-release version is denoted by appending minus sign and a series of dot separated identifiers which comprise alphanumeric and hyphen.

Dotted version cannot include letters and hyphens, a workaround is required.

First, let us call it trial (instead of pre-release), it is more Perlish and CPANish. (BTW, it is also more correct term, because trial versions are released, actually.)

Second, let us reduce trial identifier alphabet to digits (instead of alphanumeric and hyphen; it fully meets Semantic Versioning, they call such identifiers "numeric").

Third, let us denote trial version by dot. Dot is already used to separate parts of normal version: major, minor, and patch. However, the number of parts in normal version is fixed, so we can easily distinguish trial: the first 3 parts compose normal version, everything behind the third dot (if any) compose trial.

Paragraph 10, build metadata

Build metadata is denoted by appending a plus sign and dot separated identifiers.

Dotted version cannot include plus sign, a workaround is required (again).

Replacement plus sign with dot (like replacing hyphen with dot for trial versions) does not work: build metadata would be indistinguishable from trial version. Fortunately, build metadata is not mandatory, so let us drop it completely.

Paragraph 11, precedence

This paragraph defines version precedence. It prescribes a pre-release version has lower precedence than a normal version with the same major, minor, and patch: 1.0.0-alpha < 1.0.0.

This looks good for Semantic Versioning with hyphen and alphanumeric pre-release identifiers, but it does not look good for Dotted Semantic Versioning with only dots and numeric trial identifiers: 1.0.0.1 < 1.0.0.

So, let us use natural precedence as it implemented by version module: 1.0.0 < 1.0.0.1. A trial release can be placed before normal release by choosing appropriate major, minor, and patch versions. For example, a series of trial releases preceding version 1.0.0 could be 0.99.99.1, 0.99.99.2, 0.999.999.3, etc, a series of trial releases preceding 1.1.0 could be 1.0.99.1, 1.0.99.2, etc.

SEE ALSO

Version::Dotted
Semantic Versioning 2.0.0

AUTHOR

Van de Bugger <van.de.bugger@gmail.com>

COPYRIGHT AND LICENSE

Everything except "Dotted Semantic Versioning" chapter

Copyright (C) 2017 Van de Bugger

License GPLv3+: The GNU General Public License version 3 or later <http://www.gnu.org/licenses/gpl-3.0.txt>.

This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.

"Dotted Semantic Versioning" chapter

Licensed under CC BY 3.0.