File Coverage

blib/lib/ShipIt/VC/Git.pm
Criterion Covered Total %
statement 9 66 13.6
branch 0 16 0.0
condition 0 5 0.0
subroutine 3 12 25.0
pod 5 7 71.4
total 17 106 16.0


line stmt bran cond sub pod time code
1             package ShipIt::VC::Git;
2 2     2   6 use strict;
  2         10  
  2         46  
3 2     2   7 use base 'ShipIt::VC';
  2         2  
  2         135  
4 2     2   682 use File::Temp ();
  2         26381  
  2         1682  
5              
6 0     0 0   sub command { 'git' }
7              
8             sub new {
9 0     0 0   my ($class, $conf) = @_;
10 0           my $self = bless {}, $class;
11 0           $self->{tagpattern} = $conf->value( $self->command . ".tagpattern" );
12 0           $self->{sign_tag} = $conf->value( $self->command . ".sign_tag" );
13 0           $self->{push_to} = $conf->value( $self->command . ".push_to" );
14 0           return $self;
15             }
16              
17             =head1 NAME
18              
19             ShipIt::VC::Git -- ShipIt's git support
20              
21             =head1 CONFIGURATION
22              
23             In your .shipit configuration file, the following options are recognized:
24              
25             =over
26              
27             =item B
28              
29             Defines how the tag are defined in your git repo.
30              
31             =item B
32              
33             This should be set to a truthy value, if you wish the tags to be GPG signed.
34             (C)
35              
36             =item B
37              
38             If you want the newly created to be pushed elsewhere (for instance in your
39             public git repository), then you can specify the destination in this variable
40              
41             =back
42              
43             =cut
44              
45             sub exists_tagged_version {
46 0     0 1   my ($self, $ver) = @_;
47              
48 0           my $command = $self->command;
49 0           my $x = `git tag -l $ver`;
50 0           chomp $x;
51 0           return $x;
52             }
53              
54             sub commit {
55 0     0 1   my ($self, $msg) = @_;
56              
57 0           my $command = $self->command;
58              
59 0 0         if ( my $unk = `git ls-files -z --others --exclude-standard` ) {
60 0           $unk =~ s/\0/\n/g;
61 0           die "Unknown local files:\n$unk\n\nUpdate .gitignore, or $command add them";
62 0           exit(1);
63             }
64              
65             # commit
66 0           my $tmp_fh = File::Temp->new(UNLINK => 1, SUFFIX => '.msg');
67 0           print $tmp_fh $msg;
68 0           my $tmp_fn = "$tmp_fh";
69 0           system($command, "commit", "-a", "-F", $tmp_fn);
70              
71 0 0         if (my $where = $self->{push_to}) {
72 0           my $branch = $self->_get_branch;
73 0 0         if ($branch) {
74 0           warn "pushing to $where";
75 0           system($self->command, "push", $where, $branch);
76             }
77             }
78             }
79              
80             sub _get_branch {
81 0     0     my $self = shift;
82              
83 0           open my $fh, '<', '.git/HEAD';
84 0           chomp(my $head = do { local $/; <$fh> });
  0            
  0            
85 0           close $fh;
86              
87 0           my ($branch) = $head =~ m!ref: refs/heads/(\S+)!;
88 0           return $branch;
89             }
90              
91             sub local_diff {
92 0     0 1   my ($self, $file) = @_;
93 0           my $command = $self->command;
94 0           return `$command diff --no-color HEAD $file`;
95             }
96              
97             sub _tag_of_version {
98 0     0     my ($self, $ver) = @_;
99 0   0       my $tag = $self->{tagpattern} || '';
100 0 0         $tag .= "%v" unless $tag =~ /\%v/i;
101 0           $tag =~ s/\%v/$ver/ig;
102 0           return $tag;
103             }
104              
105             sub tag_version {
106 0     0 1   my ($self, $ver, $msg) = @_;
107 0   0       $msg ||= "Tagging version $ver.\n";
108 0           my $tmp_fh = File::Temp->new(UNLINK => 1, SUFFIX => '.msg');
109 0           print $tmp_fh $msg;
110 0           my $tmp_fn = "$tmp_fh";
111 0           my $tag = $self->_tag_of_version($ver);
112 0 0         system($self->command, "tag", "-a", ($self->{sign_tag} ? "-s" : ()), "-F", $tmp_fn, $tag)
    0          
113             and die "Tagging of version '$ver' failed.\n";
114              
115 0 0         if (my $where = $self->{push_to}) {
116 0           warn "pushing to $where";
117 0           system($self->command, "push", $where, tag => $tag);
118             }
119             }
120              
121             sub are_local_diffs {
122 0     0 1   my ($self, $ver) = @_;
123 0           my $command = $self->command;
124 0           my $diff = `$command diff --no-color $ver`;
125 0 0         return $diff =~ /\S/ ? 1 : 0;
126             }
127              
128             1;