File Coverage

blib/lib/Dist/Zilla/Plugin/Subversion/Check.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1 1     1   805 use strict;
  1         2  
  1         37  
2 1     1   7 use warnings;
  1         3  
  1         52  
3             package Dist::Zilla::Plugin::Subversion::Check;
4             # ABSTRACT: check SVN working copy before release
5              
6 1     1   500 use Dist::Zilla 4 ();
  0            
  0            
7             use Moose;
8              
9             use SVN::Client;
10              
11             with 'Dist::Zilla::Role::BeforeRelease';
12              
13             has 'svn' => (
14             is => 'ro',
15             isa => 'SVN::Client',
16             lazy => 1,
17             default => sub {
18             my $self = shift;
19             SVN::Client->new();
20             },
21             );
22              
23             has check_up2date => ( is => 'rw', isa => 'Bool', default => 1 );
24             has check_uncommited => ( is => 'rw', isa => 'Bool', default => 1 );
25             has check_missing => ( is => 'rw', isa => 'Bool', default => 1 );
26             has check_untracked => ( is => 'rw', isa => 'Bool', default => 1 );
27              
28             has '_wc_revision' => ( is => 'ro', isa => 'Int', lazy => 1,
29             default => sub {
30             my $self = shift;
31             my $rev;
32             $self->svn->info("", undef, 'WORKING', sub { $rev = $_[1]->rev }, 0);
33             return($rev);
34             }
35             );
36              
37             has '_repo_head_revision' => ( is => 'ro', isa => 'Int', lazy => 1,
38             default => sub {
39             my $self = shift;
40             my $rev;
41             $self->svn->info("", undef, 'HEAD', sub { $rev = $_[1]->rev }, 0);
42             return($rev);
43             }
44             );
45              
46             has '_svn_status' => ( is => 'ro', isa => 'HashRef[ArrayRef[Str]]', lazy_build => 1 );
47              
48             sub _build__svn_status {
49             my $self = shift;
50             my $ret = { 'untracked' => [], 'added' => [], 'missing' => [], 'deleted' => [],
51             'modified' => [], 'merged' => [], 'conflicted' => [] };
52             $self->svn->status('', 'HEAD', sub {
53             if($_[1]->text_status == 2) { push(@{$ret->{'untracked'}}, $_[0]); }
54             if($_[1]->text_status == 4) { push(@{$ret->{'added'}}, $_[0]); }
55             if($_[1]->text_status == 5) { push(@{$ret->{'missing'}}, $_[0]); }
56             if($_[1]->text_status == 6) { push(@{$ret->{'deleted'}}, $_[0]); }
57             if($_[1]->text_status == 8) { push(@{$ret->{'modified'}}, $_[0]); }
58             if($_[1]->text_status == 9) { push(@{$ret->{'merged'}}, $_[0]); }
59             if($_[1]->text_status == 10) { push(@{$ret->{'conflicted'}}, $_[0]); }
60             }, 1, 1, 1, 0);
61              
62             return($ret);
63             }
64              
65             foreach my $i ('untracked', 'added', 'missing', 'deleted', 'modified', 'merged', 'conflicted') {
66             has '_'.$i.'_files' => (
67             is => 'ro', isa => 'ArrayRef[Str]', lazy => 1,
68             traits => [ 'Array' ],
69             default => sub {
70             my $self = shift;
71             return($self->_svn_status->{$i});
72             },
73             handles => {
74             '_'.$i.'_files_count' => 'count',
75             },
76             );
77             }
78              
79             sub before_release {
80             my $self = shift;
81              
82             $self->log('WC revision: '.$self->_wc_revision);
83             $self->log('Repository HEAD revision: '.$self->_repo_head_revision);
84             if( $self->check_up2date && $self->_wc_revision < $self->_repo_head_revision ) {
85             $self->log_fatal("Working copy not up-to-date!");
86             }
87              
88             foreach my $type ( keys %{$self->_svn_status} ) {
89             if( scalar @{$self->_svn_status->{$type}} ) {
90             $self->log($type." files: ".join(', ', @{$self->_svn_status->{$type}}) );
91             }
92             }
93              
94             if( $self->check_missing && $self->_missing_files_count ) {
95             $self->log_fatal('Some files in working copy are missing!');
96             }
97              
98              
99             if( $self->check_untracked && $self->_untracked_files_count ) {
100             $self->log_fatal('Some files in working copy are not under version control!');
101             }
102              
103             if( $self->check_uncommited && (
104             $self->_added_files_count ||
105             $self->_deleted_files_count ||
106             $self->_modified_files_count ||
107             $self->_merged_files_count ||
108             $self->_conflicted_files_count )
109             ) {
110             $self->log_fatal('Working copy has uncommited changes!');
111             }
112              
113             return;
114             }
115              
116             1;
117              
118             __END__
119              
120             =pod
121              
122             =head1 NAME
123              
124             Dist::Zilla::Plugin::Subversion::Check - check SVN working copy before release
125              
126             =head1 SYNOPSIS
127              
128             In your F<dist.ini>:
129              
130             [Subversion::Check]
131             # you may want to disable individual checks (uncomment)
132             #check_up2date = 0
133             #check_uncommited = 0
134             #check_missing = 0
135             #check_untracked = 0
136              
137             =head1 DESCRIPTION
138              
139             This plugin checks your current working copy before doing a dzil release.
140              
141             The plugin accepts the following options:
142              
143             =over
144              
145             =item *
146              
147             C<check_up2date> (default: 1) - check if working copy is up-to-date.
148              
149             =item *
150              
151             C<check_uncommited> (default: 1) - check if the working copy has uncommited changes.
152              
153             =item *
154              
155             C<check_missing> (default: 1) - check if files in the working copy are missing.
156              
157             =item *
158              
159             C<check_untracked> (default: 1) - check if there are untracked files in the current working copy.
160              
161             =back
162              
163             =head1 AUTHOR
164              
165             Markus Benning
166              
167             =head1 COPYRIGHT AND LICENSE
168              
169             This software is copyright (c) 2013 by Markus Benning
170              
171             This is free software; you can redistribute it and/or modify it under
172             the same terms as the Perl 5 programming language system itself.
173              
174             =cut
175