Dist-Zilla-Plugin-Git

 view release on metacpan or  search on metacpan

lib/Dist/Zilla/Plugin/Git/NextVersion.pm  view on Meta::CPAN

#
# This file is part of Dist-Zilla-Plugin-Git
#
# This software is copyright (c) 2009 by Jerome Quelin.
#
# This is free software; you can redistribute it and/or modify it under
# the same terms as the Perl 5 programming language system itself.
#
use strict;
use warnings;

package Dist::Zilla::Plugin::Git::NextVersion;
# ABSTRACT: Provide a version number by bumping the last git release tag

our $VERSION = '2.052';

use Dist::Zilla 4 ();
use version 0.80 ();

use Moose;
use namespace::autoclean 0.09;
use Path::Tiny;
use Try::Tiny;
use Types::Standard qw(Str RegexpRef Bool ArrayRef);
use Type::Utils qw(coerce from as via subtype);

use constant _cache_fn => '.gitnxtver_cache';

with 'Dist::Zilla::Role::BeforeRelease',
    'Dist::Zilla::Role::AfterRelease',
    'Dist::Zilla::Role::FilePruner',
    'Dist::Zilla::Role::VersionProvider',
    'Dist::Zilla::Role::Git::Repo';

# -- attributes

use constant _CoercedRegexp => do {
    my $tc = subtype as RegexpRef;
    coerce $tc, from Str, via { qr/$_/ };
    $tc;
};

has version_regexp  => ( is => 'ro', isa => _CoercedRegexp, coerce => 1,
                         default => sub { qr/^v(.+)$/ } );

has first_version  => ( is => 'ro', isa => Str, default => '0.001' );

has version_by_branch  => ( is => 'ro', isa => Bool, default => 0 );

sub _versions_from_tags {
  my ($regexp, $tags) = @_;

  # WARNING: The quotes in "$1" are necessary, because version doesn't
  # call get magic properly.
  return [ sort map /$regexp/ ? try { version->parse("$1") } : (), @$tags ];
} # end _versions_from_tags

has _all_versions => (
  is => 'ro',  isa => ArrayRef,
  init_arg => undef,
  lazy => 1,
  default => sub {
    my $self = shift;
    my $v = _versions_from_tags($self->version_regexp, [ $self->git->tag ]);
    if ($self->logger->get_debug) {
      $self->log_debug("Found version $_") for @$v;
    }
    $v;
  }
);

sub _max_version {
  my $versions = shift;  # arrayref of versions sorted in ascending order

  return $versions->[-1]->stringify if @$versions;

  return undef;
} # end _max_version

sub _last_version {
  my ($self) = @_;

  my $last_ver;
  my $by_branch = $self->version_by_branch;
  my $git       = $self->git;

  local $/ = "\n"; # Force record separator to be single newline

  if ($by_branch) {
    my $head;
    my $cachefile = path($self->zilla->root)->child(_cache_fn);
    if (-f $cachefile) {
      ($head) = $git->rev_parse('HEAD');
      return $1 if $cachefile->slurp =~ /^\Q$head\E (.+)/;
    }
    try {
      # Note: git < 1.6.1 doesn't understand --simplify-by-decoration or %d
      my @tags;
      for ($git->rev_list(qw(--simplify-by-decoration --pretty=%d HEAD))) {
        /^\s*\((.+)\)/ or next;
        push @tags, split /,\s*/, $1;
      } # end for lines from git log
      s/^tag:\s+// for @tags;   # Git 1.8.3 says "tag: X" instead of "X"
      my $versions = _versions_from_tags($self->version_regexp, \@tags);
      if ($self->logger->get_debug) {
        $self->log_debug("Found version $_ on branch") for @$versions;
      }
      $last_ver = _max_version($versions);
    };
    if (defined $last_ver) {
      ($head) = $git->rev_parse('HEAD') unless $head;
      print { $cachefile->openw } "$head $last_ver\n";
      return $last_ver;
    }
  } # end if version_by_branch

  # Consider versions from all branches:
  $last_ver = _max_version($self->_all_versions);



( run in 2.617 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )