File Coverage

blib/lib/Dist/Release.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


line stmt bran cond sub pod time code
1             package Dist::Release;
2              
3 1     1   32464 use 5.10.0;
  1         3  
  1         40  
4              
5 1     1   5 use strict;
  1         2  
  1         29  
6 1     1   4 use warnings;
  1         6  
  1         28  
7              
8 1     1   540 use Moose::Policy 'MooseX::Policy::SemiAffordanceAccessor';
  0            
  0            
9             use Moose;
10             use MooseX::Method::Signatures;
11              
12             use YAML;
13             use Term::ANSIColor;
14             use Hash::Merge 'merge';
15             use Readonly;
16              
17             our $VERSION = '0.0_5';
18              
19             Readonly my $rc_filename => 'distrelease.yml';
20              
21             has 'config',
22             is => 'ro',
23             builder => 'load_config';
24              
25             has 'actions',
26             isa => 'ArrayRef',
27             initializer => 'init_actions',
28             ;
29              
30             has 'checks',
31             isa => 'ArrayRef',
32             initializer => 'init_checks',
33             ;
34              
35             has 'vcs',
36             builder => 'detect_vcs',
37             is => 'rw';
38              
39             has builder => ( builder => 'detect_builder', is => 'ro' );
40              
41             has check_only => ( is => 'rw' );
42              
43             has pretend => ( is => 'ro', default => 1 );
44              
45             has stash => ( isa => 'HashRef', is => 'rw', default => sub { {} } );
46              
47             has version => (
48             is => 'ro',
49             lazy => 1,
50             default => sub {
51             my $self = shift;
52             require Dist::Release::Version;
53             my $v;
54             if ( my $f = $self->config->{distversion}{file} ) {
55             $v = Dist::Release::Version->new( config => $f );
56             }
57             else {
58             die "no distversion info found in config file\n"
59             unless $self->config->{distversion}{code};
60             $v =
61             Dist::Release::Version->new(
62             code => $self->config->{distversion}{code} );
63             }
64             return $v;
65             },
66             );
67              
68             sub detect_builder {
69             return
70             -f 'Build.PL' ? 'Build'
71             : -f 'Makefile.PL' ? 'MakeMaker'
72             : -f 'inc' ? 'ModuleInstall'
73             : undef;
74             }
75              
76             method run {
77              
78             if ( $self->pretend ) {
79             say 'Dist::Release will only pretend to perform the actions ',
80             '(use --doit for the real deal)';
81             }
82              
83             # build anew
84             $self->build;
85              
86             my $fails = $self->check;
87              
88             exit if $self->check_only;
89              
90             if ($fails) {
91             say 'some checks failed, aborting the release';
92             exit 1;
93             }
94              
95             $self->release;
96             }
97              
98             sub build {
99             my $self = shift;
100              
101             my $builder = $self->builder
102             or return say "no builder found...";
103              
104             $self->print_section("Building anew with $builder");
105              
106             if ( $builder eq 'Build' ) {
107             do 'Build.PL';
108             }
109             elsif ( $builder eq 'MakeMaker' ) {
110             do 'Makefile.PL';
111             }
112             else {
113             die "not implemented yet\n";
114             }
115              
116             }
117              
118             sub print_section {
119             shift;
120             say '-' x 30, ' ', @_;
121             }
122              
123             sub init_actions {
124             my ( $self, $value, $set ) = @_;
125              
126             if ( 'ARRAY' eq ref $value ) {
127             $self->add_actions(@$value);
128             }
129             }
130              
131             sub init_checks {
132             my ( $self, $value, $set ) = @_;
133              
134             if ( 'ARRAY' eq ref $value ) {
135             $self->add_checks(@$value);
136             }
137             }
138              
139             sub actions {
140             return @{ $_[0]->{actions} ||= [] };
141             }
142              
143             sub checks {
144             return @{ $_[0]->{checks} ||= [] };
145             }
146              
147             sub add_actions {
148             my ( $self, @actions ) = @_;
149              
150             for my $step (@actions) {
151             eval "require Dist::Release::Action::$step; 1;"
152             or die "couldn't load release step '$step'\n$@";
153             }
154              
155             push @{ $self->{actions} }, @actions;
156              
157             return $self->{actions};
158             }
159              
160             sub add_checks {
161             my ( $self, @checks ) = @_;
162              
163             $self->{checks} ||= [];
164              
165             for my $step (@checks) {
166             eval "require Dist::Release::Check::$step; 1;"
167             or die "couldn't load check step '$step'\n$@";
168             push @{ $self->{checks} }, $step;
169             }
170              
171             return $self->{checks};
172             }
173              
174             sub clear_actions {
175             $_[0]->{actions} = [];
176             }
177              
178             sub clear_checks {
179             $_[0]->{checks} = [];
180             }
181              
182             sub BUILD {
183             my $self = shift;
184              
185             $self->add_checks( @{ $self->config->{checks} } ) unless $self->checks;
186             $self->add_actions( @{ $self->config->{actions} } ) unless $self->actions;
187             }
188              
189             sub load_config {
190             my $self = shift;
191              
192             my @configs = map { YAML::LoadFile($_) }
193             grep { -f $_ }
194             map { "$_/$rc_filename" } $ENV{HOME}, '.'
195             or die "no file '$rc_filename' found\n";
196              
197             my $config = @configs == 1 ? $configs[0] : merge(@configs);
198              
199             return $config;
200             }
201              
202             sub detect_vcs {
203             my $self = shift;
204              
205             if ( -d '.git' ) {
206             require Git;
207             my $repo = Git->repository;
208             $self->set_vcs($repo);
209             }
210              
211             }
212              
213             sub vcs_name {
214             my $self = shift;
215              
216             my %mod2name = ( Git => 'Git', );
217              
218             return $mod2name{ ref $self->vcs };
219             }
220              
221             sub check {
222             my $self = shift;
223              
224             my $failed_checks;
225              
226             $self->print_section('running check cycle');
227              
228             print "regular checks\n";
229              
230             $failed_checks += !$self->check_single($_) for $self->checks;
231              
232             print "pre-action checks\n" if $self->actions;
233              
234             $failed_checks += !$self->check_single( $_, 'Action' ) for $self->actions;
235              
236             if ($failed_checks) {
237             print $failed_checks . ' checks failed' . "\n";
238             }
239              
240             return $failed_checks;
241             }
242              
243             # return true on success, false on failure
244             sub check_single {
245             my $self = shift;
246             my $checkname = shift;
247             my $type = shift || 'Check';
248              
249             my $pass = 1;
250             printf "%-30s ", $_;
251             my $s = "Dist::Release::${type}::$checkname"->new( distrel => $self );
252             $s->check;
253              
254             if ( $s->failed ) {
255             print '[' . colored( 'failed', 'red' ) . "]\n";
256             $pass = 0;
257             }
258             else {
259             print '[' . colored( 'passed', 'green' ) . "]\n";
260              
261             }
262              
263             no warnings qw/ uninitialized /;
264             print $s->log;
265              
266             return $pass;
267             }
268              
269             sub release {
270             my $self = shift;
271              
272             $self->print_section('running release cycle');
273              
274             my @actions = $self->actions;
275             while ( my $a = shift @actions ) {
276             my $name = $a;
277             printf "%-30s ", $a;
278             $a = "Dist::Release::Action::$a"->new( distrel => $self );
279             $a->release;
280              
281             if ( $a->failed ) {
282             print '[' . colored( 'failed', 'red' ) . "]\n";
283             print $a->log;
284             print "release actions not run to completion: ",
285             join( ', ', $name, @actions ), "\n";
286             exit;
287             }
288             else {
289             print '[' . colored( 'passed', 'green' ) . "]\n";
290              
291             }
292              
293             print $a->log;
294             }
295              
296             }
297              
298             sub print_steps {
299             my $self = shift;
300              
301             say 'checks';
302             say "\t$_" for $self->checks;
303             say 'actions';
304             say "\t$_" for $self->actions;
305              
306             }
307              
308             1;
309              
310             __END__
311              
312             =head1 NAME
313              
314             Dist::Release - manages the process of releasing a module (DEPRECATED)
315              
316             =head1 DESCRIPTION
317              
318             B<THIS MODULE IS DEPRECATED>
319              
320             Back in its early days, L<Dist::Zilla> wasn't quite scratching the release itch
321             to my satisfaction, so I had to have a go at it with I<Dist::Release>. But
322             now that I<Dist::Zilla> has blossomed to full-fledged awesomeness, it makes
323             much more sense to join the party than to continue on a parallel effort. Hence
324             de deprecation. I'll
325             keep this module around a little while still, but I strongly recommend to use
326             I<Dist::Zilla> instead. You'll like it better, trust me.
327              
328              
329             Dist::Release is meant to help CPAN authors automate the
330             release process of their modules. In Dist::Release, the
331             release process is seen as a sequence of steps. There are two
332             different kind of steps: checks and actions. Checks are non-intrusive
333             verifications (i.e., they're not supposed to touch anything),
334             and actions are the steps that do the active part of the release.
335             When one launches a release, checks are done first. If some fail,
336             we abort the process. If they all pass, then we are good to go and the actions are done as well.
337              
338              
339             The rest of this documentation deals with the guts of Dist::Release and
340             how to write new steps. If you are rather interested in using Dist::Release,
341             look at the documentation of L<distrelease>.
342              
343             =head1 METHODS
344              
345             =head2 builder
346              
347             Guesses the name of the build module used by the distribution.
348             Returns 'Build' for 'Module::Build',
349             'MakeMaker' for 'ExtUtils::MakeMaker',
350             'ModuleInstall' for 'Module::Install' and
351             I<undef> if it couldn't find anything.
352              
353             =head1 SEE ALSO
354              
355             L<Dist::Zilla> - rjbs' awesome distribution builder
356              
357             L<Module::Release> - another module tackling the same task.
358              
359              
360              
361             =head1 version
362              
363             This documentation refers to Dist::Release version 0.0_1.
364              
365             =head1 AUTHOR
366              
367             Yanick Champoux, <yanick@cpan.org>.
368              
369             =head1 LICENSE AND COPYRIGHT
370              
371             Copyright (c) 2008 Yanick Champoux (<yanick@cpan.org>). All rights reserved.
372              
373             This module is free software; you can redistribute it and/or
374             modify it under the same terms as Perl itself. See L<perlartistic>.
375