App-DocKnot

 view release on metacpan or  search on metacpan

lib/App/DocKnot/Release.pm  view on Meta::CPAN

    } elsif (!-d $distdir) {
        croak("distdir path $distdir does not exist or is not a directory");
    }

    # Build an App::DocKnot::Spin::Versions object if configured with a path
    # to a versions database.
    my $versions;
    if ($global_config_ref->{versions}) {
        my $versions_path = path($global_config_ref->{versions});
        $versions = App::DocKnot::Spin::Versions->new($versions_path);
    }

    # Create and return the object.
    my $self = {
        archivedir   => path($archivedir),
        distdir      => path($distdir),
        package      => $config_ref->{name},
        section      => $config_ref->{distribution}{section},
        tarname      => $config_ref->{distribution}{tarname},
        version_name => $config_ref->{distribution}{version},
        versions     => $versions,
    };
    bless($self, $class);
    return $self;
}

# Release a new version and update .versions if so configured.
#
# Throws: Text exception on any failures
sub release {
    my ($self) = @_;
    my $tarball_ref = latest_tarball($self->{distdir}, $self->{tarname});
    if (!defined($tarball_ref)) {
        croak("no release of $self->{tarname} found in $self->{distdir}");
    }

    # Archive old versions.  This is only done if the current version in the
    # archive directory is different than the version we're about to release.
    # If it is not, we overwrite the version in the archive directory, since
    # we assume we're replacing a release.
    my $current_path = $self->{archivedir}->child($self->{section});
    my $current_ref = latest_tarball($current_path, $self->{tarname});
    if (defined($current_ref)) {
        if ($current_ref->{version} ne $tarball_ref->{version}) {
            my $old_root = $self->{archivedir}->child('ARCHIVE');
            my $old_path = $old_root->child($self->{tarname});
            $old_path->mkpath();
            for my $file ($current_ref->{files}->@*) {
                $current_path->child($file)->move($old_path->child($file));
            }
        }
    }

    # Copy the new version into place and update the symlinks.
    my @times;
    $current_path->mkpath();
    for my $file ($tarball_ref->{files}->@*) {
        my $source = $self->{distdir}->child($file);
        my $dest = $current_path->child($file);
        $source->copy($dest);
        my ($atime, $mtime) = $source->stat()->@[8, 9];
        push(@times, $mtime);
        utime($atime, $mtime, $dest)
          or die "cannot reset timestamps of $dest: $!\n";
        my $generic_name = $file;
        $generic_name =~ s{ \A (\Q$self->{tarname}\E) - v?[\d.]+ [.] }{$1.}xms;
        my $generic_path = $current_path->child($generic_name);
        $generic_path->remove();
        symlink($file, $generic_path);
    }

    # Update the .versions file.
    if ($self->{versions}) {
        my $name = $self->{version_name};
        my $version = $tarball_ref->{version};
        my $date = min(@times);
        $self->{versions}->update_version($name, $version, $date);
    }
    return;
}

##############################################################################
# Module return value and documentation
##############################################################################

1;
__END__

=for stopwords
Allbery DocKnot MERCHANTABILITY NONINFRINGEMENT sublicense archivedir distdir

=head1 Name

App::DocKnot::Release - Release a distribution tarball

=head1 SYNOPSIS

    use App::DocKnot::Release;
    my $docknot = App::DocKnot::Release->new();
    $docknot->release();

=head1 REQUIREMENTS

Perl 5.24 or later and the modules File::BaseDir, File::ShareDir,
Git::Repository, Path::Tiny, and YAML::XS, all of which are available from
CPAN.

=head1 DESCRIPTION

This component of DocKnot releases a distribution tarball (normally created by
C<docknot dist> or App::DocKnot::Dist), maintains a software distribution
directory, and updates a version and release date database.

=head1 CLASS METHODS

=over 4

=item new(ARGS)

Create a new App::DocKnot::Release object.  This should be used for all
subsequent actions.  ARGS should be a hash reference with one or more of the



( run in 0.614 second using v1.01-cache-2.11-cpan-39bf76dae61 )