Merge pull request #218 from abf/rosa-build:214-delete-and-restore-branches
#214: Delete/Restore branches
This commit is contained in:
commit
c33588f620
6
Gemfile
6
Gemfile
|
@ -59,6 +59,12 @@ gem 'rest-client', '~> 1.6.6'
|
||||||
gem 'attr_encrypted', '1.2.1'
|
gem 'attr_encrypted', '1.2.1'
|
||||||
gem "gemoji", "~> 1.2.1", require: 'emoji/railtie'
|
gem "gemoji", "~> 1.2.1", require: 'emoji/railtie'
|
||||||
|
|
||||||
|
# AngularJS related stuff
|
||||||
|
gem 'angularjs-rails'
|
||||||
|
gem 'ng-rails-csrf'
|
||||||
|
gem 'momentjs-rails'
|
||||||
|
gem 'angular-i18n', '0.1.2'
|
||||||
|
|
||||||
group :assets do
|
group :assets do
|
||||||
gem 'sass-rails', '~> 3.2.5'
|
gem 'sass-rails', '~> 3.2.5'
|
||||||
gem 'coffee-rails', '~> 3.2.2'
|
gem 'coffee-rails', '~> 3.2.2'
|
||||||
|
|
120
Gemfile.lock
120
Gemfile.lock
|
@ -58,36 +58,37 @@ GEM
|
||||||
json
|
json
|
||||||
ancestry (1.3.0)
|
ancestry (1.3.0)
|
||||||
activerecord (>= 2.3.14)
|
activerecord (>= 2.3.14)
|
||||||
|
angular-i18n (0.1.2)
|
||||||
|
angularjs-rails (1.0.7)
|
||||||
arel (3.0.2)
|
arel (3.0.2)
|
||||||
attr_encrypted (1.2.1)
|
attr_encrypted (1.2.1)
|
||||||
encryptor (>= 1.1.1)
|
encryptor (>= 1.1.1)
|
||||||
bcrypt-ruby (3.0.1)
|
bcrypt-ruby (3.1.1)
|
||||||
better_errors (0.8.0)
|
better_errors (0.9.0)
|
||||||
coderay (>= 1.0.0)
|
coderay (>= 1.0.0)
|
||||||
erubis (>= 2.6.6)
|
erubis (>= 2.6.6)
|
||||||
binding_of_caller (0.7.1)
|
binding_of_caller (0.7.2)
|
||||||
debug_inspector (>= 0.0.1)
|
debug_inspector (>= 0.0.1)
|
||||||
blankslate (3.1.2)
|
blankslate (3.1.2)
|
||||||
bluepill (0.0.62)
|
bluepill (0.0.66)
|
||||||
activesupport (>= 3.0.0)
|
activesupport (>= 3.0.0, < 4.0.0)
|
||||||
daemons (~> 1.1.4)
|
daemons (~> 1.1.4)
|
||||||
i18n (>= 0.5.0)
|
i18n (>= 0.5.0)
|
||||||
state_machine (~> 1.1.0)
|
state_machine (~> 1.1)
|
||||||
bourne (1.4.0)
|
|
||||||
mocha (~> 0.13.2)
|
|
||||||
builder (3.0.4)
|
builder (3.0.4)
|
||||||
|
callsite (0.0.11)
|
||||||
cancan (1.6.7)
|
cancan (1.6.7)
|
||||||
cape (1.7.0)
|
cape (1.7.0)
|
||||||
capistrano (2.14.2)
|
capistrano (2.15.5)
|
||||||
highline
|
highline
|
||||||
net-scp (>= 1.0.0)
|
net-scp (>= 1.0.0)
|
||||||
net-sftp (>= 2.0.0)
|
net-sftp (>= 2.0.0)
|
||||||
net-ssh (>= 2.0.14)
|
net-ssh (>= 2.0.14)
|
||||||
net-ssh-gateway (>= 1.1.0)
|
net-ssh-gateway (>= 1.1.0)
|
||||||
capistrano_colors (0.5.5)
|
capistrano_colors (0.5.5)
|
||||||
charlock_holmes (0.6.9.2)
|
charlock_holmes (0.6.9.4)
|
||||||
chronic (0.6.7)
|
chronic (0.6.7)
|
||||||
chunky_png (1.2.7)
|
chunky_png (1.2.8)
|
||||||
cocaine (0.4.2)
|
cocaine (0.4.2)
|
||||||
coderay (1.0.9)
|
coderay (1.0.9)
|
||||||
coffee-rails (3.2.2)
|
coffee-rails (3.2.2)
|
||||||
|
@ -96,7 +97,7 @@ GEM
|
||||||
coffee-script (2.2.0)
|
coffee-script (2.2.0)
|
||||||
coffee-script-source
|
coffee-script-source
|
||||||
execjs
|
execjs
|
||||||
coffee-script-source (1.6.2)
|
coffee-script-source (1.6.3)
|
||||||
compass (0.12.2)
|
compass (0.12.2)
|
||||||
chunky_png (~> 1.2)
|
chunky_png (~> 1.2)
|
||||||
fssm (>= 0.2.7)
|
fssm (>= 0.2.7)
|
||||||
|
@ -106,7 +107,7 @@ GEM
|
||||||
creole (0.5.0)
|
creole (0.5.0)
|
||||||
daemons (1.1.9)
|
daemons (1.1.9)
|
||||||
debug_inspector (0.0.2)
|
debug_inspector (0.0.2)
|
||||||
devise (2.2.3)
|
devise (2.2.4)
|
||||||
bcrypt-ruby (~> 3.0)
|
bcrypt-ruby (~> 3.0)
|
||||||
orm_adapter (~> 0.1)
|
orm_adapter (~> 0.1)
|
||||||
railties (~> 3.1)
|
railties (~> 3.1)
|
||||||
|
@ -156,9 +157,9 @@ GEM
|
||||||
activesupport (>= 3.1, < 4.1)
|
activesupport (>= 3.1, < 4.1)
|
||||||
haml (~> 3.1)
|
haml (~> 3.1)
|
||||||
railties (>= 3.1, < 4.1)
|
railties (>= 3.1, < 4.1)
|
||||||
hashie (1.2.0)
|
hashie (2.0.5)
|
||||||
highline (1.6.15)
|
highline (1.6.19)
|
||||||
hike (1.2.1)
|
hike (1.2.3)
|
||||||
hirb (0.7.1)
|
hirb (0.7.1)
|
||||||
httpauth (0.2.0)
|
httpauth (0.2.0)
|
||||||
i18n (0.6.1)
|
i18n (0.6.1)
|
||||||
|
@ -176,11 +177,10 @@ GEM
|
||||||
libv8 (3.3.10.4)
|
libv8 (3.3.10.4)
|
||||||
macaddr (1.6.1)
|
macaddr (1.6.1)
|
||||||
systemu (~> 2.5.0)
|
systemu (~> 2.5.0)
|
||||||
mail (2.5.3)
|
mail (2.5.4)
|
||||||
i18n (>= 0.4.0)
|
|
||||||
mime-types (~> 1.16)
|
mime-types (~> 1.16)
|
||||||
treetop (~> 1.4.8)
|
treetop (~> 1.4.8)
|
||||||
mailcatcher (0.5.11)
|
mailcatcher (0.5.12)
|
||||||
activesupport (~> 3.0)
|
activesupport (~> 3.0)
|
||||||
eventmachine (~> 1.0.0)
|
eventmachine (~> 1.0.0)
|
||||||
haml (>= 3.1, < 5)
|
haml (>= 3.1, < 5)
|
||||||
|
@ -191,41 +191,44 @@ GEM
|
||||||
thin (~> 1.5.0)
|
thin (~> 1.5.0)
|
||||||
meta-tags (1.2.6)
|
meta-tags (1.2.6)
|
||||||
actionpack
|
actionpack
|
||||||
meta_request (0.2.3)
|
meta_request (0.2.7)
|
||||||
|
callsite
|
||||||
rack-contrib
|
rack-contrib
|
||||||
railties
|
railties
|
||||||
metaclass (0.0.1)
|
mime-types (1.23)
|
||||||
mime-types (1.21)
|
mini_portile (0.5.1)
|
||||||
mocha (0.13.3)
|
|
||||||
metaclass (~> 0.0.1)
|
|
||||||
mock_redis (0.6.2)
|
mock_redis (0.6.2)
|
||||||
multi_json (1.7.5)
|
momentjs-rails (2.0.0.2)
|
||||||
|
railties (>= 3.1)
|
||||||
|
multi_json (1.7.7)
|
||||||
multipart-post (1.2.0)
|
multipart-post (1.2.0)
|
||||||
mustache (0.99.4)
|
mustache (0.99.4)
|
||||||
net-scp (1.1.0)
|
net-scp (1.1.2)
|
||||||
net-ssh (>= 2.6.5)
|
net-ssh (>= 2.6.5)
|
||||||
net-sftp (2.1.1)
|
net-sftp (2.1.2)
|
||||||
net-ssh (>= 2.6.5)
|
net-ssh (>= 2.6.5)
|
||||||
net-ssh (2.6.6)
|
net-ssh (2.6.8)
|
||||||
net-ssh-gateway (1.2.0)
|
net-ssh-gateway (1.2.0)
|
||||||
net-ssh (>= 2.6.5)
|
net-ssh (>= 2.6.5)
|
||||||
newrelic_rpm (3.5.5.38)
|
newrelic_rpm (3.5.5.38)
|
||||||
nokogiri (1.5.9)
|
ng-rails-csrf (0.1.0)
|
||||||
|
nokogiri (1.6.0)
|
||||||
|
mini_portile (~> 0.5.0)
|
||||||
oauth2 (0.8.1)
|
oauth2 (0.8.1)
|
||||||
faraday (~> 0.8)
|
faraday (~> 0.8)
|
||||||
httpauth (~> 0.1)
|
httpauth (~> 0.1)
|
||||||
jwt (~> 0.1.4)
|
jwt (~> 0.1.4)
|
||||||
multi_json (~> 1.0)
|
multi_json (~> 1.0)
|
||||||
rack (~> 1.2)
|
rack (~> 1.2)
|
||||||
omniauth (1.1.3)
|
omniauth (1.1.4)
|
||||||
hashie (~> 1.2)
|
hashie (>= 1.2, < 3)
|
||||||
rack
|
rack
|
||||||
omniauth-facebook (1.4.1)
|
omniauth-facebook (1.4.1)
|
||||||
omniauth-oauth2 (~> 1.1.0)
|
omniauth-oauth2 (~> 1.1.0)
|
||||||
omniauth-github (1.1.0)
|
omniauth-github (1.1.1)
|
||||||
omniauth (~> 1.0)
|
omniauth (~> 1.0)
|
||||||
omniauth-oauth2 (~> 1.1)
|
omniauth-oauth2 (~> 1.1)
|
||||||
omniauth-google-oauth2 (0.1.13)
|
omniauth-google-oauth2 (0.2.0)
|
||||||
omniauth (~> 1.0)
|
omniauth (~> 1.0)
|
||||||
omniauth-oauth2
|
omniauth-oauth2
|
||||||
omniauth-oauth2 (1.1.1)
|
omniauth-oauth2 (1.1.1)
|
||||||
|
@ -283,13 +286,13 @@ GEM
|
||||||
rake (>= 0.8.7)
|
rake (>= 0.8.7)
|
||||||
rdoc (~> 3.4)
|
rdoc (~> 3.4)
|
||||||
thor (>= 0.14.6, < 2.0)
|
thor (>= 0.14.6, < 2.0)
|
||||||
raindrops (0.10.0)
|
raindrops (0.11.0)
|
||||||
rake (10.0.4)
|
rake (10.1.0)
|
||||||
rdiscount (2.0.7.1)
|
rdiscount (2.1.6)
|
||||||
rdoc (3.12.2)
|
rdoc (3.12.2)
|
||||||
json (~> 1.4)
|
json (~> 1.4)
|
||||||
redcarpet (2.2.2)
|
redcarpet (2.2.2)
|
||||||
redis (3.0.3)
|
redis (3.0.4)
|
||||||
redis-actionpack (3.2.3)
|
redis-actionpack (3.2.3)
|
||||||
actionpack (~> 3.2.3)
|
actionpack (~> 3.2.3)
|
||||||
redis-rack (~> 1.4.0)
|
redis-rack (~> 1.4.0)
|
||||||
|
@ -297,7 +300,7 @@ GEM
|
||||||
redis-activesupport (3.2.3)
|
redis-activesupport (3.2.3)
|
||||||
activesupport (~> 3.2.3)
|
activesupport (~> 3.2.3)
|
||||||
redis-store (~> 1.1.0)
|
redis-store (~> 1.1.0)
|
||||||
redis-namespace (1.2.1)
|
redis-namespace (1.3.0)
|
||||||
redis (~> 3.0.0)
|
redis (~> 3.0.0)
|
||||||
redis-rack (1.4.2)
|
redis-rack (1.4.2)
|
||||||
rack (~> 1.4.1)
|
rack (~> 1.4.1)
|
||||||
|
@ -324,7 +327,7 @@ GEM
|
||||||
actionmailer (~> 3.0)
|
actionmailer (~> 3.0)
|
||||||
rest-client (1.6.7)
|
rest-client (1.6.7)
|
||||||
mime-types (>= 1.16)
|
mime-types (>= 1.16)
|
||||||
rr (1.0.4)
|
rr (1.0.5)
|
||||||
rspec (2.11.0)
|
rspec (2.11.0)
|
||||||
rspec-core (~> 2.11.0)
|
rspec-core (~> 2.11.0)
|
||||||
rspec-expectations (~> 2.11.0)
|
rspec-expectations (~> 2.11.0)
|
||||||
|
@ -338,7 +341,7 @@ GEM
|
||||||
activesupport (>= 3.0)
|
activesupport (>= 3.0)
|
||||||
railties (>= 3.0)
|
railties (>= 3.0)
|
||||||
rspec (~> 2.11.0)
|
rspec (~> 2.11.0)
|
||||||
ruby-haml-js (0.0.3)
|
ruby-haml-js (0.0.4)
|
||||||
execjs
|
execjs
|
||||||
sprockets (>= 2.0.0)
|
sprockets (>= 2.0.0)
|
||||||
rubypython (0.5.3)
|
rubypython (0.5.3)
|
||||||
|
@ -346,28 +349,27 @@ GEM
|
||||||
ffi (~> 1.0.7)
|
ffi (~> 1.0.7)
|
||||||
russian (0.6.0)
|
russian (0.6.0)
|
||||||
i18n (>= 0.5.0)
|
i18n (>= 0.5.0)
|
||||||
rvm-capistrano (1.2.7)
|
rvm-capistrano (1.4.1)
|
||||||
capistrano (>= 2.0.0)
|
capistrano (>= 2.0.0)
|
||||||
sanitize (2.0.3)
|
sanitize (2.0.6)
|
||||||
nokogiri (>= 1.4.4, < 1.6)
|
nokogiri (>= 1.4.4)
|
||||||
sass (3.2.7)
|
sass (3.2.9)
|
||||||
sass-rails (3.2.6)
|
sass-rails (3.2.6)
|
||||||
railties (~> 3.2.0)
|
railties (~> 3.2.0)
|
||||||
sass (>= 3.1.10)
|
sass (>= 3.1.10)
|
||||||
tilt (~> 1.3)
|
tilt (~> 1.3)
|
||||||
shotgun (0.9)
|
shotgun (0.9)
|
||||||
rack (>= 1.0)
|
rack (>= 1.0)
|
||||||
shoulda (3.4.0)
|
shoulda (3.5.0)
|
||||||
shoulda-context (~> 1.0, >= 1.0.1)
|
shoulda-context (~> 1.0, >= 1.0.1)
|
||||||
shoulda-matchers (~> 1.0, >= 1.4.1)
|
shoulda-matchers (>= 1.4.1, < 3.0)
|
||||||
shoulda-context (1.0.2)
|
shoulda-context (1.1.4)
|
||||||
shoulda-matchers (1.5.4)
|
shoulda-matchers (2.2.0)
|
||||||
activesupport (>= 3.0.0)
|
activesupport (>= 3.0.0)
|
||||||
bourne (~> 1.3)
|
sinatra (1.4.3)
|
||||||
sinatra (1.3.6)
|
|
||||||
rack (~> 1.4)
|
rack (~> 1.4)
|
||||||
rack-protection (~> 1.3)
|
rack-protection (~> 1.4)
|
||||||
tilt (~> 1.3, >= 1.3.3)
|
tilt (~> 1.3, >= 1.3.4)
|
||||||
skinny (0.2.3)
|
skinny (0.2.3)
|
||||||
eventmachine (~> 1.0.0)
|
eventmachine (~> 1.0.0)
|
||||||
thin (~> 1.5.0)
|
thin (~> 1.5.0)
|
||||||
|
@ -377,7 +379,7 @@ GEM
|
||||||
rack (~> 1.0)
|
rack (~> 1.0)
|
||||||
tilt (~> 1.1, != 1.3.0)
|
tilt (~> 1.1, != 1.3.0)
|
||||||
sqlite3 (1.3.7)
|
sqlite3 (1.3.7)
|
||||||
state_machine (1.1.2)
|
state_machine (1.2.0)
|
||||||
stringex (1.4.0)
|
stringex (1.4.0)
|
||||||
systemu (2.5.2)
|
systemu (2.5.2)
|
||||||
therubyracer (0.10.2)
|
therubyracer (0.10.2)
|
||||||
|
@ -386,9 +388,9 @@ GEM
|
||||||
daemons (>= 1.0.9)
|
daemons (>= 1.0.9)
|
||||||
eventmachine (>= 0.12.6)
|
eventmachine (>= 0.12.6)
|
||||||
rack (>= 1.0.0)
|
rack (>= 1.0.0)
|
||||||
thor (0.17.0)
|
thor (0.18.1)
|
||||||
tilt (1.3.6)
|
tilt (1.4.1)
|
||||||
treetop (1.4.12)
|
treetop (1.4.14)
|
||||||
polyglot
|
polyglot
|
||||||
polyglot (>= 0.3.1)
|
polyglot (>= 0.3.1)
|
||||||
turbo-sprockets-rails3 (0.3.6)
|
turbo-sprockets-rails3 (0.3.6)
|
||||||
|
@ -407,7 +409,7 @@ GEM
|
||||||
macaddr (~> 1.0)
|
macaddr (~> 1.0)
|
||||||
vegas (0.1.11)
|
vegas (0.1.11)
|
||||||
rack (>= 1.0.0)
|
rack (>= 1.0.0)
|
||||||
warden (1.2.1)
|
warden (1.2.3)
|
||||||
rack (>= 1.0)
|
rack (>= 1.0)
|
||||||
whenever (0.7.3)
|
whenever (0.7.3)
|
||||||
activesupport (>= 2.3.4)
|
activesupport (>= 2.3.4)
|
||||||
|
@ -424,6 +426,8 @@ DEPENDENCIES
|
||||||
RedCloth
|
RedCloth
|
||||||
airbrake (~> 3.1.2)
|
airbrake (~> 3.1.2)
|
||||||
ancestry (~> 1.3.0)
|
ancestry (~> 1.3.0)
|
||||||
|
angular-i18n (= 0.1.2)
|
||||||
|
angularjs-rails
|
||||||
attr_encrypted (= 1.2.1)
|
attr_encrypted (= 1.2.1)
|
||||||
better_errors
|
better_errors
|
||||||
binding_of_caller
|
binding_of_caller
|
||||||
|
@ -453,7 +457,9 @@ DEPENDENCIES
|
||||||
meta-tags (~> 1.2.5)
|
meta-tags (~> 1.2.5)
|
||||||
meta_request
|
meta_request
|
||||||
mock_redis (= 0.6.2)
|
mock_redis (= 0.6.2)
|
||||||
|
momentjs-rails
|
||||||
newrelic_rpm (~> 3.5.5.38)
|
newrelic_rpm (~> 3.5.5.38)
|
||||||
|
ng-rails-csrf
|
||||||
omniauth
|
omniauth
|
||||||
omniauth-facebook
|
omniauth-facebook
|
||||||
omniauth-github
|
omniauth-github
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
var RosaABF = angular.module('RosaABF', ['ngResource', 'ng-rails-csrf', 'angular-i18n']);
|
||||||
|
|
||||||
|
var DateTimeFormatter = function() {
|
||||||
|
|
||||||
|
var UtcFormatter = function(api_time) {
|
||||||
|
return moment.utc(api_time * 1000).format('YYYY-MM-DD HH:mm:ss UTC');
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
utc : UtcFormatter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RosaABF.factory("DateTimeFormatter", DateTimeFormatter);
|
||||||
|
|
||||||
|
var LocalesHelper = function($locale) {
|
||||||
|
var locales = {
|
||||||
|
'ru' : 'ru-ru',
|
||||||
|
'en' : 'en-us'
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
setLocale: function(locale) {
|
||||||
|
$locale.id = locales[locale];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RosaABF.factory("LocalesHelper", ['$locale', LocalesHelper]);
|
|
@ -0,0 +1,70 @@
|
||||||
|
RosaABF.controller('ProjectRefsController', ['$scope', '$http', 'ApiProject', function($scope, $http, ApiProject) {
|
||||||
|
|
||||||
|
$scope.singleton = ApiProject.singleton;
|
||||||
|
$scope.branches = [];
|
||||||
|
$scope.tags = [];
|
||||||
|
|
||||||
|
$scope.project_id = null;
|
||||||
|
$scope.current_ref = null;
|
||||||
|
$scope.project_resource = null;
|
||||||
|
|
||||||
|
$scope.init = function(project_id, ref, locale) {
|
||||||
|
$scope.project_id = project_id;
|
||||||
|
$scope.current_ref = ref;
|
||||||
|
|
||||||
|
$scope.project_resource = ApiProject.resource.get({id: $scope.project_id}, function(results) {
|
||||||
|
$scope.project = new Project(results.project);
|
||||||
|
$scope.getRefs();
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.getRefs = function() {
|
||||||
|
|
||||||
|
$scope.project_resource.$refs({id: $scope.project_id}, function(results) {
|
||||||
|
$scope.tags = [];
|
||||||
|
$scope.branches = [];
|
||||||
|
_.each(results.refs_list, function(ref){
|
||||||
|
var result = new ProjectRef(ref);
|
||||||
|
if (result.isTag) {
|
||||||
|
if (result.ref == $scope.current_ref) {
|
||||||
|
$scope.tags.unshift(result);
|
||||||
|
} else {
|
||||||
|
$scope.tags.push(result);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (result.ref == $scope.current_ref) {
|
||||||
|
$scope.branches.unshift(result);
|
||||||
|
} else {
|
||||||
|
$scope.branches.push(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$scope.updateBranchesCount();
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.updateBranchesCount = function() {
|
||||||
|
$scope.singleton.project.branches_count = $scope.branches.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.destroy = function(branch) {
|
||||||
|
$scope.project_resource.$delete_branch(
|
||||||
|
{owner: $scope.project.owner.uname, project: $scope.project.name, ref: branch.ref},
|
||||||
|
function() { // on success
|
||||||
|
var i = $scope.branches.indexOf(branch);
|
||||||
|
if(i != -1) { $scope.branches.splice(i, 1); }
|
||||||
|
|
||||||
|
$scope.updateBranchesCount();
|
||||||
|
// Removes branch from "Current branch/tag:" select box
|
||||||
|
$('#branch_selector option').filter(function() {
|
||||||
|
return this.value.match('.*\/branches\/' + branch.ref + '$');
|
||||||
|
}).remove();
|
||||||
|
}, function () { // on error
|
||||||
|
$scope.getRefs();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}]);
|
9
app/assets/javascripts/angularjs/controllers/project_repo_block_controller.js
vendored
Normal file
9
app/assets/javascripts/angularjs/controllers/project_repo_block_controller.js
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
RosaABF.controller('ProjectRepoBlockController', ['$scope', 'ApiProject', function($scope, ApiProject) {
|
||||||
|
|
||||||
|
$scope.singleton = ApiProject.singleton;
|
||||||
|
|
||||||
|
$scope.init = function(branches) {
|
||||||
|
$scope.singleton.project.branches_count = branches;
|
||||||
|
}
|
||||||
|
|
||||||
|
}]);
|
|
@ -0,0 +1,98 @@
|
||||||
|
RosaABF.controller('PullRequestController',['$scope', '$http', 'ApiPullRequest', 'ApiProject', 'DateTimeFormatter', function($scope, $http, ApiPullRequest, ApiProject, DateTimeFormatter) {
|
||||||
|
|
||||||
|
$scope.project_id = null;
|
||||||
|
$scope.project_resource = null;
|
||||||
|
|
||||||
|
$scope.serial_id = null;
|
||||||
|
$scope.pull = null;
|
||||||
|
$scope.pull_resource = null;
|
||||||
|
|
||||||
|
$scope.merged_at = null;
|
||||||
|
$scope.closed_at = null;
|
||||||
|
$scope.branch = null;
|
||||||
|
|
||||||
|
$scope.can_delete_branch = false;
|
||||||
|
|
||||||
|
$scope.init = function(project_id, serial_id) {
|
||||||
|
$scope.project_id = project_id;
|
||||||
|
$scope.serial_id = serial_id;
|
||||||
|
$scope.getPullRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.getPullRequest = function() {
|
||||||
|
$scope.pull_resource = ApiPullRequest.resource.get(
|
||||||
|
{project_id: $scope.project_id, serial_id: $scope.serial_id},
|
||||||
|
function(results) {
|
||||||
|
$scope.pull = results.pull_request;
|
||||||
|
if ($scope.pull.merged_at) { $scope.merged_at = DateTimeFormatter.utc($scope.pull.merged_at); }
|
||||||
|
if ($scope.pull.closed_at) { $scope.closed_at = DateTimeFormatter.utc($scope.pull.closed_at); }
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// @param [from_ref] - sets only at first time
|
||||||
|
$scope.getBranch = function(from_ref) {
|
||||||
|
if (!$scope.project_resource) {
|
||||||
|
$scope.project_resource = ApiProject.resource.get({id: $scope.project_id});
|
||||||
|
}
|
||||||
|
// Fix: at first load
|
||||||
|
// Cannot read property 'from_ref' of null
|
||||||
|
if (!from_ref) { from_ref = $scope.pull.from_ref.ref; }
|
||||||
|
$scope.project_resource.$refs({id: $scope.project_id}, function(results) {
|
||||||
|
var branch = null;
|
||||||
|
_.each(results.refs_list, function(ref){
|
||||||
|
var result = new ProjectRef(ref);
|
||||||
|
if (!result.isTag && result.ref == from_ref) {
|
||||||
|
branch = result;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$scope.branch = branch;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.reopen = function() {
|
||||||
|
$scope.pull.status = 'reopen';
|
||||||
|
$scope.pull_resource.$update(function() {
|
||||||
|
$scope.getPullRequest();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.close = function() {
|
||||||
|
$scope.pull.status = 'close';
|
||||||
|
$scope.pull_resource.$update(function() {
|
||||||
|
$scope.getPullRequest();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.merge = function() {
|
||||||
|
$scope.pull_resource.$merge(function() {
|
||||||
|
$scope.getPullRequest();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.deleteBranch = function() {
|
||||||
|
$scope.project_resource.$delete_branch($scope.branch_params(),
|
||||||
|
function() { $scope.branch = null; }, // success
|
||||||
|
function() { $scope.getBranch(); } // error
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.restoreBranch = function() {
|
||||||
|
$scope.project_resource.$restore_branch($scope.branch_params(),
|
||||||
|
function() { $scope.getBranch(); }, // success
|
||||||
|
function() { $scope.getBranch(); } // error
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.branch_params = function() {
|
||||||
|
var project = $scope.pull.from_ref.project;
|
||||||
|
return {
|
||||||
|
owner: project.fullname.replace(/\/.*/, ''),
|
||||||
|
project: project.name,
|
||||||
|
ref: $scope.pull.from_ref.ref,
|
||||||
|
sha: $scope.pull.from_ref.sha
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}]);
|
|
@ -0,0 +1,7 @@
|
||||||
|
RosaABF.controller('RosaABFController', ['$scope', 'LocalesHelper', function($scope, LocalesHelper) {
|
||||||
|
|
||||||
|
$scope.init = function(locale) {
|
||||||
|
LocalesHelper.setLocale(locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
}]);
|
|
@ -0,0 +1,24 @@
|
||||||
|
var _locales = {
|
||||||
|
'ru-ru': {
|
||||||
|
'project.total_branches': [
|
||||||
|
'Всего %1 ветка',
|
||||||
|
'Всего %1 ветки',
|
||||||
|
'Всего %1 веток'
|
||||||
|
],
|
||||||
|
'project.total_tags': [
|
||||||
|
'Всего %1 тег',
|
||||||
|
'Всего %1 тега',
|
||||||
|
'Всего %1 тегов'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
'en-us': {
|
||||||
|
'project.total_branches': [
|
||||||
|
'Total %1 branch',
|
||||||
|
'Total %1 branches'
|
||||||
|
],
|
||||||
|
'project.total_tags': [
|
||||||
|
'Total %1 tag',
|
||||||
|
'Total %1 tags'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,14 @@
|
||||||
|
var Project = function(atts){
|
||||||
|
var self = this;
|
||||||
|
var initialSettings = atts || {};
|
||||||
|
//initial settings if passed in
|
||||||
|
for(var setting in initialSettings){
|
||||||
|
if(initialSettings.hasOwnProperty(setting))
|
||||||
|
self[setting] = initialSettings[setting];
|
||||||
|
};
|
||||||
|
|
||||||
|
//with some logic...
|
||||||
|
|
||||||
|
//return the scope-safe instance
|
||||||
|
return self;
|
||||||
|
};
|
|
@ -0,0 +1,29 @@
|
||||||
|
var ProjectRef = function(atts) {
|
||||||
|
var self = this;
|
||||||
|
var initialSettings = atts || {};
|
||||||
|
//initial settings if passed in
|
||||||
|
for(var setting in initialSettings){
|
||||||
|
if(initialSettings.hasOwnProperty(setting))
|
||||||
|
self[setting] = initialSettings[setting];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//with some logic...
|
||||||
|
self.isTag = self.object.type == 'tag';
|
||||||
|
|
||||||
|
self.path = function(project) {
|
||||||
|
return '/' + project.fullname + '/tree/' + self.ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.diff_path = function(project, current_ref) {
|
||||||
|
return '/' + project.fullname + '/diff/' + current_ref + '...' + self.ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.archive_path = function(project, type) {
|
||||||
|
return '/' + project.fullname + '/archive/' + project.name + '-' + self.ref + '.' + type;
|
||||||
|
}
|
||||||
|
|
||||||
|
//return the scope-safe instance
|
||||||
|
return self;
|
||||||
|
};
|
|
@ -0,0 +1,33 @@
|
||||||
|
RosaABF.factory("ApiProject", ['$resource', function($resource) {
|
||||||
|
|
||||||
|
var ProjectResource = $resource(
|
||||||
|
'/api/v1/projects/:id.json',
|
||||||
|
{id: '@project.id'},
|
||||||
|
{
|
||||||
|
refs: {
|
||||||
|
url: '/api/v1/projects/:id/refs_list.json',
|
||||||
|
method: 'GET',
|
||||||
|
isArray : false
|
||||||
|
},
|
||||||
|
delete_branch: {
|
||||||
|
url: '/:owner/:project/branches/:ref',
|
||||||
|
method: 'DELETE',
|
||||||
|
isArray : false
|
||||||
|
},
|
||||||
|
restore_branch: {
|
||||||
|
url: '/:owner/:project/branches/:ref', // ?sha=<sha>
|
||||||
|
method: 'PUT',
|
||||||
|
isArray : false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
resource : ProjectResource,
|
||||||
|
singleton : {
|
||||||
|
project : {
|
||||||
|
branches_count : 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}]);
|
|
@ -0,0 +1,25 @@
|
||||||
|
RosaABF.factory("ApiPullRequest", ['$resource', function($resource) {
|
||||||
|
|
||||||
|
var PullRequestResource = $resource(
|
||||||
|
'/api/v1/projects/:project_id/pull_requests/:serial_id.json',
|
||||||
|
{
|
||||||
|
project_id: '@pull_request.to_ref.project.id',
|
||||||
|
serial_id: '@pull_request.number'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
update: {
|
||||||
|
method: 'PUT',
|
||||||
|
isArray : false
|
||||||
|
},
|
||||||
|
merge: {
|
||||||
|
url: '/api/v1/projects/:project_id/pull_requests/:serial_id/merge.json',
|
||||||
|
method: 'PUT',
|
||||||
|
isArray: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
resource : PullRequestResource
|
||||||
|
}
|
||||||
|
}]);
|
|
@ -13,6 +13,16 @@
|
||||||
//= require backbone_rails_sync
|
//= require backbone_rails_sync
|
||||||
//= require backbone_datalink
|
//= require backbone_datalink
|
||||||
//= require backbone/rosa
|
//= require backbone/rosa
|
||||||
|
|
||||||
|
// require angular
|
||||||
|
//= require unstable/angular
|
||||||
|
// require angular-resource
|
||||||
|
//= require unstable/angular-resource
|
||||||
|
//= require ng-rails-csrf
|
||||||
|
//= require angular-i18n
|
||||||
|
//= require_tree ./angularjs
|
||||||
|
//= require moment
|
||||||
|
|
||||||
//= require_self
|
//= require_self
|
||||||
|
|
||||||
function disableNotifierCbx(global_cbx) {
|
function disableNotifierCbx(global_cbx) {
|
||||||
|
|
|
@ -744,7 +744,7 @@ div.admin-role {
|
||||||
padding-right: 10px;
|
padding-right: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
article a.right_floated {
|
.right_floated {
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
class Api::V1::ProjectsController < Api::V1::BaseController
|
class Api::V1::ProjectsController < Api::V1::BaseController
|
||||||
|
|
||||||
before_filter :authenticate_user!
|
before_filter :authenticate_user!
|
||||||
skip_before_filter :authenticate_user!, :only => [:get_id, :show, :refs] if APP_CONFIG['anonymous_access']
|
skip_before_filter :authenticate_user!, :only => [:get_id, :show, :refs_list] if APP_CONFIG['anonymous_access']
|
||||||
|
|
||||||
load_and_authorize_resource :project
|
load_and_authorize_resource :project
|
||||||
|
|
||||||
|
@ -23,6 +23,8 @@ class Api::V1::ProjectsController < Api::V1::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def refs_list
|
def refs_list
|
||||||
|
@refs = @project.repo.branches.sort_by(&:name) +
|
||||||
|
@project.repo.tags.select{ |t| t.commit }.sort_by(&:name).reverse
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
|
|
|
@ -78,7 +78,7 @@ class Api::V1::PullRequestsController < Api::V1::BaseController
|
||||||
if (action = pull_params[:status]) && %w(close reopen).include?(pull_params[:status])
|
if (action = pull_params[:status]) && %w(close reopen).include?(pull_params[:status])
|
||||||
if @pull.send("can_#{action}?")
|
if @pull.send("can_#{action}?")
|
||||||
@pull.set_user_and_time current_user
|
@pull.set_user_and_time current_user
|
||||||
need_check = true if action == 'reopen'
|
need_check = true if action == 'reopen' && @pull.valid?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
class Projects::Git::BaseController < Projects::BaseController
|
class Projects::Git::BaseController < Projects::BaseController
|
||||||
before_filter :authenticate_user!
|
before_filter :authenticate_user!
|
||||||
skip_before_filter :authenticate_user!, :only => [:show, :index, :blame, :raw, :archive, :diff, :tags, :branches] if APP_CONFIG['anonymous_access']
|
skip_before_filter :authenticate_user!, :only => [:show, :index, :blame, :raw, :archive, :diff, :tags, :branches] if APP_CONFIG['anonymous_access']
|
||||||
load_and_authorize_resource :project
|
|
||||||
|
|
||||||
|
load_and_authorize_resource :project
|
||||||
before_filter :set_treeish_and_path
|
before_filter :set_treeish_and_path
|
||||||
before_filter :set_branch_and_tree
|
before_filter :set_branch_and_tree
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,10 @@
|
||||||
class Projects::Git::TreesController < Projects::Git::BaseController
|
class Projects::Git::TreesController < Projects::Git::BaseController
|
||||||
before_filter lambda{redirect_to @project if params[:treeish] == @project.default_branch and params[:path].blank?}, :only => :show
|
before_filter lambda{redirect_to @project if params[:treeish] == @project.default_branch and params[:path].blank?}, :only => :show
|
||||||
skip_before_filter :set_branch_and_tree, :set_treeish_and_path, :only => :archive
|
skip_before_filter :set_branch_and_tree, :set_treeish_and_path, :only => :archive
|
||||||
|
before_filter lambda { raise Grit::NoSuchPathError if params[:treeish] != @branch.try(:name) }, :only => [:branch, :destroy]
|
||||||
|
|
||||||
|
skip_authorize_resource :project, :only => [:destroy, :restore_branch]
|
||||||
|
before_filter lambda { authorize!(:write, @project) }, :only => [:destroy, :restore_branch]
|
||||||
|
|
||||||
def show
|
def show
|
||||||
render('empty') and return if @project.is_empty?
|
render('empty') and return if @project.is_empty?
|
||||||
|
@ -28,14 +32,19 @@ class Projects::Git::TreesController < Projects::Git::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def tags
|
def tags
|
||||||
@tags = @project.repo.tags.select{ |t| t.commit }.sort_by(&:name).reverse
|
end
|
||||||
render 'refs'
|
|
||||||
|
def restore_branch
|
||||||
|
@project.restore_branch @treeish, params[:sha] if @treeish.present? && params[:sha].present?
|
||||||
|
render :nothing => true
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
status = @branch && @project.delete_branch(@branch, current_user) ? 200 : 422
|
||||||
|
render :nothing => true, :status => status
|
||||||
end
|
end
|
||||||
|
|
||||||
def branches
|
def branches
|
||||||
raise Grit::NoSuchPathError if params[:treeish] != @branch.try(:name) # get wrong branch name to nonempty project
|
|
||||||
@branches = @project.repo.branches.sort_by(&:name).select{ |b| b.name != @branch.name }.unshift(@branch).compact if @branch
|
|
||||||
render 'refs'
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -78,14 +78,6 @@ class Projects::PullRequestsController < Projects::BaseController
|
||||||
redirect_to project_pull_request_path(@pull.to_project, @pull)
|
redirect_to project_pull_request_path(@pull.to_project, @pull)
|
||||||
end
|
end
|
||||||
|
|
||||||
def merge
|
|
||||||
unless @pull.merge!(current_user)
|
|
||||||
flash.now[:error] = t('flash.pull_request.save_error')
|
|
||||||
flash.now[:warning] = @pull.errors.full_messages.join('. ')
|
|
||||||
end
|
|
||||||
redirect_to project_pull_request_path(@pull.to_project, @pull)
|
|
||||||
end
|
|
||||||
|
|
||||||
def show
|
def show
|
||||||
load_diff_commits_data
|
load_diff_commits_data
|
||||||
end
|
end
|
||||||
|
|
|
@ -8,9 +8,9 @@ module PullRequestHelper
|
||||||
(common_comments + pull_comments + commits).sort_by{ |c| c[0] }.map{ |c| c[1] }
|
(common_comments + pull_comments + commits).sort_by{ |c| c[0] }.map{ |c| c[1] }
|
||||||
end
|
end
|
||||||
|
|
||||||
def pull_status_label pull
|
def pull_status_label pull_status, options = {}
|
||||||
statuses = {'ready' => 'success', 'closed' => 'important', 'merged' => 'important', 'blocked' => 'warning'}
|
statuses = {'ready' => 'success', 'closed' => 'important', 'merged' => 'important', 'blocked' => 'warning'}
|
||||||
content_tag :span, t("projects.pull_requests.statuses.#{pull.status}"), :class => "state label-bootstrap label-#{statuses[pull.status]}"
|
content_tag :span, t("projects.pull_requests.statuses.#{pull_status}"), options.merge(:class => "state label-bootstrap label-#{statuses[pull_status]}")
|
||||||
end
|
end
|
||||||
|
|
||||||
def pull_status pull
|
def pull_status pull
|
||||||
|
|
|
@ -15,7 +15,7 @@ class Ability
|
||||||
# Shared rights between guests and registered users
|
# Shared rights between guests and registered users
|
||||||
can [:show, :archive], Project, :visibility => 'open'
|
can [:show, :archive], Project, :visibility => 'open'
|
||||||
can :get_id, Project, :visibility => 'open' # api
|
can :get_id, Project, :visibility => 'open' # api
|
||||||
can :archive, Project, :visibility => 'open'
|
can(:refs_list, Project) {|project| can? :show, project}
|
||||||
can :read, Issue, :project => {:visibility => 'open'}
|
can :read, Issue, :project => {:visibility => 'open'}
|
||||||
can [:read, :commits, :files], PullRequest, :to_project => {:visibility => 'open'}
|
can [:read, :commits, :files], PullRequest, :to_project => {:visibility => 'open'}
|
||||||
can :search, BuildList
|
can :search, BuildList
|
||||||
|
@ -74,7 +74,6 @@ class Ability
|
||||||
can(:destroy, Project) {|project| project.owner_type == 'Group' and project.owner.actors.exists?(:actor_type => 'User', :actor_id => user.id, :role => 'admin')}
|
can(:destroy, Project) {|project| project.owner_type == 'Group' and project.owner.actors.exists?(:actor_type => 'User', :actor_id => user.id, :role => 'admin')}
|
||||||
can :remove_user, Project
|
can :remove_user, Project
|
||||||
can :preview, Project
|
can :preview, Project
|
||||||
can(:refs_list, Project) {|project| can? :read, project}
|
|
||||||
|
|
||||||
can([:read, :create, :edit, :destroy, :update], Hook) {|hook| can?(:edit, hook.project)}
|
can([:read, :create, :edit, :destroy, :update], Hook) {|hook| can?(:edit, hook.project)}
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,10 @@ class PullRequest < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def cross_pull?
|
||||||
|
from_project_id != to_project_id
|
||||||
|
end
|
||||||
|
|
||||||
def check(do_transaction = true)
|
def check(do_transaction = true)
|
||||||
if do_transaction && !valid?
|
if do_transaction && !valid?
|
||||||
issue.set_close nil
|
issue.set_close nil
|
||||||
|
|
|
@ -109,7 +109,7 @@ class CommentPresenter < ApplicationPresenter
|
||||||
statuses = {'open' => 'success', 'closed' => 'important'}
|
statuses = {'open' => 'success', 'closed' => 'important'}
|
||||||
content_tag :span, t("layout.issues.status.#{@referenced_issue.status}"), :class => "state label-bootstrap label-#{statuses[@referenced_issue.status]}"
|
content_tag :span, t("layout.issues.status.#{@referenced_issue.status}"), :class => "state label-bootstrap label-#{statuses[@referenced_issue.status]}"
|
||||||
else
|
else
|
||||||
pull_status_label @referenced_issue
|
pull_status_label @referenced_issue.status
|
||||||
end.html_safe
|
end.html_safe
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
json.refs_list (@project.repo.branches + @project.repo.tags) do |grit|
|
json.refs_list @refs do |grit|
|
||||||
json.ref grit.name
|
json.ref grit.name
|
||||||
json.object do
|
json.object do
|
||||||
json.type (grit.class.name =~ /Tag/ ? 'tag' : 'commit')
|
json.type (grit.class.name =~ /Tag/ ? 'tag' : 'commit')
|
||||||
json.sha grit.commit.id
|
json.sha grit.commit.id
|
||||||
|
json.authored_date grit.commit.authored_date.to_i
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
json.url refs_list_api_v1_project_path(@project.id, :format => :json)
|
json.url refs_list_api_v1_project_path(@project.id, :format => :json)
|
|
@ -2,14 +2,14 @@ json.number pull.serial_id
|
||||||
json.(pull, :title, :status)
|
json.(pull, :title, :status)
|
||||||
json.to_ref do
|
json.to_ref do
|
||||||
json.ref pull.to_ref
|
json.ref pull.to_ref
|
||||||
json.sha pull.to_commit.id
|
json.sha pull.to_commit.try(:id)
|
||||||
json.project do
|
json.project do
|
||||||
json.partial! 'api/v1/projects/project', :project => pull.to_project
|
json.partial! 'api/v1/projects/project', :project => pull.to_project
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
json.from_ref do
|
json.from_ref do
|
||||||
json.ref pull.from_ref
|
json.ref pull.from_ref
|
||||||
json.sha pull.from_commit.id
|
json.sha pull.from_commit.try(:id)
|
||||||
json.project do
|
json.project do
|
||||||
json.partial! 'api/v1/projects/project', :project => pull.from_project
|
json.partial! 'api/v1/projects/project', :project => pull.from_project
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
json.issue do
|
json.pull_request do
|
||||||
json.partial! 'pull', :pull => @pull
|
json.partial! 'pull', :pull => @pull
|
||||||
json.body @pull.body
|
json.body @pull.body
|
||||||
json.closed_at pull.issue.closed_at.to_i if @pull.merged? || @pull.closed?
|
json.closed_at @pull.issue.closed_at.to_i if @pull.merged? || @pull.closed?
|
||||||
json.closed_by do
|
json.closed_by do
|
||||||
json.partial! 'api/v1/shared/member', :member => @pull.issue.closer
|
json.partial! 'api/v1/shared/member', :member => @pull.issue.closer
|
||||||
end if @pull.issue.closer
|
end if @pull.issue.closer
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
json.(member, :id, :name)
|
json.(member, :id, :name, :uname)
|
||||||
json.type member.class.name
|
json.type member.class.name
|
||||||
json.url member_path(member)
|
json.url member_path(member)
|
|
@ -12,7 +12,7 @@
|
||||||
- if user_signed_in?
|
- if user_signed_in?
|
||||||
= auto_discovery_link_tag :atom, atom_activity_feeds_path(:format => 'atom', :token => current_user.authentication_token), :title => t("layout.atom_link_tag_title", :nickname => current_user.uname, :app_name => APP_CONFIG['project_name'])
|
= auto_discovery_link_tag :atom, atom_activity_feeds_path(:format => 'atom', :token => current_user.authentication_token), :title => t("layout.atom_link_tag_title", :nickname => current_user.uname, :app_name => APP_CONFIG['project_name'])
|
||||||
|
|
||||||
%body
|
%body{'ng-app' => 'RosaABF', 'ng-controller' => 'RosaABFController', 'ng-init' => "init('#{I18n.locale}')"}
|
||||||
.wrap{:class => content_for?(:sidebar) ? 'columns' : ''}
|
.wrap{:class => content_for?(:sidebar) ? 'columns' : ''}
|
||||||
%header
|
%header
|
||||||
.left
|
.left
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
- act = action_name.to_sym; contr = controller_name.to_sym; treeish = project.default_head(params[:treeish]); branch = @branch.try(:name) || project.default_head
|
- act = action_name.to_sym; contr = controller_name.to_sym; treeish = project.default_head(params[:treeish]); branch = @branch.try(:name) || project.default_head
|
||||||
-http_url = git_repo_url(project.name_with_owner)
|
-http_url = git_repo_url(project.name_with_owner)
|
||||||
-ssh_url = git_ssh_repo_url(project.name_with_owner)
|
-ssh_url = git_ssh_repo_url(project.name_with_owner)
|
||||||
#description-top
|
#description-top{'ng-controller' => 'ProjectRepoBlockController', 'ng-init' => "init(#{project.repo.branches.count})"}
|
||||||
-if @commit
|
-if @commit
|
||||||
%ul.nav.zip
|
%ul.nav.zip
|
||||||
%li#menu-archive.dropdown
|
%li#menu-archive.dropdown
|
||||||
|
@ -42,7 +42,7 @@
|
||||||
%li{:class => ('selected' if act == :index && contr == :commits )}
|
%li{:class => ('selected' if act == :index && contr == :commits )}
|
||||||
= link_to t('project_menu.commits'), commits_path(project, treeish)
|
= link_to t('project_menu.commits'), commits_path(project, treeish)
|
||||||
%li{:class => ('selected' if act == :branches && contr == :trees )}
|
%li{:class => ('selected' if act == :branches && contr == :trees )}
|
||||||
= link_to t('project_menu.branches', :count => project.repo.branches.count), branches_path(project, branch)
|
= link_to t('project_menu.branches', :count => '{{singleton.project.branches_count}}'), branches_path(project, branch)
|
||||||
%li.tags{:class => ('selected' if act == :tags && contr == :trees )}
|
%li.tags{:class => ('selected' if act == :tags && contr == :trees )}
|
||||||
= link_to t('project_menu.tags', :count => project.repo.tags.count), tags_path(project)
|
= link_to t('project_menu.tags', :count => project.repo.tags.count), tags_path(project)
|
||||||
.both
|
.both
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
- base = branch.name == @branch.name
|
|
||||||
%tr{:class => (base ? 'base' : '')}
|
|
||||||
%td.name= link_to branch.name, tree_path(@project, branch.name)
|
|
||||||
%td.actions
|
|
||||||
%ul.actions
|
|
||||||
- if base
|
|
||||||
%li.text= t('layout.projects.base_branch')
|
|
||||||
- else
|
|
||||||
%li
|
|
||||||
= link_to t('layout.projects.compare'), diff_path(@project, "#{@branch.name}...#{branch.name}")
|
|
|
@ -1,10 +0,0 @@
|
||||||
- subjects_name = action_name.to_s
|
|
||||||
|
|
||||||
%h3= t("layout.projects.#{subjects_name}")
|
|
||||||
- if subject.blank?
|
|
||||||
%p= t("layout.projects.no_#{subjects_name}")
|
|
||||||
- elsif subject.count == 1
|
|
||||||
%p= t("layout.projects.showing_#{subjects_name.singularize}")
|
|
||||||
- else
|
|
||||||
%p= t("layout.projects.showing_#{subjects_name}", :count => subject.count)
|
|
||||||
.both
|
|
|
@ -1,8 +0,0 @@
|
||||||
%li
|
|
||||||
= link_to t('layout.projects.browse_code'), tree_path(@project, tag.name), :class => 'detail-link'
|
|
||||||
- file_name = "#{@project.name}-#{tag.name}"
|
|
||||||
- %w(zip tar.gz).each do |type|
|
|
||||||
= link_to t('layout.projects.source_code', :type => type), archive_path(@project, file_name, type), :class => 'detail-link'
|
|
||||||
%p.name
|
|
||||||
%b= tag.name
|
|
||||||
.date= tag.commit.authored_date.strftime('%d.%m.%Y')
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
-set_meta_tags :title => "#{title_object @project}"
|
||||||
|
|
||||||
|
= render 'submenu'
|
||||||
|
= render 'repo_block', :project => @project
|
||||||
|
|
||||||
|
%div{'ng-controller' => 'ProjectRefsController',
|
||||||
|
'ng-init' => "init('#{@project.id}','#{@branch.try(:name)}')"}
|
||||||
|
|
||||||
|
%h3= t('layout.projects.branches')
|
||||||
|
%p{'ng-show' => '!branches.length'}= t('layout.projects.no_branches')
|
||||||
|
%p{'ng-show' => 'branches.length > 0'} {{'project.total_branches' | i18n:'plural':branches.length}}
|
||||||
|
.both
|
||||||
|
%br
|
||||||
|
|
||||||
|
%input.mediumheight{'ng-model' => 'query.ref'}
|
||||||
|
.both
|
||||||
|
|
||||||
|
%table#project-branches
|
||||||
|
%tbody
|
||||||
|
%tr{'ng-repeat' => 'branch in branches | filter:query', 'ng-class' => '{base: branch.ref == current_ref}'}
|
||||||
|
%td.name
|
||||||
|
%a{'ng-href' => '{{branch.path(project)}}' } {{branch.ref}}
|
||||||
|
%td.actions
|
||||||
|
%ul.actions
|
||||||
|
%li.text{'ng-show' => 'branch.ref == current_ref'}
|
||||||
|
= t('layout.projects.base_branch')
|
||||||
|
- if can?(:write, @project)
|
||||||
|
%li{'ng-hide' => 'branch.ref == current_ref'}
|
||||||
|
%a{:href => '', 'ng-click' => 'destroy(branch)'}
|
||||||
|
= t('layout.projects.delete_branch')
|
||||||
|
%li{'ng-hide' => 'branch.ref == current_ref'}
|
||||||
|
%a{'ng-href' => '{{branch.diff_path(project, current_ref)}}' }
|
||||||
|
= t('layout.projects.compare')
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
-set_meta_tags :title => "#{title_object @project}"
|
|
||||||
|
|
||||||
= render 'submenu'
|
|
||||||
= render 'repo_block', :project => @project
|
|
||||||
= render 'header', :subject => (@branches || @tags)
|
|
||||||
|
|
||||||
- if @tags.present?
|
|
||||||
%div#project-tags
|
|
||||||
%ol.release-list
|
|
||||||
= render :partial => 'tag', :collection => @tags
|
|
||||||
- elsif @branches.present?
|
|
||||||
%table#project-branches
|
|
||||||
%tbody
|
|
||||||
= render :partial => 'branch', :collection => @branches
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
-set_meta_tags :title => "#{title_object @project}"
|
||||||
|
|
||||||
|
= render 'submenu'
|
||||||
|
= render 'repo_block', :project => @project
|
||||||
|
|
||||||
|
%div{'ng-controller' => 'ProjectRefsController', 'ng-init' => "init('#{@project.id}')"}
|
||||||
|
|
||||||
|
%h3= t('layout.projects.tags')
|
||||||
|
%p{'ng-show' => '!tags.length'}= t('layout.projects.no_tags')
|
||||||
|
%p{'ng-show' => 'tags.length > 0'} {{'project.total_tags' | i18n:'plural':tags.length}}
|
||||||
|
.both
|
||||||
|
%br
|
||||||
|
|
||||||
|
%input.mediumheight{'ng-model' => 'query.ref'}
|
||||||
|
.both
|
||||||
|
|
||||||
|
#project-tags
|
||||||
|
%ol.release-list
|
||||||
|
%li{'ng-repeat' => 'tag in tags | filter:query'}
|
||||||
|
%a.detail-link{'ng-href' => '{{tag.path(project)}}' }
|
||||||
|
= t('layout.projects.browse_code')
|
||||||
|
- %w(zip tar.gz).each do |type|
|
||||||
|
%a.detail-link{'ng-href' => "{{tag.archive_path(project, '#{type}')}}" }
|
||||||
|
= t('layout.projects.source_code', :type => type)
|
||||||
|
%p.name
|
||||||
|
%b {{tag.ref}}
|
||||||
|
.date {{tag.object.authored_date * 1000 | date:'yyyy.MM.dd'}}
|
|
@ -1,14 +1,36 @@
|
||||||
- if can?(:merge, @pull) && @pull.can_merging?
|
- if can?(:merge, @pull) && @pull.can_merging?
|
||||||
%br
|
%a.button{:href => '', 'ng-click' => 'merge()', 'ng-show' => "pull.status == 'ready'"}
|
||||||
=form_for PullRequest.new, :url => merge_project_pull_request_path(@project, @pull), :html => { :method => :put, :class => :form } do |f|
|
= t 'projects.pull_requests.ready'
|
||||||
=f.submit t 'projects.pull_requests.ready'
|
.both
|
||||||
-else
|
|
||||||
.flash
|
.flash{'ng-show' => '!pull.mergeable'}
|
||||||
%div{:class => @pull.ready? ? 'notice' : 'alert'}
|
.notice{'ng-show' => "pull.status == 'blocked'"}
|
||||||
=pull_status @pull
|
= t "projects.pull_requests.blocked"
|
||||||
|
.alert{'ng-show' => "pull.status == 'merged'"}
|
||||||
|
= t("projects.pull_requests.merged",
|
||||||
|
:user => '{{pull.merged_by.uname}}',
|
||||||
|
:to_ref => show_ref(@pull, 'to'),
|
||||||
|
:from_ref => show_ref(@pull, 'from'),
|
||||||
|
:time => '{{merged_at}}').html_safe
|
||||||
|
.alert{'ng-show' => "pull.status == 'closed'"}
|
||||||
|
= t("projects.pull_requests.closed",
|
||||||
|
:user => '{{pull.closed_by.uname}}',
|
||||||
|
:time => '{{closed_at}}')
|
||||||
|
.both
|
||||||
|
|
||||||
|
|
||||||
|
- if !@pull.cross_pull? && can?(:write, @project)
|
||||||
|
%div{'ng-init' => "getBranch('#{@pull.from_ref}')", 'ng-show' => "pull.status == 'closed' || pull.status == 'merged'"}
|
||||||
|
%a.button{:href => '', 'ng-click' => 'deleteBranch()', 'ng-show' => "branch && branch.object.sha == pull.from_ref.sha"}
|
||||||
|
= t('layout.projects.delete_branch')
|
||||||
|
%a.button{:href => '', 'ng-click' => 'restoreBranch()', 'ng-hide' => "branch"}
|
||||||
|
= t('layout.projects.restore_branch')
|
||||||
|
.both
|
||||||
|
|
||||||
|
|
||||||
-if can? :update, @pull
|
-if can? :update, @pull
|
||||||
-if action = @pull.can_close? ? 'close' : ('reopen' if @pull.can_reopen?)
|
%br
|
||||||
%br
|
%a.button{:href => '', 'ng-click' => 'reopen()', 'ng-show' => "pull.status == 'closed'"}
|
||||||
=form_for :pull, :url => [@project, @pull], :html => { :id => 'do_pull_action',:method => :put, :class => :form } do |f|
|
= t '.reopen'
|
||||||
=hidden_field_tag "pull_request_action", action
|
%a.button{:href => '', 'ng-click' => 'close()', 'ng-show' => "pull.status == 'ready' || pull.status == 'open' || pull.status == 'blocked'"}
|
||||||
=f.submit t ".#{action}"
|
= t '.close'
|
|
@ -1,19 +1,23 @@
|
||||||
-ar = 'activerecord.attributes.pull_requests'
|
-ar = 'activerecord.attributes.pull_requests'
|
||||||
-set_meta_tags :title => [title_object(@project), t('.title', :name => @pull.title.truncate(40), :user => @pull.user.try(:uname))]
|
-set_meta_tags :title => [title_object(@project), t('.title', :name => @pull.title.truncate(40), :user => @pull.user.try(:uname))]
|
||||||
= render :partial => 'submenu'
|
= render :partial => 'submenu'
|
||||||
%h3.bpadding10
|
|
||||||
=pull_status_label @pull
|
%div{'ng-controller' => 'PullRequestController', 'ng-init' => "init('#{@project.id}', '#{@pull.serial_id}')"}
|
||||||
=pull_header @pull
|
|
||||||
#repo-wrapper
|
%h3.bpadding10
|
||||||
=render 'nav_tabs'
|
- PullRequest::STATUSES.each do |status|
|
||||||
.tab-content.pull_diff_fix
|
= pull_status_label status, {'ng-show' => "pull.status == '#{status}'"}
|
||||||
#discussion.tab-pane.active
|
= pull_header @pull
|
||||||
=render 'projects/issues/header'
|
#repo-wrapper
|
||||||
=render 'activity'
|
=render 'nav_tabs'
|
||||||
%br
|
.tab-content.pull_diff_fix
|
||||||
=render "projects/comments/add", :project => @project, :commentable => @issue if current_user
|
#discussion.tab-pane.active
|
||||||
.pull_status
|
=render 'projects/issues/header'
|
||||||
=render 'status'
|
=render 'activity'
|
||||||
=render 'diff_commits_tabs' unless @pull.already?
|
%br
|
||||||
=hidden_field_tag :preview_url, project_md_preview_path(@project)
|
=render "projects/comments/add", :project => @project, :commentable => @issue if current_user
|
||||||
= render "projects/comments/markdown_help"
|
.pull_status
|
||||||
|
=render 'status'
|
||||||
|
=render 'diff_commits_tabs' unless @pull.already?
|
||||||
|
=hidden_field_tag :preview_url, project_md_preview_path(@project)
|
||||||
|
= render "projects/comments/markdown_help"
|
||||||
|
|
|
@ -2,16 +2,14 @@ en:
|
||||||
layout:
|
layout:
|
||||||
projects:
|
projects:
|
||||||
branches: Branches
|
branches: Branches
|
||||||
showing_branches: Showing %{count} branches
|
delete_branch: Delete branch
|
||||||
showing_branch: Showing 1 branch
|
restore_branch: Restore branch
|
||||||
no_branches: No branches
|
no_branches: No branches
|
||||||
base_branch: Base branch
|
base_branch: Base branch
|
||||||
compare: Compare
|
compare: Compare
|
||||||
browse_code: Browse code
|
browse_code: Browse code
|
||||||
source_code: Source code (%{type})
|
source_code: Source code (%{type})
|
||||||
tags: Tags
|
tags: Tags
|
||||||
showing_tags: Showing %{count} tags
|
|
||||||
showing_tag: Showing 1 tag
|
|
||||||
no_tags: No tags
|
no_tags: No tags
|
||||||
add: Add
|
add: Add
|
||||||
public_projects_list: Public projects list
|
public_projects_list: Public projects list
|
||||||
|
|
|
@ -2,16 +2,14 @@ ru:
|
||||||
layout:
|
layout:
|
||||||
projects:
|
projects:
|
||||||
branches: Ветки
|
branches: Ветки
|
||||||
showing_branches: Показано %{count} веток
|
delete_branch: Удалить ветку
|
||||||
showing_branch: Показана 1 ветка
|
restore_branch: Востановить ветку
|
||||||
no_branch: Нет веток
|
no_branches: Нет веток
|
||||||
base_branch: Текущая ветка
|
base_branch: Текущая ветка
|
||||||
compare: Сравнить
|
compare: Сравнить
|
||||||
browse_code: Просмотреть код
|
browse_code: Просмотреть код
|
||||||
source_code: Исходный код (%{type})
|
source_code: Исходный код (%{type})
|
||||||
tags: Теги
|
tags: Теги
|
||||||
showing_tags: Показано %{count} тегов
|
|
||||||
showing_tag: Показан 1 тег
|
|
||||||
no_tags: Нет тегов
|
no_tags: Нет тегов
|
||||||
add: Добавить
|
add: Добавить
|
||||||
public_projects_list: Список публичных проектов
|
public_projects_list: Список публичных проектов
|
||||||
|
|
|
@ -21,7 +21,7 @@ ru:
|
||||||
ready: Данный пул реквест можно смержить автоматически.
|
ready: Данный пул реквест можно смержить автоматически.
|
||||||
merged: |
|
merged: |
|
||||||
%{user} смержил <span class="label-bootstrap label-info font14">%{to_ref}</span>
|
%{user} смержил <span class="label-bootstrap label-info font14">%{to_ref}</span>
|
||||||
с <span class="label-bootstrap label-info font14">%{from_ref}</span> в %{time}'
|
с <span class="label-bootstrap label-info font14">%{from_ref}</span> в %{time}
|
||||||
closed: '%{user} закрыл пул реквест в %{time}'
|
closed: '%{user} закрыл пул реквест в %{time}'
|
||||||
is_big: Этот пул реквест слишком большой! Мы показываем только последние %{count} коммитов.
|
is_big: Этот пул реквест слишком большой! Мы показываем только последние %{count} коммитов.
|
||||||
open: ''
|
open: ''
|
||||||
|
|
|
@ -310,7 +310,6 @@ Rosa::Application.routes.draw do
|
||||||
resources :hooks, :except => :show
|
resources :hooks, :except => :show
|
||||||
resources :pull_requests, :except => :destroy do
|
resources :pull_requests, :except => :destroy do
|
||||||
get :autocomplete_to_project, :on => :collection
|
get :autocomplete_to_project, :on => :collection
|
||||||
put :merge, :on => :member
|
|
||||||
end
|
end
|
||||||
post '/preview' => 'projects#preview', :as => 'md_preview'
|
post '/preview' => 'projects#preview', :as => 'md_preview'
|
||||||
post 'refs_list' => 'projects#refs_list', :as => 'refs_list'
|
post 'refs_list' => 'projects#refs_list', :as => 'refs_list'
|
||||||
|
@ -336,6 +335,8 @@ Rosa::Application.routes.draw do
|
||||||
get '/tags' => "git/trees#tags", :as => :tags
|
get '/tags' => "git/trees#tags", :as => :tags
|
||||||
# Branches
|
# Branches
|
||||||
get '/branches/:treeish' => "git/trees#branches", :as => :branches
|
get '/branches/:treeish' => "git/trees#branches", :as => :branches
|
||||||
|
delete '/branches/:treeish' => "git/trees#destroy", :as => :branches
|
||||||
|
put '/branches/:treeish' => "git/trees#restore_branch", :as => :branches
|
||||||
# Commits
|
# Commits
|
||||||
get '/commits/:treeish(/*path)' => "git/commits#index", :as => :commits, :format => false
|
get '/commits/:treeish(/*path)' => "git/commits#index", :as => :commits, :format => false
|
||||||
get '/commit/:id(.:format)' => "git/commits#show", :as => :commit
|
get '/commit/:id(.:format)' => "git/commits#show", :as => :commit
|
||||||
|
|
|
@ -33,6 +33,20 @@ module Modules
|
||||||
repo.tags.map(&:name) + repo.branches.map(&:name)
|
repo.tags.map(&:name) + repo.branches.map(&:name)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# TODO: return something else instead of empty string on success and error
|
||||||
|
def restore_branch(branch, sha)
|
||||||
|
repo.git.native(:branch, {}, branch, sha)
|
||||||
|
end
|
||||||
|
|
||||||
|
def delete_branch(branch, user)
|
||||||
|
return false if default_branch == branch.name
|
||||||
|
message = repo.git.native(:branch, {}, '-D', branch.name)
|
||||||
|
if message.present?
|
||||||
|
Resque.enqueue(GitHook,owner.uname, name, GitHook::ZERO, branch.commit.id, "refs/heads/#{branch.name}", 'commit', "user-#{user.id}", message)
|
||||||
|
end
|
||||||
|
return message.present?
|
||||||
|
end
|
||||||
|
|
||||||
def update_file(path, data, options = {})
|
def update_file(path, data, options = {})
|
||||||
head = options[:head].to_s || default_branch
|
head = options[:head].to_s || default_branch
|
||||||
actor = get_actor(options[:actor])
|
actor = get_actor(options[:actor])
|
||||||
|
|
|
@ -7,7 +7,6 @@ describe Projects::Git::TreesController do
|
||||||
stub_symlink_methods
|
stub_symlink_methods
|
||||||
|
|
||||||
@project = FactoryGirl.create(:project)
|
@project = FactoryGirl.create(:project)
|
||||||
@another_user = FactoryGirl.create(:user)
|
|
||||||
@params = { :owner_name => @project.owner.uname,
|
@params = { :owner_name => @project.owner.uname,
|
||||||
:project_name => @project.name,
|
:project_name => @project.name,
|
||||||
:treeish => "#{@project.name}-master"}
|
:treeish => "#{@project.name}-master"}
|
||||||
|
@ -37,6 +36,17 @@ describe Projects::Git::TreesController do
|
||||||
get :archive, @params.merge(:format => 'tar.gz')
|
get :archive, @params.merge(:format => 'tar.gz')
|
||||||
response.code.should == '401'
|
response.code.should == '401'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'should not be able to perform destroy action' do
|
||||||
|
delete :destroy, @params.merge(:treeish => 'master')
|
||||||
|
response.should_not be_success
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should not be able to perform restore_branch action' do
|
||||||
|
put :restore_branch, @params.merge(:treeish => 'master')
|
||||||
|
response.should_not be_success
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'for other user' do
|
context 'for other user' do
|
||||||
|
@ -60,6 +70,16 @@ describe Projects::Git::TreesController do
|
||||||
response.should be_success
|
response.should be_success
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'should not be able to perform destroy action' do
|
||||||
|
delete :destroy, @params.merge(:treeish => 'master')
|
||||||
|
response.should_not be_success
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should not be able to perform restore_branch action' do
|
||||||
|
put :restore_branch, @params.merge(:treeish => 'master')
|
||||||
|
response.should_not be_success
|
||||||
|
end
|
||||||
|
|
||||||
[:tags, :branches].each do |action|
|
[:tags, :branches].each do |action|
|
||||||
it "should be able to perform #{action} action" do
|
it "should be able to perform #{action} action" do
|
||||||
get action, @params.merge(:treeish => 'master')
|
get action, @params.merge(:treeish => 'master')
|
||||||
|
@ -68,5 +88,28 @@ describe Projects::Git::TreesController do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'for writer user' do
|
||||||
|
before(:each) do
|
||||||
|
user = FactoryGirl.create(:user)
|
||||||
|
@project.relations.create!(:actor_type => 'User', :actor_id => user.id, :role => 'writer')
|
||||||
|
set_session_for user
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should be able to perform destroy action' do
|
||||||
|
delete :destroy, @params.merge(:treeish => 'conflicts')
|
||||||
|
response.should be_success
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should not be able to perform destroy action for master branch' do
|
||||||
|
delete :destroy, @params.merge(:treeish => 'master')
|
||||||
|
response.should_not be_success
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should be able to perform restore_branch action' do
|
||||||
|
put :restore_branch, @params.merge(:treeish => 'conflicts')
|
||||||
|
response.should be_success
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
after(:all) {clean_projects_dir}
|
after(:all) {clean_projects_dir}
|
||||||
end
|
end
|
||||||
|
|
|
@ -97,11 +97,6 @@ shared_examples_for 'user with pull request update rights' do
|
||||||
response.should redirect_to(project_pull_request_path(@pull.to_project, @pull))
|
response.should redirect_to(project_pull_request_path(@pull.to_project, @pull))
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should be able to perform merge action' do
|
|
||||||
put :merge, @update_params
|
|
||||||
response.should redirect_to(project_pull_request_path(@pull.to_project, @pull))
|
|
||||||
end
|
|
||||||
|
|
||||||
let(:pull) { @project.pull_requests.find(@pull) }
|
let(:pull) { @project.pull_requests.find(@pull) }
|
||||||
it 'should update pull request status' do
|
it 'should update pull request status' do
|
||||||
put :update, @update_params
|
put :update, @update_params
|
||||||
|
@ -135,11 +130,6 @@ shared_examples_for 'user without pull request update rights' do
|
||||||
response.should redirect_to(controller.current_user ? forbidden_path : new_user_session_path)
|
response.should redirect_to(controller.current_user ? forbidden_path : new_user_session_path)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should not be able to perform merge action' do
|
|
||||||
put :merge, @update_params
|
|
||||||
response.should redirect_to(controller.current_user ? forbidden_path : new_user_session_path)
|
|
||||||
end
|
|
||||||
|
|
||||||
let(:pull) { @project.pull_requests.find(@pull) }
|
let(:pull) { @project.pull_requests.find(@pull) }
|
||||||
it 'should not update pull request status' do
|
it 'should not update pull request status' do
|
||||||
put :update, @update_params
|
put :update, @update_params
|
||||||
|
|
|
@ -86,4 +86,55 @@ describe Project do
|
||||||
lambda {FactoryGirl.create(:project, :name => "...\nbeatiful_name\n for project")}.should raise_error(ActiveRecord::RecordInvalid)
|
lambda {FactoryGirl.create(:project, :name => "...\nbeatiful_name\n for project")}.should raise_error(ActiveRecord::RecordInvalid)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'manage branches' do
|
||||||
|
let!(:project) { FactoryGirl.create(:project_with_commit) }
|
||||||
|
let(:branch) { project.repo.branches.detect{|b| b.name == 'conflicts'} }
|
||||||
|
let(:master) { project.repo.branches.detect{|b| b.name == 'master'} }
|
||||||
|
let(:user) { FactoryGirl.create(:user) }
|
||||||
|
before { stub_redis }
|
||||||
|
|
||||||
|
context '#delete_branch' do
|
||||||
|
it 'ensures that returns true on success' do
|
||||||
|
project.delete_branch(branch, user).should be_true
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'ensures that branch has been deleted' do
|
||||||
|
lambda { project.delete_branch(branch, user) }.should change{ project.repo.branches.count }.by(-1)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'ensures that returns false on delete master' do
|
||||||
|
project.delete_branch(master, user).should be_false
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'ensures that master has not been deleted' do
|
||||||
|
lambda { project.delete_branch(master, user) }.should change{ project.repo.branches.count }.by(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'ensures that returns false on delete wrong branch' do
|
||||||
|
project.delete_branch(branch, user)
|
||||||
|
project.delete_branch(branch, user).should be_false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context '#restore_branch' do
|
||||||
|
before do
|
||||||
|
project.delete_branch(branch, user)
|
||||||
|
end
|
||||||
|
|
||||||
|
xit 'ensures that returns true on success' do
|
||||||
|
project.restore_branch(branch.name, branch.commit.id).should be_true
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'ensures that branch has been restored' do
|
||||||
|
lambda { project.restore_branch(branch.name, branch.commit.id) }.should change{ project.repo.branches.count }.by(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
xit 'ensures that returns false on restore wrong branch' do
|
||||||
|
project.restore_branch(branch.name, GitHook::ZERO).should be_false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue