File Coverage

blib/lib/Git/Flux/Command/init.pm
Criterion Covered Total %
statement 15 112 13.3
branch 0 60 0.0
condition 0 46 0.0
subroutine 5 9 55.5
pod 1 1 100.0
total 21 228 9.2


line stmt bran cond sub pod time code
1             package Git::Flux::Command::init;
2              
3 5     5   3658 use strict;
  5         10  
  5         189  
4 5     5   24 use warnings;
  5         10  
  5         160  
5 5     5   24 use mixin::with 'Git::Flux';
  5         9  
  5         34  
6 5     5   12189 use Try::Tiny;
  5         8234  
  5         294  
7 5     5   5339 use Term::ReadLine;
  5         25009  
  5         8426  
8              
9             sub init {
10 0     0 1   my $self = shift;
11 0           my $force = shift;
12 0           my $dir = $self->{'dir'};
13 0           my $term = Term::ReadLine->new('Gitflux');
14              
15 0           $term->ornaments(0);
16              
17 0           my ( $failed, $repo, $master_branch, $devel_branch, $prefix );
18              
19 0 0         if ($force) {
20 0 0         $force eq '-f' or die "Improper opt to init: $force\n";
21             }
22              
23             try {
24 0     0     $repo = $self->{'repo'} =
25             Git::Repository->new( work_tree => $dir ) }
26             catch {
27 0     0     $repo = $self->{'repo'} =
28             Git::Repository->create( 'init' => { cwd => $dir } );
29             } finally {
30 0 0   0     @_ and $failed++;
31 0           };
32              
33 0 0         unless ($failed) {
34 0 0         $self->git_repo_is_headless or $self->require_clean_working_tree;
35             }
36              
37 0 0 0       if ( $self->gitflux_is_initialized && ! $force ) {
38 0           die "Already initialized for gitflux.\n" .
39             "To force reinitialization, use: git flux init -f\n";
40             }
41              
42             # set up master branch
43 0 0 0       if ( $self->gitflux_has_master_configured && ! $force ) {
44 0           $master_branch =
45             $repo->run( config => qw/ --get gitflux.branch.master / );
46             } else {
47             # Two cases are distinguished:
48             # 1. A fresh git repo (without any branches)
49             # We will create a new master/devel branch for the user
50             # 2. Some branches do already exist
51             # We will disallow creation of new master/devel branches and
52             # rather allow to use existing branches for git-flow.
53 0           my ( $check_existence, $default_suggestion );
54 0           my @local_branches = $self->git_local_branches;
55              
56 0 0         if ( @local_branches == 0 ) {
57 0           print "No branches exist yet. Base branches must be created now.\n";
58 0           $check_existence = 0;
59 0   0       $default_suggestion = $repo->run(
60             config => qw/ --get gitflux.branch.master /
61             ) || 'master';
62             } else {
63 0           print "\nWhich branch should be used for production releases?\n";
64 0           print map { $_=~ s/^(.*)$/ - $1/; $_; } $self->git_local_branches;
  0            
  0            
65 0           print "\n";
66              
67 0           $check_existence = 1;
68 0           my @guesses = (
69             $repo->run( config => qw/ --get gitflux.branch.master / ),
70             qw/ production main master /
71             );
72              
73 0           foreach my $guess (@guesses) {
74 0 0         if ( $self->git_local_branch_exists($guess) ) {
75 0           $default_suggestion = $guess;
76 0           last;
77             }
78             }
79             }
80              
81 0           my $prompt = 'Branch name for production releases: ' .
82             "[$default_suggestion] ";
83              
84 0 0         my $answer = $self->is_interactive ?
85             $term->readline($prompt) :
86             $default_suggestion;
87              
88 0   0       $master_branch = $answer || $default_suggestion;
89              
90 0 0         if ($check_existence) {
91 0 0         $self->git_local_branch_exists($master_branch)
92             or die "Local branch '$master_branch' does not exist.\n";
93             }
94              
95 0           $repo->run( config => 'gitflux.branch.master', $master_branch );
96             }
97              
98             # set up devel branch
99 0 0 0       if ( $self->gitflux_has_devel_configured && ! $force ) {
100 0           $devel_branch = $repo->run( config => qw/--get gitflux.branch.devel/ );
101             } else {
102             # Again, the same two cases as with the master selection are
103             # considered (fresh repo or repo that contains branches)
104 0           my ( $check_existence, $default_suggestion );
105 0           my @local_branches_wo_master = grep { $_ !~ /^\Q$master_branch\E$/ }
  0            
106             $self->git_local_branches;
107              
108 0 0         if ( @local_branches_wo_master == 0 ) {
109 0           $check_existence = 0;
110 0   0       $default_suggestion = $repo->run(
111             config => qw/ --get gitflux.branch.devel /
112             ) || 'devel';
113             } else {
114 0           print "\nWhich branch should be used for integration of the " .
115             "\"next release\"?\n";
116 0           print map { $_=~ s/^(.*)$/ - $1/; $_; }
  0            
  0            
117 0           grep { $_ !~ /^\Q$master_branch$/ } $self->git_local_branches;
118 0           print "\n";
119              
120 0           $check_existence = 1;
121 0           my @guesses = (
122             $repo->run( config => qw/ --get gitflux.branch.devel / ),
123             qw/ devel develop int integration master /
124             );
125              
126 0           foreach my $guess (@guesses) {
127 0 0         if ( $self->git_local_branch_exists($guess) ) {
128 0           $default_suggestion = $guess;
129 0           last;
130             }
131             }
132             }
133              
134             # on and on
135              
136 0           my $prompt = 'Branch name for "next release" development: ' .
137             "[$default_suggestion] ";
138              
139 0 0         my $answer = $self->is_interactive ?
140             $term->readline($prompt) :
141             $default_suggestion;
142              
143 0   0       $devel_branch = $answer || $default_suggestion;
144              
145 0 0         if ( $master_branch eq $devel_branch ) {
146 0           die "Production and integration branches should differ.\n";
147             }
148              
149 0 0         if ($check_existence) {
150 0 0         $self->git_local_branch_exists($devel_branch)
151             or die "Local branch '$devel_branch' does not exist.\n";
152             }
153              
154 0           $repo->run( config => 'gitflux.branch.devel', $devel_branch );
155             }
156              
157             # Creation of HEAD
158             # ----------------
159             # We create a HEAD now, if it does not exist yet (in a fresh repo). We need
160             # it to be able to create new branches.
161 0           my $created_gitflux_branch;
162 0           my $cmd = $repo->command( 'rev-parse' => qw/ --quiet --verify HEAD / );
163 0           $cmd->close;
164              
165 0 0         if ( $cmd->exit == 1 ) {
166 0           $repo->run( 'symbolic-ref' => 'HEAD', "refs/heads/$master_branch" );
167 0           $repo->run( commit => qw/--allow-empty --quiet -m/, 'Initial commit' );
168 0           $created_gitflux_branch = 1;
169             }
170              
171             # Creation of master
172             # ------------------
173             # At this point, there always is a master branch: either it existed already
174             # (and was picked interactively as the production branch) or it has just
175             # been created in a fresh repo
176              
177             # Creation of devel
178             # -------------------
179             # The devel branch possibly does not exist yet. This is the case when,
180             # in a git init'ed repo with one or more commits, master was picked as the
181             # default production branch and devel was "created". We should create
182             # the devel branch now in that case (we base it on master, of course)
183 0 0         if ( ! $self->git_local_branch_exists($devel_branch) ) {
184 0           $repo->run( branch => '--no-track', $devel_branch, $master_branch );
185 0           $created_gitflux_branch = 1;
186             }
187              
188             # assert gitflux initialization
189 0           $self->gitflux_is_initialized;
190              
191             # switch to devel if newly created
192 0 0         if ($created_gitflux_branch) {
193 0           $repo->run( checkout => '-q', $devel_branch );
194             }
195              
196             # finally, ask the user for naming conventions (branch and tag prefixes)
197 0 0 0       if (
      0        
      0        
      0        
      0        
198             $force ||
199             ! $repo->run( config => qw/--get gitflux.prefix.feature/ ) ||
200             ! $repo->run( config => qw/--get gitflux.prefix.release/ ) ||
201             ! $repo->run( config => qw/--get gitflux.prefix.hotfix/ ) ||
202             ! $repo->run( config => qw/--get gitflux.prefix.support/ ) ||
203             ! $repo->run( config => qw/--get gitflux.prefix.versiontag/ )
204             ) {
205 0           print "\nHow to name your supporting branch prefixes?\n";
206             }
207              
208 0           foreach my $type ( qw/ feature release hotfix support versiontag / ) {
209 0           my $cmd = $repo->command( config => '--get', "gitflux.prefix.$type" );
210 0           $cmd->close;
211              
212 0           my $prefix = '';
213              
214 0 0 0       if ( $cmd->exit == 1 or $force ) {
215 0   0       my $default_suggestion = $repo->run(
216             config => '--get', "gitflux.prefix.$type"
217             ) || "$type/";
218              
219             # version tag has its own default suggestion
220 0 0         $type eq 'versiontag' and $default_suggestion = 'v';
221              
222             # version tag has its own prompt text
223 0 0         my $prompt = $type eq 'versiontag' ?
224             "Version tag prefix? [$default_suggestion] " :
225             ucfirst $type . " branches? [$default_suggestion] ";
226              
227 0 0         my $answer = $self->is_interactive ?
228             $term->readline($prompt) :
229             $default_suggestion;
230              
231 0 0         defined $answer and chomp $answer;
232 0 0 0       ( defined $answer and $answer ne '' )
233             or $answer = $default_suggestion;
234              
235             # - means empty prefix, otherwise take the answer (or default)
236 0 0 0       ( defined $answer and $answer eq '-' )
237             or $prefix = $answer;
238              
239 0           $repo->run( config => "gitflux.prefix.$type", $prefix );
240             }
241             }
242             }
243              
244             1;
245              
246             __END__