File Coverage

blib/lib/Dist/Zilla/Plugin/ACPS/Git/CommitBuild.pm
Criterion Covered Total %
statement 28 30 93.3
branch n/a
condition n/a
subroutine 10 10 100.0
pod n/a
total 38 40 95.0


line stmt bran cond sub pod time code
1             #
2             # This file is part of Dist-Zilla-Plugin-Git
3             #
4             # This software is copyright (c) 2009 by Jerome Quelin.
5             #
6             # This is free software; you can redistribute it and/or modify it under
7             # the same terms as the Perl 5 programming language system itself.
8             #
9 1     1   1753 use 5.008;
  1         3  
  1         33  
10 1     1   5 use strict;
  1         1  
  1         28  
11 1     1   3 use warnings;
  1         1  
  1         53  
12              
13             package Dist::Zilla::Plugin::ACPS::Git::CommitBuild;
14             our $VERSION = '0.30'; # VERSION
15             # ABSTRACT: checkin build results on separate branch
16              
17 1     1   4 use Git::Wrapper 0.021;
  1         14  
  1         17  
18 1     1   3 use IPC::Open3;
  1         2  
  1         55  
19 1     1   527 use IPC::System::Simple; # required for Fatalised/autodying system
  1         12305  
  1         53  
20 1     1   413 use File::chdir;
  1         2303  
  1         188  
21 1     1   7 use File::Spec::Functions qw/ rel2abs catfile /;
  1         1  
  1         40  
22 1     1   5 use File::Temp;
  1         2  
  1         63  
23 1     1   202 use Moose;
  0            
  0            
24             use namespace::autoclean;
25             use MooseX::AttributeShortcuts;
26             use Path::Class;
27             use MooseX::Types::Path::Class ':all';
28             use MooseX::Has::Sugar;
29             use MooseX::Types::Moose qw{ Str };
30             use Cwd qw(abs_path);
31             use Try::Tiny;
32              
33             use String::Formatter (
34             method_stringf => {
35             -as => '_format_branch',
36             codes => {
37             b => sub { (shift->name_rev( '--name-only', 'HEAD' ))[0] },
38             },
39             },
40             method_stringf => {
41             -as => '_format_message',
42             codes => {
43             b => sub { (shift->_git->name_rev( '--name-only', 'HEAD' ))[0] },
44             h => sub { (shift->_git->rev_parse( '--short', 'HEAD' ))[0] },
45             H => sub { (shift->_git->rev_parse('HEAD'))[0] },
46             t => sub { shift->zilla->is_trial ? '-TRIAL' : '' },
47             v => sub { shift->zilla->version },
48             }
49             }
50             );
51              
52             # debugging...
53             #use Smart::Comments '###';
54              
55             with 'Dist::Zilla::Role::Releaser';
56             with 'Dist::Zilla::Role::Git::Repo';
57              
58             # -- attributes
59              
60             has release_branch => ( ro, isa => Str, default => 'release', required => 1 );
61             has release_message => ( ro, isa => Str, default => 'build release %v', required => 1 );
62             has build_root => ( rw, coerce => 1, isa => Dir );
63             has _git => (rw, weak_ref => 1);
64              
65             # -- role implementation
66              
67             sub release {
68             my ( $self, $args) = @_;
69              
70             $self->_commit_build( $args, $self->release_branch, $self->release_message );
71             }
72              
73             sub _commit_build {
74             my ( $self, undef, $branch, $message ) = @_;
75              
76             return unless $branch;
77              
78             my $tmp_dir = File::Temp->newdir( CLEANUP => 1) ;
79             my $src = Git::Wrapper->new( $self->repo_root );
80             $self->_git($src);
81              
82             my $target_branch = _format_branch( $branch, $src );
83             #my $dir = $self->build_root;
84             my $dir = dir($self->zilla->root, $self->zilla->name . '-' . $self->zilla->version);
85              
86             # returns the sha1 of the created tree object
87             my $tree = $self->_create_tree($src, $dir);
88              
89             my ($last_build_tree) = try { $src->rev_parse("$target_branch^{tree}") };
90             $last_build_tree ||= 'none';
91              
92             ### $last_build_tree
93             if ($tree eq $last_build_tree) {
94              
95             $self->log("No changes since the last build; not committing");
96             return;
97             }
98              
99             my @parents = grep {
100             eval { $src->rev_parse({ 'q' => 1, 'verify'=>1}, $_ ) }
101             } $target_branch;
102              
103             ### @parents
104              
105             my $this_message = _format_message( $message, $self );
106             my @commit = $src->commit_tree( { -STDIN => $this_message }, $tree, map { ( '-p' => $_) } @parents );
107              
108             ### @commit
109             $src->update_ref( 'refs/heads/' . $target_branch, $commit[0] );
110             }
111              
112             sub _create_tree {
113             my ($self, $repo, $fs_obj) = @_;
114              
115             ### called with: "$fs_obj"
116             if (!$fs_obj->is_dir) {
117              
118             my ($sha) = $repo->hash_object({ w => 1 }, "$fs_obj");
119             ### hashed: "$sha $fs_obj"
120             return $sha;
121             }
122              
123             my @entries;
124             for my $obj ($fs_obj->children) {
125              
126             ### working on: "$obj"
127             my $sha = $self->_create_tree($repo, $obj);
128             my $mode = sprintf('%o', $obj->stat->mode); # $obj->is_dir ? '040000' : '
129             my $type = $obj->is_dir ? 'tree' : 'blob';
130             my $name = $obj->basename;
131              
132             push @entries, "$mode $type $sha\t$name";
133             }
134              
135             ### @entries
136              
137             my ($sha) = $repo->mktree({ -STDIN => join("\n", @entries, q{}) });
138              
139             return $sha;
140             }
141              
142             1;
143              
144              
145             __END__
146             =pod
147              
148             =head1 NAME
149              
150             Dist::Zilla::Plugin::ACPS::Git::CommitBuild - checkin build results on separate branch
151              
152             =head1 VERSION
153              
154             version 0.30
155              
156             =head1 SYNOPSIS
157              
158             In your F<dist.ini>:
159              
160             [ACPS::Git::CommitBuild]
161             ; these are the defaults
162             release = release/%b
163             release_message = 'build release %v'
164              
165             =head1 DESCRIPTION
166              
167             Forked from [Git::CommitBuild] to do the action during release, not
168             after. Only operates on release, not on build.
169              
170             =head1 AUTHOR
171              
172             Graham Ollis <gollis@sesda3.com>
173              
174             =head1 COPYRIGHT AND LICENSE
175              
176             This software is copyright (c) 2012 by NASA GSFC.
177              
178             This is free software; you can redistribute it and/or modify it under
179             the same terms as the Perl 5 programming language system itself.
180              
181             =cut
182