... | ... |
@@ -312,12 +312,6 @@ sub description { |
312 | 312 |
} |
313 | 313 |
} |
314 | 314 |
|
315 |
-sub exists_repository { |
|
316 |
- my ($self, $user, $project) = @_; |
|
317 |
- |
|
318 |
- return -e $self->rep($user, $project); |
|
319 |
-} |
|
320 |
- |
|
321 | 315 |
sub file_type { |
322 | 316 |
my ($self, $mode) = @_; |
323 | 317 |
|
... | ... |
@@ -1329,6 +1323,12 @@ sub cmd { |
1329 | 1323 |
my $rep = "$home/$user/$project.git"; |
1330 | 1324 |
|
1331 | 1325 |
# Execute git command |
1326 |
+ return $self->cmd_rep($rep, @cmd); |
|
1327 |
+} |
|
1328 |
+ |
|
1329 |
+sub cmd_rep { |
|
1330 |
+ my ($self, $rep, @cmd) = @_; |
|
1331 |
+ |
|
1332 | 1332 |
return ($self->bin, "--git-dir=$rep", @cmd); |
1333 | 1333 |
} |
1334 | 1334 |
|
... | ... |
@@ -5,6 +5,7 @@ use Carp 'croak'; |
5 | 5 |
use File::Copy 'move'; |
6 | 6 |
use File::Path qw/mkpath rmtree/; |
7 | 7 |
use Mojo::JSON; |
8 |
+use File::Temp (); |
|
8 | 9 |
|
9 | 10 |
has 'app'; |
10 | 11 |
|
... | ... |
@@ -41,53 +42,110 @@ sub _create_project { |
41 | 42 |
sub _create_rep { |
42 | 43 |
my ($self, $user, $project, $opts) = @_; |
43 | 44 |
|
45 |
+ # Git |
|
44 | 46 |
my $git = $self->app->git; |
47 |
+ |
|
48 |
+ # Create temp repository |
|
49 |
+ my $temp_dir = File::Temp->newdir; |
|
50 |
+ my $temp_rep = "$temp_dir/remote.git"; |
|
51 |
+ mkdir $temp_rep |
|
52 |
+ or croak "Can't create directory $temp_rep: $!"; |
|
53 |
+ |
|
54 |
+ # Git init |
|
55 |
+ { |
|
56 |
+ my @git_init_cmd = $git->cmd_rep($temp_rep, 'init', '--bare'); |
|
57 |
+ open my $fh, "-|", @git_init_cmd |
|
58 |
+ or croak "Can't execute git init"; |
|
59 |
+ close $fh; |
|
60 |
+ } |
|
61 |
+ |
|
62 |
+ # Add git-daemon-export-ok |
|
63 |
+ { |
|
64 |
+ my $file = "$temp_rep/git-daemon-export-ok"; |
|
65 |
+ open my $fh, '>', $file |
|
66 |
+ or croak "Can't create git-daemon-export-ok: $!" |
|
67 |
+ } |
|
68 |
+ |
|
69 |
+ # HTTP support |
|
70 |
+ my @git_update_server_info_cmd = $git->cmd_rep( |
|
71 |
+ $temp_rep, |
|
72 |
+ '--bare', |
|
73 |
+ 'update-server-info' |
|
74 |
+ ); |
|
75 |
+ system(@git_update_server_info_cmd) == 0 |
|
76 |
+ or croak "Can't execute git --bare update-server-info"; |
|
77 |
+ move("$temp_rep/hooks/post-update.sample", "$temp_rep/hooks/post-update") |
|
78 |
+ or croak "Can't move post-update"; |
|
79 |
+ |
|
80 |
+ # Description |
|
81 |
+ if (my $description = $opts->{description}) { |
|
82 |
+ my $file = "$temp_rep/description"; |
|
83 |
+ open my $fh, '>', $file |
|
84 |
+ or croak "Can't open $file: $!"; |
|
85 |
+ print $fh $description |
|
86 |
+ or croak "Can't write $file: $!"; |
|
87 |
+ close $fh; |
|
88 |
+ } |
|
89 |
+ |
|
90 |
+ # Add README and commit |
|
91 |
+ if ($opts->{readme}) { |
|
92 |
+ # Create working directory |
|
93 |
+ my $temp_dir = File::Temp->newdir; |
|
94 |
+ my $temp_work = "$temp_dir/work.git"; |
|
95 |
+ mkdir $temp_work |
|
96 |
+ or croak "Can't create directory $temp_work: $!"; |
|
45 | 97 |
|
46 |
- my $rep_home = $git->rep_home; |
|
47 |
- my $rep = "$rep_home/$user/$project.git"; |
|
48 |
- eval { |
|
49 |
- # Repository |
|
50 |
- mkpath $rep; |
|
51 |
- |
|
52 | 98 |
# Git init |
53 |
- my @git_init_cmd = $git->cmd($user, $project, 'init', '--bare'); |
|
99 |
+ my @git_init_cmd = $git->cmd_rep($temp_work, 'init', '-q'); |
|
54 | 100 |
system(@git_init_cmd) == 0 |
55 | 101 |
or croak "Can't execute git init"; |
56 |
- |
|
57 |
- # Add git-daemon-export-ok |
|
58 |
- { |
|
59 |
- my $file = "$rep/git-daemon-export-ok"; |
|
60 |
- open my $fh, '>', $file |
|
61 |
- or croak "Can't create git-daemon-export-ok: $!" |
|
62 |
- } |
|
63 | 102 |
|
64 |
- # HTTP support |
|
65 |
- my @git_update_server_info_cmd = $git->cmd( |
|
66 |
- $user, |
|
67 |
- $project, |
|
68 |
- '--bare', |
|
69 |
- 'update-server-info' |
|
103 |
+ # Add README |
|
104 |
+ my $file = "$temp_work/README"; |
|
105 |
+ open my $fh, '>', $file |
|
106 |
+ or croak "Can't create $file: $!"; |
|
107 |
+ my @git_add_cmd = $git->cmd_rep( |
|
108 |
+ $temp_work, |
|
109 |
+ "--work-tree=$temp_work", |
|
110 |
+ 'add', |
|
111 |
+ 'README' |
|
70 | 112 |
); |
71 |
- system(@git_update_server_info_cmd) == 0 |
|
72 |
- or croak "Can't execute git --bare update-server-info"; |
|
73 |
- move("$rep/hooks/post-update.sample", "$rep/hooks/post-update") |
|
74 |
- or croak "Can't move post-update"; |
|
113 |
+ system(@git_add_cmd) == 0 |
|
114 |
+ or croak "Can't execute git add"; |
|
75 | 115 |
|
76 |
- # Description |
|
77 |
- if (my $description = $opts->{description}) { |
|
78 |
- my $file = "$rep/description"; |
|
79 |
- open my $fh, '>', $file |
|
80 |
- or croak "Can't open $file: $!"; |
|
81 |
- print $fh $description |
|
82 |
- or croak "Can't write $file: $!"; |
|
83 |
- close $fh; |
|
116 |
+ # Commit |
|
117 |
+ my @git_commit_cmd = $git->cmd_rep( |
|
118 |
+ $temp_work, |
|
119 |
+ "--work-tree=$temp_work", |
|
120 |
+ 'commit', |
|
121 |
+ '-q', |
|
122 |
+ '-m', |
|
123 |
+ 'first commit' |
|
124 |
+ ); |
|
125 |
+ system(@git_commit_cmd) == 0 |
|
126 |
+ or croak "Can't execute git commit"; |
|
127 |
+ |
|
128 |
+ # Push |
|
129 |
+ { |
|
130 |
+ my @git_push_cmd = $git->cmd_rep( |
|
131 |
+ $temp_work, |
|
132 |
+ "--work-tree=$temp_work", |
|
133 |
+ 'push', |
|
134 |
+ '-q', |
|
135 |
+ $temp_rep, |
|
136 |
+ 'master' |
|
137 |
+ ); |
|
138 |
+ # (This is bad, but --quiet option can't supress in old git) |
|
139 |
+ my $git_push_cmd = join(' ', @git_push_cmd); |
|
140 |
+ system("$git_push_cmd 2> /dev/null") == 0 |
|
141 |
+ or croak "Can't execute git push"; |
|
84 | 142 |
} |
85 |
- }; |
|
86 |
- if ($@) { |
|
87 |
- my $error = $@; |
|
88 |
- eval { $self->_delete_rep($user, $project) }; |
|
89 |
- croak $error; |
|
90 | 143 |
} |
144 |
+ |
|
145 |
+ # Move temp rep to rep |
|
146 |
+ my $rep = $git->rep($user, $project); |
|
147 |
+ move $temp_rep, $rep |
|
148 |
+ or croak "Can't move $temp_rep to $rep: $!"; |
|
91 | 149 |
} |
92 | 150 |
|
93 | 151 |
sub delete_project { |
... | ... |
@@ -158,6 +216,8 @@ sub rename_project { |
158 | 216 |
return 1; |
159 | 217 |
} |
160 | 218 |
|
219 |
+sub exists_project { shift->_exists_project(@_) } |
|
220 |
+ |
|
161 | 221 |
sub _exists_project { |
162 | 222 |
my ($self, $user, $project) = @_; |
163 | 223 |
|
... | ... |
@@ -20,6 +20,9 @@ |
20 | 20 |
], |
21 | 21 |
description => [ |
22 | 22 |
'any' |
23 |
+ ], |
|
24 |
+ readme => {require => 0} => [ |
|
25 |
+ 'any' |
|
23 | 26 |
] |
24 | 27 |
]; |
25 | 28 |
my $validator = app->validator; |
... | ... |
@@ -37,17 +40,19 @@ |
37 | 40 |
my $user = session('user_id'); |
38 | 41 |
my $project = $data->{project}; |
39 | 42 |
my $description = $data->{description}; |
40 |
- |
|
41 |
- if ($git->exists_repository($user, $project)) { |
|
43 |
+ my $readme = $data->{readme}; |
|
44 |
+ |
|
45 |
+ my $manager = app->manager; |
|
46 |
+ if ($manager->exists_project($user, $project)) { |
|
42 | 47 |
$errors = ['Repositry already exists']; |
43 | 48 |
} |
44 | 49 |
else { |
45 | 50 |
# Create repository |
46 | 51 |
eval { |
47 |
- app->manager->create_project( |
|
52 |
+ $manager->create_project( |
|
48 | 53 |
$user, |
49 | 54 |
$project, |
50 |
- {description => $description} |
|
55 |
+ {description => $description, readme => $readme} |
|
51 | 56 |
); |
52 | 57 |
}; |
53 | 58 |
|
... | ... |
@@ -59,7 +64,6 @@ |
59 | 64 |
$self->redirect_to("/$user/$project"); |
60 | 65 |
return 1; |
61 | 66 |
} |
62 |
- |
|
63 | 67 |
} |
64 | 68 |
} |
65 | 69 |
else { $errors = $vresult->messages } |
... | ... |
@@ -85,6 +89,13 @@ |
85 | 89 |
|
86 | 90 |
<div><b>Description</b> (optional)</div> |
87 | 91 |
<div><%= input_tag 'description', type => 'text', style => 'width:600px' %></div> |
92 |
+ |
|
93 |
+ <div> |
|
94 |
+ <label class="checkbox" style="margin-bottom:0"> |
|
95 |
+ <%= check_box readme => 1 %><b>Initialize this repository with a README</b> |
|
96 |
+ </label> |
|
97 |
+ </div> |
|
98 |
+ <div class="muted" style="margin-bottom:10px;margin-left:20px">This will allow you to git clone the repository immediately.</div> |
|
88 | 99 |
|
89 | 100 |
<input type="submit" class="btn" value="Create repository"> |
90 | 101 |
</form> |