Merge branch 'master' into 90-pull
Conflicts: app/assets/stylesheets/design/custom.scss config/locales/title.en.yml config/locales/title.ru.yml config/routes.rb db/schema.rb
1
Gemfile
|
@ -71,6 +71,7 @@ group :development do
|
||||||
gem 'shotgun'
|
gem 'shotgun'
|
||||||
# deploy
|
# deploy
|
||||||
gem 'capistrano', :require => false
|
gem 'capistrano', :require => false
|
||||||
|
gem 'rvm-capistrano', :require => false
|
||||||
gem 'cape', :require => false
|
gem 'cape', :require => false
|
||||||
gem 'capistrano_colors', :require => false
|
gem 'capistrano_colors', :require => false
|
||||||
end
|
end
|
||||||
|
|
|
@ -255,6 +255,8 @@ GEM
|
||||||
ruby-openid (2.1.8)
|
ruby-openid (2.1.8)
|
||||||
russian (0.6.0)
|
russian (0.6.0)
|
||||||
i18n (>= 0.5.0)
|
i18n (>= 0.5.0)
|
||||||
|
rvm-capistrano (1.1.0)
|
||||||
|
capistrano (>= 2.0.0)
|
||||||
sanitize (2.0.3)
|
sanitize (2.0.3)
|
||||||
nokogiri (>= 1.4.4, < 1.6)
|
nokogiri (>= 1.4.4, < 1.6)
|
||||||
sass (3.1.16)
|
sass (3.1.16)
|
||||||
|
@ -358,6 +360,7 @@ DEPENDENCIES
|
||||||
rspec-rails (~> 2.9.0)
|
rspec-rails (~> 2.9.0)
|
||||||
ruby-haml-js (~> 0.0.3)
|
ruby-haml-js (~> 0.0.3)
|
||||||
russian (~> 0.6.0)
|
russian (~> 0.6.0)
|
||||||
|
rvm-capistrano
|
||||||
sass-rails (~> 3.2.5)
|
sass-rails (~> 3.2.5)
|
||||||
shotgun
|
shotgun
|
||||||
shoulda
|
shoulda
|
||||||
|
|
After Width: | Height: | Size: 97 KiB |
After Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 40 KiB |
After Width: | Height: | Size: 40 KiB |
After Width: | Height: | Size: 59 KiB |
After Width: | Height: | Size: 205 KiB |
After Width: | Height: | Size: 130 KiB |
After Width: | Height: | Size: 103 KiB |
After Width: | Height: | Size: 211 KiB |
After Width: | Height: | Size: 226 KiB |
After Width: | Height: | Size: 181 KiB |
After Width: | Height: | Size: 319 KiB |
After Width: | Height: | Size: 115 KiB |
After Width: | Height: | Size: 160 KiB |
After Width: | Height: | Size: 132 KiB |
After Width: | Height: | Size: 34 KiB |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 60 KiB |
After Width: | Height: | Size: 60 KiB |
After Width: | Height: | Size: 48 KiB |
After Width: | Height: | Size: 81 KiB |
After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 48 KiB |
After Width: | Height: | Size: 36 KiB |
|
@ -1,5 +1,5 @@
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
$('#build_list_pl_id').change(function() {
|
$('#build_list_save_to_platform_id').change(function() {
|
||||||
var platform_id = $(this).val();
|
var platform_id = $(this).val();
|
||||||
var base_platforms = $('.all_platforms input[type=checkbox].build_bpl_ids');
|
var base_platforms = $('.all_platforms input[type=checkbox].build_bpl_ids');
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ $(document).ready(function() {
|
||||||
$(this).attr('checked', 'checked').removeAttr('disabled').trigger('change');
|
$(this).attr('checked', 'checked').removeAttr('disabled').trigger('change');
|
||||||
$(this).parent().find('.offset25 input[type="checkbox"]').removeAttr('disabled');
|
$(this).parent().find('.offset25 input[type="checkbox"]').removeAttr('disabled');
|
||||||
|
|
||||||
var rep_name = $('#build_list_pl_id option[value="' + $(this).val() + '"]').text().match(/[\w-]+\/([\w-]+)/)[1];
|
var rep_name = $('#build_list_save_to_platform_id option[value="' + $(this).val() + '"]').text().match(/[\w-]+\/([\w-]+)/)[1];
|
||||||
if (rep_name != 'main') {
|
if (rep_name != 'main') {
|
||||||
$(this).parent().find('.offset25 input[type="checkbox"][rep_name="' + rep_name + '"]').attr('checked', 'checked');
|
$(this).parent().find('.offset25 input[type="checkbox"][rep_name="' + rep_name + '"]').attr('checked', 'checked');
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ $(document).ready(function() {
|
||||||
|
|
||||||
setBranchSelected();
|
setBranchSelected();
|
||||||
});
|
});
|
||||||
$('#build_list_pl_id').trigger('change');
|
$('#build_list_save_to_platform_id').trigger('change');
|
||||||
|
|
||||||
$('.offset25 label').click(function() {
|
$('.offset25 label').click(function() {
|
||||||
setPlChecked($(this).prev()[0], !$(this).prev().attr('checked'));
|
setPlChecked($(this).prev()[0], !$(this).prev().attr('checked'));
|
||||||
|
@ -58,10 +58,10 @@ function setPlChecked(pointer, checked) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function setBranchSelected() {
|
function setBranchSelected() {
|
||||||
var pl_id = $('#build_list_pl_id').val();
|
var pl_id = $('#build_list_save_to_platform_id').val();
|
||||||
// Checks if selected platform is main or not:
|
// Checks if selected platform is main or not:
|
||||||
if ( $('.all_platforms').find('input[type="checkbox"][value=' + pl_id + '].build_bpl_ids').size() > 0 ) {
|
if ( $('.all_platforms').find('input[type="checkbox"][value=' + pl_id + '].build_bpl_ids').size() > 0 ) {
|
||||||
var pl_name = $('#build_list_pl_id option[value="' + pl_id + '"]').text().match(/([\w-]+)\/[\w-]+/)[1];
|
var pl_name = $('#build_list_save_to_platform_id option[value="' + pl_id + '"]').text().match(/([\w-]+)\/[\w-]+/)[1];
|
||||||
var branch_pl_opt = $('#build_list_project_version option[value="latest_' + pl_name + '"]');
|
var branch_pl_opt = $('#build_list_project_version option[value="latest_' + pl_name + '"]');
|
||||||
// If there is branch we need - set it selected:
|
// If there is branch we need - set it selected:
|
||||||
if ( branch_pl_opt.size() > 0 ) {
|
if ( branch_pl_opt.size() > 0 ) {
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
//= require jquery
|
||||||
|
//= require jquery-ui
|
||||||
|
//= require pirobox_extended_min
|
|
@ -456,6 +456,18 @@ table.tablesorter.platforms .th2 {
|
||||||
width: 280px;
|
width: 280px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
table.tablesorter.advisories .th1 {
|
||||||
|
width: 120px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.tablesorter.advisories .th2 {
|
||||||
|
width: 250px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.tablesorter.advisories .th3 {
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
table.tablesorter tr td.buttons {
|
table.tablesorter tr td.buttons {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
@ -922,6 +934,16 @@ div#git_help_data p {
|
||||||
background: none repeat scroll 0 0;
|
background: none repeat scroll 0 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.font14 {
|
.rightlist p {
|
||||||
font-size: 14px;
|
padding-bottom: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.leftlist span.hint {
|
||||||
|
padding-top: 1em;
|
||||||
|
display: block;
|
||||||
|
font-size: 0.9em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.atom_icon {
|
||||||
|
vertical-align: top;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,455 @@
|
||||||
|
html, body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
font-family: Tahoma, Geneva, Helvetica, sans-serif;
|
||||||
|
color: #292929;
|
||||||
|
background: #1f60a1 image-url("bg.png") repeat-x;
|
||||||
|
min-width: 940px;
|
||||||
|
min-height: 600px;
|
||||||
|
text-align: center;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
header, section, footer, aside, nav, article, menu {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="text"]:focus { outline: none; }
|
||||||
|
|
||||||
|
input[type="password"]:focus { outline: none; }
|
||||||
|
|
||||||
|
input:focus { outline: none; }
|
||||||
|
|
||||||
|
select:focus { outline: none; }
|
||||||
|
|
||||||
|
a img { border: none; }
|
||||||
|
|
||||||
|
.wrap {
|
||||||
|
width: 940px;
|
||||||
|
margin: 0 auto;
|
||||||
|
text-align: center;
|
||||||
|
border: 1px solid #3f668c;
|
||||||
|
-webkit-box-shadow: 0px 0px 7px 0px rgba(0, 0, 0, 0.5);
|
||||||
|
-moz-box-shadow: 0px 0px 7px 0px rgba(0, 0, 0, 0.5);
|
||||||
|
box-shadow: 0px 0px 7px 0px rgba(0, 0, 0, 0.5);
|
||||||
|
background: #FFF;
|
||||||
|
min-height: 92%;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.both {
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Top menu */
|
||||||
|
|
||||||
|
header {
|
||||||
|
-webkit-box-shadow: 0px 5px 5px -3px rgba(0, 0, 0, 0.4);
|
||||||
|
-moz-box-shadow: 0px 5px 5px -3px rgba(0, 0, 0, 0.4);
|
||||||
|
box-shadow: 0px 5px 5px -3px rgba(0, 0, 0, 0.4);
|
||||||
|
position: relative;
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
header div.left {
|
||||||
|
background: image-url("top-left-tour.png");
|
||||||
|
height: 46px;
|
||||||
|
width: 14px;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
header div.middle {
|
||||||
|
background: image-url("top-middle.png");
|
||||||
|
float: left;
|
||||||
|
height: 46px;
|
||||||
|
width: 912px;
|
||||||
|
}
|
||||||
|
|
||||||
|
header div.right {
|
||||||
|
background: image-url("top-right-tour.png");
|
||||||
|
height: 46px;
|
||||||
|
width: 14px;
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Left part of top menu*/
|
||||||
|
|
||||||
|
header menu {
|
||||||
|
float: left;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
header menu ul {
|
||||||
|
list-style: none;
|
||||||
|
margin: 0;
|
||||||
|
padding-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
header menu ul li {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
header menu ul li a {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #FFF;
|
||||||
|
text-decoration: none;
|
||||||
|
height: 43px;
|
||||||
|
padding: 15px 10px 15px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
header menu ul li a:hover {
|
||||||
|
color: #cee7ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
header menu ul li a.first {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
header menu ul li a.active {
|
||||||
|
background: image-url("menu-hover.png") repeat-x;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
header div.logo {
|
||||||
|
float: left;
|
||||||
|
margin-top: 5px;
|
||||||
|
padding-left: 0px;
|
||||||
|
padding-right: 0px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Right part of top menu */
|
||||||
|
|
||||||
|
header div.information {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
header div.search {
|
||||||
|
float: left;
|
||||||
|
margin: 10px 0px 0px 0px;
|
||||||
|
-moz-border-radius-topleft: 3px;
|
||||||
|
-moz-border-radius-topright: 3px;
|
||||||
|
-moz-border-radius-bottomright: 3px;
|
||||||
|
-moz-border-radius-bottomleft: 3px;
|
||||||
|
-webkit-border-radius: 3px 3px 3px 3px;
|
||||||
|
border-radius: 3px 3px 3px 3px;
|
||||||
|
background: #FFF;
|
||||||
|
border: 1px solid #7691aa;
|
||||||
|
}
|
||||||
|
|
||||||
|
header div.search div.pic {
|
||||||
|
background: image-url("search-button.png");
|
||||||
|
height: 22px;
|
||||||
|
width: 24px;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
header div.search div.field {
|
||||||
|
float: left;
|
||||||
|
margin: -1px 0px 0px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
header div.search div.field input {
|
||||||
|
border: none;
|
||||||
|
height: 18px;
|
||||||
|
background: none;
|
||||||
|
width: 132px;
|
||||||
|
font-size: 12px;
|
||||||
|
font-family: Arial;
|
||||||
|
padding: 2px 0px 0px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
header div.search div.field input.gray {
|
||||||
|
color: #cfcfcf;
|
||||||
|
}
|
||||||
|
|
||||||
|
header div.search div.field input.black {
|
||||||
|
color: #333333;
|
||||||
|
}
|
||||||
|
|
||||||
|
header div.avatar {
|
||||||
|
float:left;
|
||||||
|
padding: 6px 10px 10px 10px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
header div.information div.active {
|
||||||
|
background: image-url("menu-hover.png") repeat-x;
|
||||||
|
}
|
||||||
|
|
||||||
|
header div.information div.user {
|
||||||
|
float: left;
|
||||||
|
margin-left: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
header div.profile {
|
||||||
|
float: left;
|
||||||
|
text-align: right;
|
||||||
|
color: #FFF;
|
||||||
|
font-size: 12px;
|
||||||
|
padding-top: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
header div.profile a {
|
||||||
|
color: #FFF;
|
||||||
|
text-decoration: none;
|
||||||
|
padding-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
header div.profile a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
header div.droplist-wrap {
|
||||||
|
margin: -4px 0px 0px 0px;
|
||||||
|
width: 151px;
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
header div.droplist {
|
||||||
|
background: image-url("bg-droplist.png") repeat-x;
|
||||||
|
height: 91px;
|
||||||
|
width: 151px;
|
||||||
|
-webkit-box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.5);
|
||||||
|
-moz-box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.5);
|
||||||
|
box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.5);
|
||||||
|
position: absolute;
|
||||||
|
margin-top: 0px;
|
||||||
|
border-radius: 0px 0px 4px 4px;
|
||||||
|
display: none;
|
||||||
|
text-align: right;
|
||||||
|
z-index: 9999;
|
||||||
|
}
|
||||||
|
|
||||||
|
header div.droplist-wrap div.a {
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
header div.droplist a{
|
||||||
|
position: relative;
|
||||||
|
padding-left: 15px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #447cae;
|
||||||
|
text-decoration: none;
|
||||||
|
padding-right: 15px;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
header div.droplist a:hover{
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Submenu */
|
||||||
|
|
||||||
|
.sub-menu {
|
||||||
|
height: 38px;
|
||||||
|
margin: -7px 0px 0px 0px;
|
||||||
|
padding: 0px 0px 0px 15px;
|
||||||
|
background: #ededed;
|
||||||
|
position: relative;
|
||||||
|
z-index: 100;
|
||||||
|
border-bottom: 1px solid #FFF;
|
||||||
|
-webkit-box-shadow: 0px 5px 3px -3px rgba(18, 86, 135, 0.2);
|
||||||
|
-moz-box-shadow: 0px 5px 3px -3px rgba(18, 86, 135, 0.2);
|
||||||
|
box-shadow: 0px 5px 3px -3px rgba(18, 86, 135, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sub-menu div.left {
|
||||||
|
float: left;
|
||||||
|
width: 200px;
|
||||||
|
border-right: 1px solid #dcdcdc;
|
||||||
|
font-size: 12px;
|
||||||
|
text-align: left;
|
||||||
|
font-weight: 700;
|
||||||
|
padding: 10px 0px 0px 0px;
|
||||||
|
height: 21px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sub-menu div.right {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.sub-menu nav {
|
||||||
|
float: left;
|
||||||
|
margin: 0px 0px 0px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sub-menu nav ul {
|
||||||
|
list-style: none;
|
||||||
|
text-align: left;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
padding-top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sub-menu nav ul li {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sub-menu nav ul li a {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #292929;
|
||||||
|
text-decoration: none;
|
||||||
|
height: 34px;
|
||||||
|
padding: 0px 20px 9px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sub-menu nav ul li a.active {
|
||||||
|
background: image-url("submenu-hover.png") repeat-x scroll 0 100% transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sub-menu nav ul li a:hover {
|
||||||
|
color: #2b6daf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Page markup */
|
||||||
|
|
||||||
|
article {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
article a{
|
||||||
|
color: #447cae;
|
||||||
|
font-size: 12px;
|
||||||
|
text-decoration: none;
|
||||||
|
padding: 0px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
article a:hover{
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Footer */
|
||||||
|
|
||||||
|
footer {
|
||||||
|
height: 32px;
|
||||||
|
padding-left: 15px;
|
||||||
|
width: 900px;
|
||||||
|
margin: 0 auto;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer ul {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
list-style: none;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #FFF;
|
||||||
|
padding-top: 10px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer ul li {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer ul li a {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #FFF;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer ul li a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*TOUR*/
|
||||||
|
|
||||||
|
header.top {
|
||||||
|
position: relative;
|
||||||
|
z-index: 3;
|
||||||
|
background: none;
|
||||||
|
background: image-url("tour-top.png") no-repeat 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
header.tour {
|
||||||
|
height: 194px;
|
||||||
|
position: relative;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.sub-menu.tour {
|
||||||
|
padding: 10px 0 0 0;
|
||||||
|
height: 35px;
|
||||||
|
text-align: center;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.sub-menu.tour nav {
|
||||||
|
float: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.sub-menu.tour nav ul {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.sub-menu.tour nav li a {
|
||||||
|
font-size: 18px;
|
||||||
|
color: #575756;
|
||||||
|
}
|
||||||
|
|
||||||
|
article div.feature-wrap {
|
||||||
|
background: image-url("tour-bg.png") repeat-x 0 100%;
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
article div.feature {
|
||||||
|
width: 744px;
|
||||||
|
text-align: center;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
article div.feature div {
|
||||||
|
width: 362px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
article div.feature div img{
|
||||||
|
padding-bottom: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
article div.feature div h1 {
|
||||||
|
font-size: 24px;
|
||||||
|
color: #7eb7ed;
|
||||||
|
margin: -4px 0 10px 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
article div.feature div p {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #58595b;
|
||||||
|
padding-bottom: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
article div.feature div.left {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
article div.feature div.right {
|
||||||
|
float: right;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
article div.tour-gap {
|
||||||
|
height: 330px;
|
||||||
|
width: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@import "pirobox";
|
||||||
|
|
||||||
|
/* Custom */
|
||||||
|
header menu ul li a {
|
||||||
|
padding: 15px 8px 15px 8px;
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
# -*- encoding : utf-8 -*-
|
||||||
|
class AdvisoriesController < ApplicationController
|
||||||
|
before_filter :authenticate_user!
|
||||||
|
before_filter :find_advisory, :only => [:show]
|
||||||
|
load_and_authorize_resource
|
||||||
|
|
||||||
|
def index
|
||||||
|
@advisories = @advisories.paginate(:page => params[:page])
|
||||||
|
end
|
||||||
|
|
||||||
|
def show
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
def find_advisory
|
||||||
|
@advisory = Advisory.where(:advisory_id => params[:id]).limit(1).first if params[:id].present?
|
||||||
|
end
|
||||||
|
end
|
|
@ -21,7 +21,8 @@ class ApplicationController < ActionController::Base
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def set_locale
|
def set_locale
|
||||||
I18n.locale = check_locale( get_user_locale || request.env['HTTP_ACCEPT_LANGUAGE'] )
|
I18n.locale = check_locale( get_user_locale ||
|
||||||
|
(request.env['HTTP_ACCEPT_LANGUAGE'] ? request.env['HTTP_ACCEPT_LANGUAGE'][0,2].downcase : nil ))
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_user_locale
|
def get_user_locale
|
||||||
|
|
|
@ -6,7 +6,7 @@ class Groups::BaseController < ApplicationController
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def find_group
|
def find_group
|
||||||
if group_id = params[:owner_name] || params[:group_id] || params[:id]
|
if group_id = params[:uname] || params[:group_id] || params[:id]
|
||||||
@group = Group.find_by_insensitive_uname! group_id
|
@group = Group.find_by_insensitive_uname! group_id
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,6 +4,19 @@ class PagesController < ApplicationController
|
||||||
# load_and_authorize_resource
|
# load_and_authorize_resource
|
||||||
|
|
||||||
def root
|
def root
|
||||||
|
render 'pages/tour/abf-tour-project-description-1', :layout => 'tour'
|
||||||
|
end
|
||||||
|
|
||||||
|
def tour_inside
|
||||||
|
@entries = case params[:id]
|
||||||
|
when 'projects'
|
||||||
|
%w(repo builds monitoring)
|
||||||
|
when 'sources'
|
||||||
|
%w(source history annotation edit)
|
||||||
|
when 'builds'
|
||||||
|
%w(control git tracker)
|
||||||
|
end
|
||||||
|
render "pages/tour/tour-inside", :layout => 'tour'
|
||||||
end
|
end
|
||||||
|
|
||||||
def forbidden
|
def forbidden
|
||||||
|
|
|
@ -7,7 +7,7 @@ class Projects::BuildListsController < Projects::BaseController
|
||||||
before_filter :authenticate_build_service!, :only => CALLBACK_ACTIONS
|
before_filter :authenticate_build_service!, :only => CALLBACK_ACTIONS
|
||||||
skip_before_filter :authenticate_user!, :only => [:show, :index, :search] if APP_CONFIG['anonymous_access']
|
skip_before_filter :authenticate_user!, :only => [:show, :index, :search] if APP_CONFIG['anonymous_access']
|
||||||
|
|
||||||
before_filter :find_build_list, :only => [:show, :publish, :cancel]
|
before_filter :find_build_list, :only => [:show, :publish, :cancel, :update]
|
||||||
before_filter :find_build_list_by_bs, :only => [:publish_build, :status_build, :pre_build, :post_build, :circle_build]
|
before_filter :find_build_list_by_bs, :only => [:publish_build, :status_build, :pre_build, :post_build, :circle_build]
|
||||||
|
|
||||||
load_and_authorize_resource :project, :only => NESTED_ACTIONS
|
load_and_authorize_resource :project, :only => NESTED_ACTIONS
|
||||||
|
@ -40,16 +40,16 @@ class Projects::BuildListsController < Projects::BaseController
|
||||||
|
|
||||||
def create
|
def create
|
||||||
notices, errors = [], []
|
notices, errors = [], []
|
||||||
@platform = Platform.find params[:build_list][:pl_id]
|
@platform = Platform.find params[:build_list][:save_to_platform_id]
|
||||||
params[:build_list][:auto_publish] = false if @platform.released
|
params[:build_list][:auto_publish] = false if @platform.released
|
||||||
Arch.where(:id => params[:arches]).each do |arch|
|
Arch.where(:id => params[:arches]).each do |arch|
|
||||||
Platform.main.where(:id => params[:bpls]).each do |bpl|
|
Platform.main.where(:id => params[:build_for_platforms]).each do |build_for_platform|
|
||||||
@build_list = @project.build_lists.build(params[:build_list])
|
@build_list = @project.build_lists.build(params[:build_list])
|
||||||
@build_list.commit_hash = @project.git_repository.commits(@build_list.project_version.match(/^latest_(.+)/).to_a.last || @build_list.project_version).first.id if @build_list.project_version
|
@build_list.commit_hash = @project.git_repository.commits(@build_list.project_version.match(/^latest_(.+)/).to_a.last || @build_list.project_version).first.id if @build_list.project_version
|
||||||
@build_list.bpl = bpl; @build_list.arch = arch; @build_list.user = current_user
|
@build_list.build_for_platform = build_for_platform; @build_list.arch = arch; @build_list.user = current_user
|
||||||
@build_list.include_repos = @build_list.include_repos.select {|ir| @build_list.bpl.repository_ids.include? ir.to_i}
|
@build_list.include_repos = @build_list.include_repos.select {|ir| @build_list.build_for_platform.repository_ids.include? ir.to_i}
|
||||||
@build_list.priority = 100 # User builds more priority than mass rebuild with zero priority
|
@build_list.priority = current_user.build_priority # User builds more priority than mass rebuild with zero priority
|
||||||
flash_options = {:project_version => @build_list.project_version, :arch => arch.name, :bpl => bpl.name, :pl => @build_list.pl}
|
flash_options = {:project_version => @build_list.project_version, :arch => arch.name, :build_for_platform => build_for_platform.name}
|
||||||
if @build_list.save
|
if @build_list.save
|
||||||
notices << t("flash.build_list.saved", flash_options)
|
notices << t("flash.build_list.saved", flash_options)
|
||||||
else
|
else
|
||||||
|
@ -72,19 +72,14 @@ class Projects::BuildListsController < Projects::BaseController
|
||||||
@item_groups = @build_list.items.group_by_level
|
@item_groups = @build_list.items.group_by_level
|
||||||
end
|
end
|
||||||
|
|
||||||
def publish
|
def update
|
||||||
if @build_list.publish
|
if params[:publish].present? and can?(:publish, @build_list)
|
||||||
redirect_to :back, :notice => t('layout.build_lists.publish_success')
|
publish
|
||||||
|
elsif params[:reject_publish].present? and can?(:reject_publish)
|
||||||
|
reject_publish
|
||||||
else
|
else
|
||||||
redirect_to :back, :notice => t('layout.build_lists.publish_fail')
|
# King Arthur, we are under attack!
|
||||||
end
|
redirect_to :forbidden and return
|
||||||
end
|
|
||||||
|
|
||||||
def reject_publish
|
|
||||||
if @build_list.reject_publish
|
|
||||||
redirect_to :back, :notice => t('layout.build_lists.reject_publish_success')
|
|
||||||
else
|
|
||||||
redirect_to :back, :notice => t('layout.build_lists.reject_publish_fail')
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -117,6 +112,8 @@ class Projects::BuildListsController < Projects::BaseController
|
||||||
@build_list.container_path = params[:container_path]
|
@build_list.container_path = params[:container_path]
|
||||||
@build_list.save
|
@build_list.save
|
||||||
|
|
||||||
|
@build_list.set_packages(ActiveSupport::JSON.decode(params[:pkg_info])) if params[:status].to_i == BuildServer::SUCCESS and params[:pkg_info].present?
|
||||||
|
|
||||||
render :nothing => true, :status => 200
|
render :nothing => true, :status => 200
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -172,4 +169,29 @@ class Projects::BuildListsController < Projects::BaseController
|
||||||
render :nothing => true, :status => 403
|
render :nothing => true, :status => 403
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def publish
|
||||||
|
@build_list.update_type = params[:build_list][:update_type] if params[:build_list][:update_type].present?
|
||||||
|
if params[:create_advisory].present?
|
||||||
|
a = @build_list.build_advisory
|
||||||
|
a.update_type = @build_list.update_type
|
||||||
|
a.project = @build_list.project
|
||||||
|
a.platforms << @build_list.save_to_platform unless a.platforms.include? @build_list.save_to_platform
|
||||||
|
redirect_to :back, :notice => t('layout.build_lists.publish_fail') unless a.update_attributes(params[:build_list][:advisory])
|
||||||
|
end
|
||||||
|
if @build_list.save and @build_list.publish
|
||||||
|
redirect_to :back, :notice => t('layout.build_lists.publish_success')
|
||||||
|
else
|
||||||
|
redirect_to :back, :notice => t('layout.build_lists.publish_fail')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def reject_publish
|
||||||
|
if @build_list.reject_publish
|
||||||
|
redirect_to :back, :notice => t('layout.build_lists.reject_publish_success')
|
||||||
|
else
|
||||||
|
redirect_to :back, :notice => t('layout.build_lists.reject_publish_fail')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,7 +6,7 @@ class Users::BaseController < ApplicationController
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def find_user
|
def find_user
|
||||||
if user_id = params[:owner_name] || params[:user_id] || params[:id]
|
if user_id = params[:uname] || params[:user_id] || params[:id]
|
||||||
@user = User.find_by_insensitive_uname! user_id
|
@user = User.find_by_insensitive_uname! user_id
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
# -*- encoding : utf-8 -*-
|
||||||
|
module AdvisoriesHelper
|
||||||
|
def construct_ref_link(ref)
|
||||||
|
ref = sanitize(ref)
|
||||||
|
url = if ref =~ %r[^http(s?)://*]
|
||||||
|
ref
|
||||||
|
else
|
||||||
|
'http://' << ref
|
||||||
|
end
|
||||||
|
link_to url, url
|
||||||
|
end
|
||||||
|
end
|
|
@ -17,7 +17,12 @@ module ApplicationHelper
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def top_menu_class(base)
|
||||||
|
(controller_name.include?('build_lists') ? controller_name : params[:controller]).include?(base.to_s) ? 'active' : nil
|
||||||
|
end
|
||||||
|
|
||||||
def title_object object
|
def title_object object
|
||||||
|
return object.advisory_id if object.class == Advisory
|
||||||
name = object.class == Group ? object.uname : object.name
|
name = object.class == Group ? object.uname : object.name
|
||||||
object_name = t "activerecord.models.#{object.class.name.downcase}"
|
object_name = t "activerecord.models.#{object.class.name.downcase}"
|
||||||
case object.class.name
|
case object.class.name
|
||||||
|
|
|
@ -4,10 +4,10 @@ module PlatformsHelper
|
||||||
return "" unless platform
|
return "" unless platform
|
||||||
return platform.released ? '/update' : '/release'
|
return platform.released ? '/update' : '/release'
|
||||||
end
|
end
|
||||||
|
|
||||||
def platfrom_printed_name(platform)
|
def platform_printed_name(platform)
|
||||||
return "" unless platform
|
return "" unless platform
|
||||||
platform.released? ? "#{platform.name} #{I18n.t("layout.platforms.released_suffix")}" : platform.name
|
platform.released? ? "#{platform.name} #{I18n.t("layout.platforms.released_suffix")}" : platform.name
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -66,15 +66,18 @@ class Ability
|
||||||
can [:read, :related], BuildList, :project => {:owner_type => 'User', :owner_id => user.id}
|
can [:read, :related], BuildList, :project => {:owner_type => 'User', :owner_id => user.id}
|
||||||
can [:read, :related], BuildList, :project => {:owner_type => 'Group', :owner_id => user.group_ids}
|
can [:read, :related], BuildList, :project => {:owner_type => 'Group', :owner_id => user.group_ids}
|
||||||
can(:read, BuildList, read_relations_for('build_lists', 'projects')) {|build_list| can? :read, build_list.project}
|
can(:read, BuildList, read_relations_for('build_lists', 'projects')) {|build_list| can? :read, build_list.project}
|
||||||
can(:create, BuildList) {|build_list| build_list.project.is_rpm && can?(:write, build_list.project)}
|
can([:create, :update], BuildList) {|build_list| build_list.project.is_rpm && can?(:write, build_list.project)}
|
||||||
|
|
||||||
can(:publish, BuildList) do |build_list|
|
can(:publish, BuildList) do |build_list|
|
||||||
build_list.can_publish? and build_list.pl.released ? local_admin?(build_list.pl) : can?(:write, build_list.project)
|
build_list.can_publish? and build_list.save_to_platform.released ? local_admin?(build_list.save_to_platform) : can?(:write, build_list.project)
|
||||||
end
|
end
|
||||||
can(:reject_publish, BuildList) do |build_list|
|
can(:reject_publish, BuildList) do |build_list|
|
||||||
build_list.can_reject_publish? and build_list.pl.released and local_admin?(build_list.pl)
|
build_list.can_reject_publish? and build_list.save_to_platform.released and local_admin?(build_list.save_to_platform)
|
||||||
end
|
end
|
||||||
can(:cancel, BuildList) {|build_list| build_list.can_cancel? && can?(:write, build_list.project)}
|
can(:cancel, BuildList) {|build_list| build_list.can_cancel? && can?(:write, build_list.project)}
|
||||||
|
|
||||||
|
can [:read], Advisory
|
||||||
|
|
||||||
can [:read, :members], Platform, :visibility => 'open'
|
can [:read, :members], Platform, :visibility => 'open'
|
||||||
can [:read, :owned, :related, :members], Platform, :owner_type => 'User', :owner_id => user.id
|
can [:read, :owned, :related, :members], Platform, :owner_type => 'User', :owner_id => user.id
|
||||||
can [:read, :related, :members], Platform, :owner_type => 'Group', :owner_id => user.group_ids
|
can [:read, :related, :members], Platform, :owner_type => 'Group', :owner_id => user.group_ids
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
class Advisory < ActiveRecord::Base
|
||||||
|
has_and_belongs_to_many :platforms
|
||||||
|
has_many :build_lists
|
||||||
|
belongs_to :project
|
||||||
|
|
||||||
|
validates :description, :update_type, :presence => true
|
||||||
|
|
||||||
|
after_create :generate_advisory_id
|
||||||
|
|
||||||
|
ID_TEMPLATE = 'ROSA%<type>s-%<year>d:%<id>04d'
|
||||||
|
TYPES = {'security' => 'SA', 'bugfix' => 'A'}
|
||||||
|
|
||||||
|
def to_param
|
||||||
|
advisory_id
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
def generate_advisory_id
|
||||||
|
self.advisory_id = sprintf(ID_TEMPLATE, :type => TYPES[self.update_type], :year => Time.now.utc.year, :id => self.id)
|
||||||
|
self.save
|
||||||
|
end
|
||||||
|
end
|
|
@ -2,20 +2,28 @@
|
||||||
class BuildList < ActiveRecord::Base
|
class BuildList < ActiveRecord::Base
|
||||||
belongs_to :project
|
belongs_to :project
|
||||||
belongs_to :arch
|
belongs_to :arch
|
||||||
belongs_to :pl, :class_name => 'Platform'
|
belongs_to :save_to_platform, :class_name => 'Platform'
|
||||||
belongs_to :bpl, :class_name => 'Platform'
|
belongs_to :build_for_platform, :class_name => 'Platform'
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
|
belongs_to :advisory
|
||||||
has_many :items, :class_name => "BuildList::Item", :dependent => :destroy
|
has_many :items, :class_name => "BuildList::Item", :dependent => :destroy
|
||||||
|
has_many :packages, :class_name => "BuildList::Package", :dependent => :destroy
|
||||||
|
|
||||||
|
UPDATE_TYPES = %w[security bugfix enhancement recommended newpackage]
|
||||||
|
RELEASE_UPDATE_TYPES = %w[security bugfix]
|
||||||
|
|
||||||
validates :project_id, :project_version, :arch, :include_repos, :presence => true
|
validates :project_id, :project_version, :arch, :include_repos, :presence => true
|
||||||
validates_numericality_of :priority, :greater_than_or_equal_to => 0
|
validates_numericality_of :priority, :greater_than_or_equal_to => 0
|
||||||
|
validates :update_type, :inclusion => UPDATE_TYPES,
|
||||||
UPDATE_TYPES = %w[security bugfix enhancement recommended newpackage]
|
:unless => Proc.new { |b| b.save_to_platform.released }
|
||||||
validates :update_type, :inclusion => UPDATE_TYPES
|
validates :update_type, :inclusion => RELEASE_UPDATE_TYPES,
|
||||||
|
:if => Proc.new { |b| b.save_to_platform.released }
|
||||||
validate lambda {
|
validate lambda {
|
||||||
errors.add(:bpl, I18n.t('flash.build_list.wrong_platform')) if pl.platform_type == 'main' && pl_id != bpl_id
|
errors.add(:build_for_platform, I18n.t('flash.build_list.wrong_platform')) if save_to_platform.platform_type == 'main' && save_to_platform_id != build_for_platform_id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LIVE_TIME = 3.week
|
||||||
|
|
||||||
# The kernel does not send these statuses directly
|
# The kernel does not send these statuses directly
|
||||||
BUILD_CANCELED = 5000
|
BUILD_CANCELED = 5000
|
||||||
WAITING_FOR_RESPONSE = 4000
|
WAITING_FOR_RESPONSE = 4000
|
||||||
|
@ -62,7 +70,6 @@ class BuildList < ActiveRecord::Base
|
||||||
}
|
}
|
||||||
|
|
||||||
scope :recent, order("#{table_name}.updated_at DESC")
|
scope :recent, order("#{table_name}.updated_at DESC")
|
||||||
|
|
||||||
scope :for_status, lambda {|status| where(:status => status) }
|
scope :for_status, lambda {|status| where(:status => status) }
|
||||||
scope :for_user, lambda { |user| where(:user_id => user.id) }
|
scope :for_user, lambda { |user| where(:user_id => user.id) }
|
||||||
scope :scoped_to_arch, lambda {|arch| where(:arch_id => arch) }
|
scope :scoped_to_arch, lambda {|arch| where(:arch_id => arch) }
|
||||||
|
@ -81,10 +88,11 @@ class BuildList < ActiveRecord::Base
|
||||||
s
|
s
|
||||||
}
|
}
|
||||||
scope :scoped_to_project_name, lambda {|project_name| joins(:project).where('projects.name LIKE ?', "%#{project_name}%")}
|
scope :scoped_to_project_name, lambda {|project_name| joins(:project).where('projects.name LIKE ?', "%#{project_name}%")}
|
||||||
|
scope :outdated, where('updated_at < ? AND status <> ?', Time.now - LIVE_TIME, BUILD_PUBLISHED)
|
||||||
|
|
||||||
serialize :additional_repos
|
serialize :additional_repos
|
||||||
serialize :include_repos
|
serialize :include_repos
|
||||||
|
|
||||||
before_create :set_default_status
|
before_create :set_default_status
|
||||||
after_create :place_build
|
after_create :place_build
|
||||||
|
|
||||||
|
@ -106,6 +114,13 @@ class BuildList < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def set_packages(pkg_hash)
|
||||||
|
build_package(pkg_hash['srpm'], 'source') {|p| p.save!}
|
||||||
|
pkg_hash['rpm'].each do |rpm_hash|
|
||||||
|
build_package(rpm_hash, 'binary') {|p| p.save!}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def publish
|
def publish
|
||||||
return false unless can_publish?
|
return false unless can_publish?
|
||||||
has_published = BuildServer.publish_container bs_id
|
has_published = BuildServer.publish_container bs_id
|
||||||
|
@ -123,7 +138,7 @@ class BuildList < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def can_reject_publish?
|
def can_reject_publish?
|
||||||
can_publish? and pl.released
|
can_publish? and save_to_platform.released
|
||||||
end
|
end
|
||||||
|
|
||||||
def cancel
|
def cancel
|
||||||
|
@ -159,18 +174,26 @@ class BuildList < ActiveRecord::Base
|
||||||
#[WAITING_FOR_RESPONSE, BuildServer::BUILD_PENDING, BuildServer::BUILD_STARTED].include?(status)
|
#[WAITING_FOR_RESPONSE, BuildServer::BUILD_PENDING, BuildServer::BUILD_STARTED].include?(status)
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
protected
|
||||||
def set_default_status
|
|
||||||
self.status = WAITING_FOR_RESPONSE unless self.status.present?
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
def place_build
|
def set_default_status
|
||||||
#XML-RPC params: project_name, project_version, plname, arch, bplname, update_type, build_requires, id_web, include_repos, priority
|
self.status = WAITING_FOR_RESPONSE unless self.status.present?
|
||||||
self.status = BuildServer.add_build_list project.name, project_version, pl.name, arch.name, (pl_id == bpl_id ? '' : bpl.name), update_type, build_requires, id, include_repos, priority
|
return true
|
||||||
self.status = BUILD_PENDING if self.status == 0
|
end
|
||||||
save
|
|
||||||
end
|
|
||||||
#handle_asynchronously :place_build
|
|
||||||
|
|
||||||
|
def place_build
|
||||||
|
#XML-RPC params: project_name, project_version, plname, arch, bplname, update_type, build_requires, id_web, include_repos, priority
|
||||||
|
self.status = BuildServer.add_build_list project.name, project_version, save_to_platform.name, arch.name, (save_to_platform_id == build_for_platform_id ? '' : build_for_platform.name), update_type, build_requires, id, include_repos, priority
|
||||||
|
self.status = BUILD_PENDING if self.status == 0
|
||||||
|
save
|
||||||
|
end
|
||||||
|
|
||||||
|
def build_package(pkg_hash, package_type)
|
||||||
|
packages.create(pkg_hash) do |p|
|
||||||
|
p.project = project # Project.joins(:repositories => :platform).where('platforms.id = ?', save_to_platform.id).find_by_name!(pkg_hash['name'])
|
||||||
|
p.platform = save_to_platform
|
||||||
|
p.package_type = package_type
|
||||||
|
yield p
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
class BuildList::Package < ActiveRecord::Base
|
||||||
|
PACKAGE_TYPES = %w(source binary)
|
||||||
|
|
||||||
|
belongs_to :build_list
|
||||||
|
belongs_to :project
|
||||||
|
belongs_to :platform
|
||||||
|
|
||||||
|
attr_accessible :fullname, :name, :release, :version
|
||||||
|
|
||||||
|
validates :build_list_id, :project_id, :platform_id, :fullname, :package_type, :name, :release, :version, :presence => true
|
||||||
|
validates :package_type, :inclusion => PACKAGE_TYPES
|
||||||
|
end
|
|
@ -4,7 +4,7 @@ class Collaborator
|
||||||
include ActiveModel::Validations
|
include ActiveModel::Validations
|
||||||
include ActiveModel::Serializers::JSON
|
include ActiveModel::Serializers::JSON
|
||||||
include ActiveModel::MassAssignmentSecurity
|
include ActiveModel::MassAssignmentSecurity
|
||||||
extend ActiveModel::Naming
|
extend ActiveModel::Naming
|
||||||
|
|
||||||
attr_accessor :role, :actor, :project, :relation
|
attr_accessor :role, :actor, :project, :relation
|
||||||
attr_reader :id, :actor_id, :actor_type, :actor_name, :project_id
|
attr_reader :id, :actor_id, :actor_type, :actor_name, :project_id
|
||||||
|
|
|
@ -13,6 +13,10 @@ class Platform < ActiveRecord::Base
|
||||||
has_many :actors, :as => :target, :class_name => 'Relation', :dependent => :destroy
|
has_many :actors, :as => :target, :class_name => 'Relation', :dependent => :destroy
|
||||||
has_many :members, :through => :actors, :source => :actor, :source_type => 'User'
|
has_many :members, :through => :actors, :source => :actor, :source_type => 'User'
|
||||||
|
|
||||||
|
has_and_belongs_to_many :advisories
|
||||||
|
|
||||||
|
has_many :packages, :class_name => "BuildList::Package", :dependent => :destroy
|
||||||
|
|
||||||
validates :description, :presence => true
|
validates :description, :presence => true
|
||||||
validates :visibility, :presence => true, :inclusion => {:in => VISIBILITIES}
|
validates :visibility, :presence => true, :inclusion => {:in => VISIBILITIES}
|
||||||
validates :name, :uniqueness => {:case_sensitive => false}, :presence => true, :format => { :with => /^[a-zA-Z0-9_\-]+$/ }
|
validates :name, :uniqueness => {:case_sensitive => false}, :presence => true, :format => { :with => /^[a-zA-Z0-9_\-]+$/ }
|
||||||
|
@ -21,11 +25,12 @@ class Platform < ActiveRecord::Base
|
||||||
before_create :create_directory, :if => lambda {Thread.current[:skip]} # TODO remove this when core will be ready
|
before_create :create_directory, :if => lambda {Thread.current[:skip]} # TODO remove this when core will be ready
|
||||||
before_create :xml_rpc_create, :unless => lambda {Thread.current[:skip]}
|
before_create :xml_rpc_create, :unless => lambda {Thread.current[:skip]}
|
||||||
before_destroy :xml_rpc_destroy
|
before_destroy :xml_rpc_destroy
|
||||||
|
|
||||||
after_update :freeze_platform
|
after_update :freeze_platform
|
||||||
|
|
||||||
after_create lambda { mount_directory_for_rsync unless hidden? }
|
after_create lambda { symlink_directory unless hidden? }
|
||||||
after_destroy lambda { umount_directory_for_rsync unless hidden? }
|
after_destroy lambda { remove_symlink_directory unless hidden? }
|
||||||
|
|
||||||
after_update :update_owner_relation
|
after_update :update_owner_relation
|
||||||
|
|
||||||
scope :search_order, order("CHAR_LENGTH(name) ASC")
|
scope :search_order, order("CHAR_LENGTH(name) ASC")
|
||||||
|
@ -42,7 +47,7 @@ class Platform < ActiveRecord::Base
|
||||||
include Modules::Models::Owner
|
include Modules::Models::Owner
|
||||||
|
|
||||||
def urpmi_list(host, pair = nil)
|
def urpmi_list(host, pair = nil)
|
||||||
blank_pair = {:login => 'login', :pass => 'password'}
|
blank_pair = {:login => 'login', :pass => 'password'}
|
||||||
pair = blank_pair if pair.blank?
|
pair = blank_pair if pair.blank?
|
||||||
urpmi_commands = ActiveSupport::OrderedHash.new
|
urpmi_commands = ActiveSupport::OrderedHash.new
|
||||||
|
|
||||||
|
@ -63,7 +68,7 @@ class Platform < ActiveRecord::Base
|
||||||
build_path(name)
|
build_path(name)
|
||||||
end
|
end
|
||||||
|
|
||||||
def mount_path
|
def symlink_path
|
||||||
Rails.root.join("public", "downloads", name)
|
Rails.root.join("public", "downloads", name)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -115,14 +120,14 @@ class Platform < ActiveRecord::Base
|
||||||
with_skip {c.save} and c.clone_relations(self) and c.delay.xml_rpc_clone
|
with_skip {c.save} and c.clone_relations(self) and c.delay.xml_rpc_clone
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def change_visibility
|
def change_visibility
|
||||||
if !self.hidden?
|
if !self.hidden?
|
||||||
self.update_attribute(:visibility, 'hidden')
|
self.update_attribute(:visibility, 'hidden')
|
||||||
umount_directory_for_rsync
|
remove_symlink_directory
|
||||||
else
|
else
|
||||||
self.update_attribute(:visibility, 'open')
|
self.update_attribute(:visibility, 'open')
|
||||||
mount_directory_for_rsync
|
symlink_directory
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -130,19 +135,17 @@ class Platform < ActiveRecord::Base
|
||||||
system("sudo mkdir -p -m 0777 #{path}")
|
system("sudo mkdir -p -m 0777 #{path}")
|
||||||
end
|
end
|
||||||
|
|
||||||
def mount_directory_for_rsync
|
def symlink_directory
|
||||||
# umount_directory_for_rsync # TODO ignore errors
|
# umount_directory_for_rsync # TODO ignore errors
|
||||||
system("sudo mkdir -p -m 0777 #{mount_path}")
|
system("ln -s #{path} #{symlink_path}")
|
||||||
system("sudo mount --bind #{path} #{mount_path}")
|
|
||||||
Arch.all.each do |arch|
|
Arch.all.each do |arch|
|
||||||
str = "country=Russian Federation,city=Moscow,latitude=52.18,longitude=48.88,bw=1GB,version=2011,arch=#{arch.name},type=distrib,url=#{public_downloads_url}\n"
|
str = "country=Russian Federation,city=Moscow,latitude=52.18,longitude=48.88,bw=1GB,version=2011,arch=#{arch.name},type=distrib,url=#{public_downloads_url}\n"
|
||||||
File.open(File.join(mount_path, "#{name}.#{arch.name}.list"), 'w') {|f| f.write(str) }
|
File.open(File.join(symlink_path, "#{name}.#{arch.name}.list"), 'w') {|f| f.write(str) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def umount_directory_for_rsync
|
def remove_symlink_directory
|
||||||
system("sudo umount #{mount_path}")
|
system("rm -Rf #{symlink_path}")
|
||||||
system("sudo rm -Rf #{mount_path}")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_owner_relation
|
def update_owner_relation
|
||||||
|
@ -210,6 +213,6 @@ class Platform < ActiveRecord::Base
|
||||||
if released_changed? && released == true
|
if released_changed? && released == true
|
||||||
result = BuildServer.freeze(name)
|
result = BuildServer.freeze(name)
|
||||||
raise "Failed freeze platform #{name} with code #{result}" if result != BuildServer::SUCCESS
|
raise "Failed freeze platform #{name} with code #{result}" if result != BuildServer::SUCCESS
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
class Project < ActiveRecord::Base
|
class Project < ActiveRecord::Base
|
||||||
VISIBILITIES = ['open', 'hidden']
|
VISIBILITIES = ['open', 'hidden']
|
||||||
MAX_OWN_PROJECTS = 32000
|
MAX_OWN_PROJECTS = 32000
|
||||||
|
NAME_REGEXP = /[a-zA-Z0-9_\-\+\.]+/
|
||||||
|
|
||||||
belongs_to :owner, :polymorphic => true, :counter_cache => :own_projects_count
|
belongs_to :owner, :polymorphic => true, :counter_cache => :own_projects_count
|
||||||
|
|
||||||
|
@ -18,7 +19,10 @@ class Project < ActiveRecord::Base
|
||||||
has_many :collaborators, :through => :relations, :source => :actor, :source_type => 'User'
|
has_many :collaborators, :through => :relations, :source => :actor, :source_type => 'User'
|
||||||
has_many :groups, :through => :relations, :source => :actor, :source_type => 'Group'
|
has_many :groups, :through => :relations, :source => :actor, :source_type => 'Group'
|
||||||
|
|
||||||
validates :name, :uniqueness => {:scope => [:owner_id, :owner_type], :case_sensitive => false}, :presence => true, :format => {:with => /^[a-zA-Z0-9_\-\+\.]+$/}
|
has_many :advisories # should be without :dependent => :destroy
|
||||||
|
has_many :packages, :class_name => "BuildList::Package", :dependent => :destroy
|
||||||
|
|
||||||
|
validates :name, :uniqueness => {:scope => [:owner_id, :owner_type], :case_sensitive => false}, :presence => true, :format => {:with => /^#{NAME_REGEXP}$/, :message => I18n.t("activerecord.errors.project.uname")}
|
||||||
validates :owner, :presence => true
|
validates :owner, :presence => true
|
||||||
validate { errors.add(:base, :can_have_less_or_equal, :count => MAX_OWN_PROJECTS) if owner.projects.size >= MAX_OWN_PROJECTS }
|
validate { errors.add(:base, :can_have_less_or_equal, :count => MAX_OWN_PROJECTS) if owner.projects.size >= MAX_OWN_PROJECTS }
|
||||||
|
|
||||||
|
@ -77,8 +81,8 @@ class Project < ActiveRecord::Base
|
||||||
|
|
||||||
arch = Arch.find_by_name(arch) if arch.acts_like?(:string)
|
arch = Arch.find_by_name(arch) if arch.acts_like?(:string)
|
||||||
build_lists.create do |bl|
|
build_lists.create do |bl|
|
||||||
bl.pl = platform
|
bl.save_to_platform = platform
|
||||||
bl.bpl = platform
|
bl.build_to_platform = platform
|
||||||
bl.update_type = 'newpackage'
|
bl.update_type = 'newpackage'
|
||||||
bl.arch = arch
|
bl.arch = arch
|
||||||
bl.project_version = "latest_#{platform.name}"
|
bl.project_version = "latest_#{platform.name}"
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
-set_meta_tags :title => nil
|
-set_meta_tags :title => nil
|
||||||
%h3.fix= t("layout.activity_feed.header")
|
%h3.fix
|
||||||
|
= t("layout.activity_feed.header")
|
||||||
|
= link_to image_tag("rss.ico", :width => '15px', :height => '15px', :class => 'atom_icon'), atom_activity_feeds_path(:format => 'atom', :token => current_user.authentication_token)
|
||||||
=render 'list'
|
=render 'list'
|
||||||
|
|
||||||
- content_for :sidebar, render('sidebar')
|
- content_for :sidebar, render('sidebar')
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
%h3= t("layout.advisories.form_header")
|
||||||
|
|
||||||
|
.leftlist
|
||||||
|
= f.label :description, t("activerecord.attributes.advisory.description")
|
||||||
|
.rightlist
|
||||||
|
= f.text_area :description, :class => 'text_field', :cols => 80
|
||||||
|
.both
|
||||||
|
|
||||||
|
.leftlist
|
||||||
|
= f.label :references, t("activerecord.attributes.advisory.references")
|
||||||
|
%span.hint
|
||||||
|
= t("layout.advisories.ref_comment")
|
||||||
|
.rightlist
|
||||||
|
= f.text_area :references, :class => 'text_field', :cols => 80
|
||||||
|
.both
|
|
@ -0,0 +1,8 @@
|
||||||
|
%table#myTable.tablesorter.advisories{:cellspacing => "0", :cellpadding => "0"}
|
||||||
|
%thead
|
||||||
|
%tr
|
||||||
|
%th.th1= t("activerecord.attributes.advisory.advisory_id")
|
||||||
|
%th.th2= t("layout.advisories.affected_versions")
|
||||||
|
%th.th3= t("activerecord.attributes.advisory.description")
|
||||||
|
%tbody
|
||||||
|
= render :partial => 'list_item', :collection => list, :as => :advisory
|
|
@ -0,0 +1,7 @@
|
||||||
|
%tr{:class => cycle("odd", "even")}
|
||||||
|
%td= link_to advisory.advisory_id, advisory_path(advisory)
|
||||||
|
%td
|
||||||
|
- advisory.platforms.each do |platform|
|
||||||
|
= link_to platform_printed_name(platform), platform_path(platform)
|
||||||
|
%br
|
||||||
|
%td= truncate(advisory.description, :length => 50)
|
|
@ -0,0 +1,7 @@
|
||||||
|
- content_for :submenu do
|
||||||
|
- act = action_name.to_sym; contr = controller_name.to_sym
|
||||||
|
.left
|
||||||
|
= @advisory.advisory_id if @advisory.present?
|
||||||
|
%nav
|
||||||
|
%ul
|
||||||
|
%li= link_to t('layout.list'), advisories_path, :class => act.in?([:index]) ? 'active' : nil
|
|
@ -0,0 +1,4 @@
|
||||||
|
- set_meta_tags :title => t('layout.advisories.list_header')
|
||||||
|
- render :partial => 'submenu'
|
||||||
|
= render :partial => 'list', :object => @advisories
|
||||||
|
= will_paginate @advisories
|
|
@ -0,0 +1,37 @@
|
||||||
|
- set_meta_tags :title => [title_object(@advisory), t('activerecord.models.advisory')]
|
||||||
|
- render :partial => 'submenu'
|
||||||
|
|
||||||
|
%h3= "#{t("activerecord.models.advisory")} #{@advisory.advisory_id}".html_safe
|
||||||
|
|
||||||
|
.leftlist= "#{t("layout.advisories.project_name")}:".html_safe
|
||||||
|
.rightlist= link_to @advisory.project.name, project_path(@advisory.project)
|
||||||
|
.both
|
||||||
|
|
||||||
|
.leftlist= "#{t("activerecord.attributes.advisory.created_at")}:".html_safe
|
||||||
|
.rightlist= @advisory.created_at
|
||||||
|
.both
|
||||||
|
|
||||||
|
.leftlist= "#{t("activerecord.attributes.advisory.advisory_id")}:".html_safe
|
||||||
|
.rightlist= @advisory.advisory_id
|
||||||
|
.both
|
||||||
|
|
||||||
|
.leftlist= "#{t("layout.advisories.affected_versions")}:".html_safe
|
||||||
|
.rightlist
|
||||||
|
- @advisory.platforms.each do |platform|
|
||||||
|
= link_to platform_printed_name(platform), platform_path(platform)
|
||||||
|
%br
|
||||||
|
.both
|
||||||
|
|
||||||
|
.leftlist= "#{t("activerecord.attributes.advisory.description")}:".html_safe
|
||||||
|
.rightlist= simple_format @advisory.description
|
||||||
|
.both
|
||||||
|
|
||||||
|
.leftlist= "#{t("activerecord.attributes.advisory.references")}:".html_safe
|
||||||
|
.rightlist
|
||||||
|
- @advisory.references.gsub(/\r| /, '').split("\n").each do |ref|
|
||||||
|
= construct_ref_link(ref)
|
||||||
|
%br
|
||||||
|
.both
|
||||||
|
|
||||||
|
:javascript
|
||||||
|
$('article .all').addClass('bigpadding');
|
|
@ -1,5 +1,5 @@
|
||||||
-set_meta_tags :title => [title_object(@group), t('layout.groups.edit')]
|
-set_meta_tags :title => [title_object(@group), t('layout.groups.edit')]
|
||||||
= form_for @group do |f|
|
= form_for @group, :url => profile_group_path(@group) do |f|
|
||||||
= render "form", :f => f
|
= render "form", :f => f
|
||||||
|
|
||||||
.hr
|
.hr
|
||||||
|
@ -9,7 +9,7 @@
|
||||||
.hr
|
.hr
|
||||||
.leftside= t("layout.groups.delete_warning")
|
.leftside= t("layout.groups.delete_warning")
|
||||||
.rightside
|
.rightside
|
||||||
= link_to t("layout.delete"), group_path(@group), :method => :delete, :confirm => t("layout.groups.confirm_delete"), :class => 'button' if can? :destroy, @group
|
= link_to t("layout.delete"), profile_group_path(@group), :method => :delete, :confirm => t("layout.groups.confirm_delete"), :class => 'button' if can? :destroy, @group
|
||||||
.both
|
.both
|
||||||
|
|
||||||
- content_for :sidebar, render('sidebar')
|
- content_for :sidebar, render('sidebar')
|
||||||
|
|
|
@ -2,6 +2,6 @@
|
||||||
%ul
|
%ul
|
||||||
- (collection = t which_menu).each do |base, title|
|
- (collection = t which_menu).each do |base, title|
|
||||||
- if can? :index, base.to_s.classify.constantize
|
- if can? :index, base.to_s.classify.constantize
|
||||||
%li= link_to title, send(:"#{namespace}#{base}_path"), :class => params[:controller].include?(base.to_s) ? 'active' : ''
|
%li= link_to title, send(:"#{namespace}#{base}_path"), :class => top_menu_class(base)
|
||||||
- if current_user.try(:admin?) and which_menu == 'top_menu'
|
- if current_user.try(:admin?) and which_menu == 'top_menu'
|
||||||
%li= link_to t('admins_menu_header'), admin_users_path, :class => t('admins_menu').has_key?(controller_name.to_sym) ? 'active' : ''
|
%li= link_to t('admins_menu_header'), admin_users_path, :class => top_menu_class('admin')
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
!!!
|
||||||
|
%html
|
||||||
|
%head
|
||||||
|
%meta{:content => "text/html; charset=utf-8", "http-equiv" => "Content-Type"}/
|
||||||
|
%title Сборочная среда
|
||||||
|
= stylesheet_link_tag "tour"
|
||||||
|
/[if lt IE 9]
|
||||||
|
= javascript_include_tag 'https://html5shiv.googlecode.com/svn/trunk/html5.js'
|
||||||
|
= javascript_include_tag "tour"
|
||||||
|
= csrf_meta_tag
|
||||||
|
%body
|
||||||
|
.wrap
|
||||||
|
%header.top
|
||||||
|
.left
|
||||||
|
.middle
|
||||||
|
%menu
|
||||||
|
.logo= link_to image_tag('logo-mini.png', :alt => 'logo'), root_path
|
||||||
|
= render 'layouts/menu/top', :which_menu => 'top_menu'
|
||||||
|
.information
|
||||||
|
= render 'search/form'
|
||||||
|
- if current_user
|
||||||
|
.user
|
||||||
|
.avatar= image_tag avatar_url(current_user), :alt => 'avatar', :height => "30"
|
||||||
|
.profile
|
||||||
|
%a{:href => "#"}
|
||||||
|
= current_user.uname
|
||||||
|
= image_tag 'expand-white.png', :alt => 'ex'
|
||||||
|
.both
|
||||||
|
.both
|
||||||
|
.droplist-wrap
|
||||||
|
#droplist.droplist
|
||||||
|
.a= link_to current_user.uname, current_user
|
||||||
|
.a= link_to t('layout.settings.label'), profile_settings_path
|
||||||
|
.a= link_to t('layout.logout'), destroy_user_session_path, :method => :delete
|
||||||
|
- else
|
||||||
|
.user
|
||||||
|
.profile= link_to t("layout.devise.shared_links.sign_in"), new_user_session_path
|
||||||
|
.right
|
||||||
|
.both
|
||||||
|
/ Page
|
||||||
|
.tour
|
||||||
|
=image_tag "tour-top#{I18n.locale == :en ? '-eng' : ''}.png", :alt => 'ABF'
|
||||||
|
.both
|
||||||
|
%article
|
||||||
|
= yield
|
||||||
|
.both
|
||||||
|
-# No idea why here was this div...
|
||||||
|
-#.tour-gap
|
||||||
|
%footer= render "layouts/menu/bottom"
|
||||||
|
= render 'layouts/counters' unless current_user.try(:admin?)
|
||||||
|
:javascript
|
||||||
|
$(document).ready(function() {
|
||||||
|
$().piroBox_ext({
|
||||||
|
piro_speed : 700,
|
||||||
|
bg_alpha : 0.5,
|
||||||
|
piro_scroll : true //pirobox always positioned at the center of the page
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,19 @@
|
||||||
|
.feature-wrap
|
||||||
|
.feature
|
||||||
|
-if is_left
|
||||||
|
.left
|
||||||
|
%h1=t "tour.#{entry}"
|
||||||
|
%p
|
||||||
|
=raw t "tour.#{entry}_description"
|
||||||
|
.right
|
||||||
|
%a.pirobox{:href => image_path("tour/big/#{entry}.png"), :rel => "single", :title => t("tour.#{entry}")}
|
||||||
|
=image_tag "tour/#{entry}.png"
|
||||||
|
-else
|
||||||
|
.left
|
||||||
|
%a.pirobox{:href => image_path("tour/big/#{entry}.png"), :rel => "single", :title => t("tour.#{entry}")}
|
||||||
|
=image_tag "tour/#{entry}.png"
|
||||||
|
.right
|
||||||
|
%h1=t "tour.#{entry}"
|
||||||
|
%p
|
||||||
|
=raw t "tour.#{entry}_description"
|
||||||
|
.both
|
|
@ -0,0 +1,4 @@
|
||||||
|
%ul
|
||||||
|
-%w(projects sources builds).each do |entry|
|
||||||
|
%li
|
||||||
|
=link_to t("tour.#{entry}"), tour_inside_path(entry), :class => params[:id] == entry ? 'active' : ''
|
|
@ -0,0 +1,39 @@
|
||||||
|
.feature-wrap
|
||||||
|
.feature
|
||||||
|
.left
|
||||||
|
%a.pirobox{:href => image_path('tour/big/control.png'), :rel => "single", :title => t('tour.projects')}
|
||||||
|
=image_tag 'tour/control.png'
|
||||||
|
.right
|
||||||
|
%a{:href => tour_inside_path('projects')}
|
||||||
|
%h1=t 'tour.projects'
|
||||||
|
%p
|
||||||
|
=t 'tour.projects_header'
|
||||||
|
%br
|
||||||
|
=link_to t('tour.read_more'), tour_inside_path('projects')
|
||||||
|
.both
|
||||||
|
.feature-wrap
|
||||||
|
.feature
|
||||||
|
.left
|
||||||
|
%a{:href => tour_inside_path('sources')}
|
||||||
|
%h1=t 'tour.sources'
|
||||||
|
%p
|
||||||
|
=t 'tour.sources_header'
|
||||||
|
%br/
|
||||||
|
=link_to t('tour.read_more'), tour_inside_path('sources')
|
||||||
|
.right
|
||||||
|
%a.pirobox{:href => image_path('tour/big/source.png'), :rel => "single", :title => t('tour.sources')}
|
||||||
|
=image_tag 'tour/source.png'
|
||||||
|
.both
|
||||||
|
.feature-wrap
|
||||||
|
.feature
|
||||||
|
.left
|
||||||
|
%a.pirobox{:href => image_path('tour/big/monitoring.png'), :rel => "single", :title => t('tour.builds')}
|
||||||
|
=image_tag 'tour/monitoring.png'
|
||||||
|
.right
|
||||||
|
%a{:href => tour_inside_path('builds')}
|
||||||
|
%h1=t 'tour.builds'
|
||||||
|
%p
|
||||||
|
=t 'tour.builds_header'
|
||||||
|
%br/
|
||||||
|
=link_to t('tour.read_more'), tour_inside_path('builds')
|
||||||
|
.both
|
|
@ -0,0 +1,65 @@
|
||||||
|
.sub-menu.tour
|
||||||
|
%nav
|
||||||
|
%ul
|
||||||
|
%li
|
||||||
|
=link_to 'Управление проектами', tour_inside_path('projects')
|
||||||
|
%li
|
||||||
|
=link_to 'Исходный код', tour_inside_path('sources'), :class => 'active'
|
||||||
|
%li
|
||||||
|
=link_to 'Сборка проектов', tour_inside_path('builds')
|
||||||
|
.both
|
||||||
|
/ Page
|
||||||
|
%article
|
||||||
|
/ Single page content
|
||||||
|
.feature-wrap
|
||||||
|
.feature
|
||||||
|
.left
|
||||||
|
%a.pirobox{:href => image_path('tour/big/source.png'), :rel => "single", :title => "Исходный код онлайн"}
|
||||||
|
=image_tag 'tour/2/source.png'
|
||||||
|
.right
|
||||||
|
%h1 Исходный код онлайн
|
||||||
|
%p
|
||||||
|
Мы сфокусировались на том, чтобы сделать исходный код
|
||||||
|
доступным и прозрачным. Все, что вы выложите в git-репозиторий,
|
||||||
|
мгновенно станет доступным для просмотра в режиме онлайн,
|
||||||
|
чтобы вы могли поделиться им с людьми, даже если они не
|
||||||
|
используют Git. На главной странице каждого проекта есть список
|
||||||
|
файлов проекта, а также информация о последнем изменении.
|
||||||
|
Вы можете сразу увидеть самое важное в вашем проекте: код.
|
||||||
|
.both
|
||||||
|
.feature-wrap
|
||||||
|
.feature
|
||||||
|
.left
|
||||||
|
%h1 История файла
|
||||||
|
%p
|
||||||
|
Каждый файл в git-репозитории имеет историю, которую вы
|
||||||
|
легко можете посмотреть: кто, когда и что в нем поменял.
|
||||||
|
.right
|
||||||
|
%a.pirobox{:href => image_path('tour/big/history.png'), :rel => "single", :title => "История файла"}
|
||||||
|
=image_tag 'tour/2/history.png'
|
||||||
|
.both
|
||||||
|
.feature-wrap
|
||||||
|
.feature
|
||||||
|
.left
|
||||||
|
%a.pirobox{:href => image_path('tour/big/annotation.png'), :rel => "single", :title => "Аннотация файла"}
|
||||||
|
=image_tag 'tour/2/annotation.png'
|
||||||
|
.right
|
||||||
|
%h1 Аннотация файла
|
||||||
|
%p
|
||||||
|
Ищете автора фрагмента кода? Откройте аннотацию файла
|
||||||
|
(Blame), чтобы увидеть: кто и в каком коммите последний
|
||||||
|
изменял данный фрагмент.
|
||||||
|
.both
|
||||||
|
.feature-wrap
|
||||||
|
.feature
|
||||||
|
.left
|
||||||
|
%h1 Редактирования онлайн
|
||||||
|
%p
|
||||||
|
Вам нужно быстро внести изменение в файл? Исправить
|
||||||
|
орфографические ошибки на вашем мобильном телефоне?
|
||||||
|
Мы предлагаем простой редактор для каждого файла в
|
||||||
|
git-репозитории.
|
||||||
|
.right
|
||||||
|
%a.pirobox{:href => image_path('tour/big/edit.png'), :rel => "single", :title => "Редактирования онлайн"}
|
||||||
|
=image_tag 'tour/2/edit.png'
|
||||||
|
.both
|
|
@ -0,0 +1,9 @@
|
||||||
|
.sub-menu.tour
|
||||||
|
%nav
|
||||||
|
=render 'pages/tour/submenu'
|
||||||
|
.both
|
||||||
|
/ Page
|
||||||
|
%article
|
||||||
|
/ Single page content
|
||||||
|
-@entries.each_with_index do |el, ind|
|
||||||
|
=render :partial => 'pages/tour/entry', :locals => {:entry => el, :is_left => ind.odd?}
|
|
@ -1,5 +1,5 @@
|
||||||
- content_for :submenu do
|
- content_for :submenu do
|
||||||
- act = action_name.to_sym; contr = controller_name.to_sym
|
- act = action_name.to_sym; contr = controller_name.to_sym
|
||||||
.left= platfrom_printed_name(@platform)
|
.left= platform_printed_name(@platform)
|
||||||
%nav
|
%nav
|
||||||
%ul
|
%ul
|
||||||
|
|
|
@ -6,5 +6,5 @@
|
||||||
%tbody
|
%tbody
|
||||||
- @platforms.each do |platform|
|
- @platforms.each do |platform|
|
||||||
%tr{:class => cycle("odd", "even")}
|
%tr{:class => cycle("odd", "even")}
|
||||||
%td= link_to platfrom_printed_name(platform), platform_path(platform)
|
%td= link_to platform_printed_name(platform), platform_path(platform)
|
||||||
%td= platform.distrib_type
|
%td= platform.distrib_type
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
- platform.repositories.each do |repo|
|
- platform.repositories.each do |repo|
|
||||||
.both
|
.both
|
||||||
= check_box_tag "build_list[include_repos][]", repo.id, repo.name == 'main' || @project.repositories.map(&:id).include?(repo.id), :id => "include_repos_#{repo.id}", :pl_id => platform.id, :rep_name => repo.name
|
= check_box_tag "build_list[include_repos][]", repo.id, repo.name == 'main' || @project.repositories.map(&:id).include?(repo.id), :id => "include_repos_#{repo.id}", :save_to_platform_id => platform.id, :rep_name => repo.name
|
||||||
= label_tag "include_repos_#{repo.id}", repo.name
|
= label_tag "include_repos_#{repo.id}", repo.name
|
||||||
|
|
|
@ -1,18 +1,17 @@
|
||||||
-set_meta_tags :title => [title_object(@project), t('layout.build_lists.new_header')]
|
-set_meta_tags :title => [title_object(@project), t('layout.build_lists.new_header')]
|
||||||
= form_for [@project, @build_list], :html => { :class => :form, :method => :post } do |f|
|
= form_for [@project, @build_list], :html => { :class => :form, :method => :post } do |f|
|
||||||
%section.left
|
%section.left
|
||||||
%h3= t("activerecord.attributes.build_list.bpl")
|
%h3= t("activerecord.attributes.build_list.build_for_platform")
|
||||||
.all_platforms
|
.all_platforms
|
||||||
- Platform.main.each do |pl|
|
- Platform.main.each do |pl|
|
||||||
- if pl.repository_ids.size > 0
|
- if pl.repository_ids.size > 0
|
||||||
.both
|
.both
|
||||||
= check_box_tag "bpls[]", pl.id, (params[:bpls]||[]).include?(pl.id.to_s), :class => 'build_bpl_ids', :id => "bpls_#{pl.id}", :'data-released' => pl.released ? 1 : 0
|
= check_box_tag "build_for_platforms[]", pl.id, (params[:build_for_platforms]||[]).include?(pl.id.to_s), :class => 'build_bpl_ids', :id => "bpls_#{pl.id}", :'data-released' => pl.released ? 1 : 0
|
||||||
= label_tag "bpls_#{pl.id}", pl.name
|
= label_tag "bpls_#{pl.id}", pl.name
|
||||||
.offset25{:style => 'padding-left: 25px'}
|
.offset25{:style => 'padding-left: 25px'}= render 'include_repos', :platform => pl
|
||||||
= render 'include_repos', :platform => pl
|
|
||||||
%section.right
|
%section.right
|
||||||
%h3= t("activerecord.attributes.build_list.pl")
|
%h3= t("activerecord.attributes.build_list.save_to_platform")
|
||||||
.lineForm= f.select :pl_id, @project.repositories.collect{|r| ["#{r.platform.name}/#{r.name}", r.platform.id]}
|
.lineForm= f.select :save_to_platform_id, @project.repositories.collect{|r| ["#{r.platform.name}/#{r.name}", r.platform.id]}
|
||||||
%h3= t("activerecord.attributes.build_list.project_version")
|
%h3= t("activerecord.attributes.build_list.project_version")
|
||||||
- if controller.action_name == 'new'
|
- if controller.action_name == 'new'
|
||||||
.lineForm= f.select :project_version, @project.versions_for_group_select, :selected => "latest_" + @project.default_branch
|
.lineForm= f.select :project_version, @project.versions_for_group_select, :selected => "latest_" + @project.default_branch
|
||||||
|
@ -21,10 +20,7 @@
|
||||||
%h3= t("activerecord.attributes.build_list.arch")
|
%h3= t("activerecord.attributes.build_list.arch")
|
||||||
- Arch.recent.each do |arch|
|
- Arch.recent.each do |arch|
|
||||||
.both
|
.both
|
||||||
- if controller.action_name == 'new'
|
= check_box_tag "arches[]", arch.id, (params[:arches]||[]).include?(arch.id.to_s) || controller.action_name == 'new', :id => "arches_#{arch.id}"
|
||||||
= check_box_tag "arches[]", arch.id, (params[:arches]||[]).include?(arch.id.to_s), :id => "arches_#{arch.id}", :checked => 'checked'
|
|
||||||
- else
|
|
||||||
= check_box_tag "arches[]", arch.id, (params[:arches]||[]).include?(arch.id.to_s), :id => "arches_#{arch.id}"
|
|
||||||
= label_tag "arches_#{arch.id}", arch.name
|
= label_tag "arches_#{arch.id}", arch.name
|
||||||
%h3= t("activerecord.attributes.build_list.update_type")
|
%h3= t("activerecord.attributes.build_list.update_type")
|
||||||
.lineForm= f.select :update_type, BuildList::UPDATE_TYPES
|
.lineForm= f.select :update_type, BuildList::UPDATE_TYPES
|
||||||
|
|
|
@ -4,66 +4,82 @@
|
||||||
%p= @build_list.human_status
|
%p= @build_list.human_status
|
||||||
%p= @build_list.updated_at
|
%p= @build_list.updated_at
|
||||||
.both
|
.both
|
||||||
%h3= t("layout.build_lists.main_data")
|
= form_for @build_list do |f|
|
||||||
.leftside.width125= t("activerecord.attributes.build_list.container_path")
|
%h3= t("layout.build_lists.main_data")
|
||||||
.leftside
|
.leftlist= t("activerecord.attributes.build_list.container_path")
|
||||||
- if @build_list.status == BuildList::BUILD_PUBLISHED
|
.rightlist
|
||||||
= t("layout.build_lists.container_published")
|
- if @build_list.status == BuildList::BUILD_PUBLISHED
|
||||||
- elsif @build_list.container_path.present?
|
= t("layout.build_lists.container_published")
|
||||||
- container_url = "http://#{request.host_with_port}/downloads#{@build_list.container_path}"
|
- elsif @build_list.container_path.present?
|
||||||
= link_to container_url, container_url
|
- container_url = "http://#{request.host_with_port}/downloads#{@build_list.container_path}"
|
||||||
.both
|
= link_to container_url, container_url
|
||||||
.leftside.width125= t("activerecord.attributes.build_list.user")
|
|
||||||
.leftside
|
|
||||||
= link_to @build_list.user.try(:fullname), @build_list.user
|
|
||||||
.both
|
|
||||||
= link_to t("layout.publish"), publish_build_list_path(@build_list), :method => "put", :confirm => t("layout.confirm"), :class => "button tmargin10" if @build_list.can_publish? and can?(:publish, @build_list)
|
|
||||||
= link_to t("layout.reject_publish"), reject_publish_build_list_path(@build_list), :method => "put", :confirm => t("layout.confirm"), :class => "button tmargin10" if @build_list.can_reject_publish? and can?(:reject_publish, @build_list)
|
|
||||||
.hr
|
|
||||||
%h3= t("layout.build_lists.main_data")
|
|
||||||
.leftside.width125= t("activerecord.attributes.build_list.bpl")
|
|
||||||
.leftside
|
|
||||||
= link_to @build_list.bpl.name, @build_list.bpl
|
|
||||||
.both
|
|
||||||
.leftside.width125= t("activerecord.attributes.build_list.pl")
|
|
||||||
.leftside
|
|
||||||
= link_to @build_list.pl.name, @build_list.pl
|
|
||||||
.both
|
|
||||||
.leftside.width125= t("activerecord.attributes.build_list.include_repos")
|
|
||||||
.leftside= (@build_list.include_repos||[]).map{|r| Repository.find(r).name}.join(', ')
|
|
||||||
.both
|
|
||||||
.leftside.width125= t("activerecord.attributes.build_list.update_type")
|
|
||||||
.leftside= @build_list.update_type
|
|
||||||
.both
|
|
||||||
.leftside.width125= t("activerecord.attributes.build_list.build_requires")
|
|
||||||
.leftside= @build_list.build_requires
|
|
||||||
.both
|
|
||||||
.leftside.width125= t("activerecord.attributes.build_list.auto_publish")
|
|
||||||
.leftside= @build_list.auto_publish
|
|
||||||
.both
|
|
||||||
.leftside.width125= t("activerecord.attributes.build_list.project_version")
|
|
||||||
.leftside= @build_list.project_version
|
|
||||||
.both
|
|
||||||
.leftside.width125= t("activerecord.attributes.build_list.arch")
|
|
||||||
.leftside= @build_list.arch.name
|
|
||||||
.both
|
|
||||||
.leftside.width125= t("activerecord.attributes.build_list.updated_at")
|
|
||||||
.leftside= @build_list.updated_at
|
|
||||||
.both
|
|
||||||
.leftside.width125= t("activerecord.attributes.build_list.is_circle")
|
|
||||||
.leftside= t("layout.#{@build_list.is_circle?}_")
|
|
||||||
.both
|
|
||||||
- if !@build_list.in_work? && @build_list.started_at
|
|
||||||
%br
|
|
||||||
.leftside.width125
|
|
||||||
.leftside= @build_list.human_duration
|
|
||||||
.both
|
.both
|
||||||
- if @build_list.in_work?
|
.leftlist= t("activerecord.attributes.build_list.user")
|
||||||
%br
|
.rightlist
|
||||||
.leftside.width125
|
= link_to @build_list.user.try(:fullname), @build_list.user
|
||||||
.leftside
|
|
||||||
= "#{@build_list.human_current_duration} / #{@build_list.project.human_average_build_time}"
|
|
||||||
.both
|
.both
|
||||||
|
.leftlist= t("activerecord.attributes.build_list.build_for_platform")
|
||||||
|
.rightlist
|
||||||
|
= link_to @build_list.build_for_platform.name, @build_list.build_for_platform
|
||||||
|
.both
|
||||||
|
.leftlist= t("activerecord.attributes.build_list.save_to_platform")
|
||||||
|
.rightlist
|
||||||
|
= link_to @build_list.save_to_platform.name, @build_list.save_to_platform
|
||||||
|
.both
|
||||||
|
.leftlist= t("activerecord.attributes.build_list.include_repos")
|
||||||
|
.rightlist= (@build_list.include_repos||[]).map{|r| Repository.find(r).name}.join(', ')
|
||||||
|
.both
|
||||||
|
.leftlist= t("activerecord.attributes.build_list.update_type")
|
||||||
|
.rightlist
|
||||||
|
- if @build_list.can_publish? and can?(:publish, @build_list)
|
||||||
|
= f.select :update_type, options_for_select(BuildList::RELEASE_UPDATE_TYPES, @build_list.update_type)
|
||||||
|
- else
|
||||||
|
= @build_list.update_type
|
||||||
|
.both
|
||||||
|
.leftlist= t("activerecord.attributes.build_list.build_requires")
|
||||||
|
.rightlist= t("layout.#{@build_list.build_requires}_")
|
||||||
|
.both
|
||||||
|
.leftlist= t("activerecord.attributes.build_list.auto_publish")
|
||||||
|
.rightlist= t("layout.#{@build_list.auto_publish}_")
|
||||||
|
.both
|
||||||
|
.leftlist= t("activerecord.attributes.build_list.project_version")
|
||||||
|
.rightlist= @build_list.project_version
|
||||||
|
.both
|
||||||
|
.leftlist= t("activerecord.attributes.build_list.arch")
|
||||||
|
.rightlist= @build_list.arch.name
|
||||||
|
.both
|
||||||
|
.leftlist= t("activerecord.attributes.build_list.updated_at")
|
||||||
|
.rightlist= @build_list.updated_at
|
||||||
|
.both
|
||||||
|
.leftlist= t("activerecord.attributes.build_list.is_circle")
|
||||||
|
.rightlist= t("layout.#{@build_list.is_circle?}_")
|
||||||
|
.both
|
||||||
|
|
||||||
|
- if @build_list.advisory.present?
|
||||||
|
.leftlist= t("layout.build_lists.attached_advisory")
|
||||||
|
.rightlist= link_to @build_list.advisory.advisory_id, advisory_path(@build_list.advisory)
|
||||||
|
.both
|
||||||
|
- if !@build_list.in_work? && @build_list.started_at
|
||||||
|
%br
|
||||||
|
.leftlist
|
||||||
|
.rightlist= @build_list.human_duration
|
||||||
|
.both
|
||||||
|
- if @build_list.in_work?
|
||||||
|
%br
|
||||||
|
.leftlist
|
||||||
|
.rightlist
|
||||||
|
= "#{@build_list.human_current_duration} / #{@build_list.project.human_average_build_time}"
|
||||||
|
.both
|
||||||
|
|
||||||
|
- if @build_list.can_publish? and @build_list.save_to_platform.released and @build_list.advisory.nil?
|
||||||
|
.leftlist= label_tag :create_advisory, t("layout.build_lists.create_advisory")
|
||||||
|
.rightlist= check_box_tag :create_advisory, 1, false
|
||||||
|
.both
|
||||||
|
= f.fields_for @build_list.build_advisory do |f|
|
||||||
|
= render :partial => 'advisories/form', :locals => {:f => f}
|
||||||
|
|
||||||
|
= submit_tag t("layout.publish"), :confirm => t("layout.confirm"), :name => 'publish' if @build_list.can_publish? and can?(:publish, @build_list)
|
||||||
|
= submit_tag t("layout.reject_publish"), :confirm => t("layout.confirm"), :name => 'reject_publish' if @build_list.can_reject_publish? and can?(:reject_publish, @build_list)
|
||||||
|
|
||||||
.hr
|
.hr
|
||||||
%h3= t("layout.build_lists.items_header")
|
%h3= t("layout.build_lists.items_header")
|
||||||
|
@ -86,6 +102,25 @@
|
||||||
%td= item.human_status
|
%td= item.human_status
|
||||||
.both
|
.both
|
||||||
|
|
||||||
|
- if @build_list.packages.present?
|
||||||
|
.hr
|
||||||
|
%h3= t("layout.build_lists.packages_header")
|
||||||
|
%table.tablesorter.width565{:cellpadding => "0", :cellspacing => "0"}
|
||||||
|
%thead
|
||||||
|
%tr
|
||||||
|
%th= t("activerecord.attributes.build_list/package.fullname")
|
||||||
|
%th= t("activerecord.attributes.build_list/package.name")
|
||||||
|
%th= t("activerecord.attributes.build_list/package.version")
|
||||||
|
%th= t("activerecord.attributes.build_list/package.release")
|
||||||
|
%tbody
|
||||||
|
- @build_list.packages.each do |package|
|
||||||
|
%tr
|
||||||
|
%td= package.fullname
|
||||||
|
%td= package.name
|
||||||
|
%td= package.version
|
||||||
|
%td= package.release
|
||||||
|
.both
|
||||||
|
|
||||||
:javascript
|
:javascript
|
||||||
$('article .all').addClass('bigpadding');
|
$('article .all').addClass('bigpadding');
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
# -*- encoding : utf-8 -*-
|
# -*- encoding : utf-8 -*-
|
||||||
$:.unshift File.expand_path('.')
|
require 'cape'
|
||||||
$:.unshift(File.expand_path('./lib', ENV['rvm_path']))
|
require 'capistrano_colors'
|
||||||
set :rvm_type, :user
|
|
||||||
|
|
||||||
set :default_environment, {
|
set :default_environment, {
|
||||||
'LANG' => 'en_US.UTF-8'
|
'LANG' => 'en_US.UTF-8'
|
||||||
|
@ -34,10 +33,10 @@ set :scm, :git
|
||||||
set :repository, "git@github.com:warpc/rosa-build.git"
|
set :repository, "git@github.com:warpc/rosa-build.git"
|
||||||
set :deploy_via, :remote_cache
|
set :deploy_via, :remote_cache
|
||||||
|
|
||||||
require 'lib/recipes/nginx'
|
require './lib/recipes/nginx'
|
||||||
require 'lib/recipes/unicorn'
|
require './lib/recipes/unicorn'
|
||||||
require 'lib/recipes/bluepill'
|
require './lib/recipes/bluepill'
|
||||||
require 'lib/recipes/delayed_job'
|
require './lib/recipes/delayed_job'
|
||||||
|
|
||||||
namespace :deploy do
|
namespace :deploy do
|
||||||
task :stub_xml_rpc do
|
task :stub_xml_rpc do
|
||||||
|
@ -92,7 +91,6 @@ after "deploy:restart", "delayed_job:restart"
|
||||||
|
|
||||||
after "deploy:restart", "deploy:cleanup"
|
after "deploy:restart", "deploy:cleanup"
|
||||||
|
|
||||||
require 'cape'
|
|
||||||
namespace :rake_tasks do
|
namespace :rake_tasks do
|
||||||
Cape do
|
Cape do
|
||||||
mirror_rake_tasks 'db:seeds'
|
mirror_rake_tasks 'db:seeds'
|
||||||
|
|
|
@ -62,7 +62,7 @@ Rosa::Application.configure do
|
||||||
config.assets.digest = true
|
config.assets.digest = true
|
||||||
|
|
||||||
# Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added)
|
# Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added)
|
||||||
config.assets.precompile += %w(login.css login.js reg_session.css)
|
config.assets.precompile += %w(login.css login.js reg_session.css tour.css tour.js)
|
||||||
end
|
end
|
||||||
|
|
||||||
# require 'stub_xml_rpc'
|
# require 'stub_xml_rpc'
|
||||||
|
|
|
@ -4,6 +4,8 @@ en:
|
||||||
turned_on: on
|
turned_on: on
|
||||||
turned_off: off
|
turned_off: off
|
||||||
|
|
||||||
|
list: List
|
||||||
|
|
||||||
year: year
|
year: year
|
||||||
|
|
||||||
enter_commit_message: Commit message
|
enter_commit_message: Commit message
|
||||||
|
|
|
@ -4,6 +4,8 @@ ru:
|
||||||
turned_on: включены
|
turned_on: включены
|
||||||
turned_off: выключены
|
turned_off: выключены
|
||||||
|
|
||||||
|
list: Список
|
||||||
|
|
||||||
year: год
|
year: год
|
||||||
|
|
||||||
enter_commit_message: Сопровождающее сообщение
|
enter_commit_message: Сопровождающее сообщение
|
||||||
|
|
|
@ -8,6 +8,7 @@ en:
|
||||||
projects: Projects
|
projects: Projects
|
||||||
build_lists: Task monitoring
|
build_lists: Task monitoring
|
||||||
groups: Groups
|
groups: Groups
|
||||||
|
advisories: Advisories
|
||||||
bottom_menu:
|
bottom_menu:
|
||||||
copyright: ROSA Lab © 2012
|
copyright: ROSA Lab © 2012
|
||||||
about: About the company
|
about: About the company
|
||||||
|
|
|
@ -8,6 +8,7 @@ ru:
|
||||||
projects: Проекты
|
projects: Проекты
|
||||||
build_lists: Мониторинг задач
|
build_lists: Мониторинг задач
|
||||||
groups: Группы
|
groups: Группы
|
||||||
|
advisories: Бюллетени
|
||||||
bottom_menu:
|
bottom_menu:
|
||||||
copyright: ROSA Лаб. © 2012
|
copyright: ROSA Лаб. © 2012
|
||||||
about: О компании
|
about: О компании
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
en:
|
||||||
|
layout:
|
||||||
|
advisories:
|
||||||
|
list_header: Advisories
|
||||||
|
form_header: New advisory
|
||||||
|
project_name: Project
|
||||||
|
affected_versions: Affected versions
|
||||||
|
ref_comment: Add links one by row
|
||||||
|
|
||||||
|
flash:
|
||||||
|
advisories:
|
||||||
|
|
||||||
|
activerecord:
|
||||||
|
models:
|
||||||
|
advisory: Advisory
|
||||||
|
|
||||||
|
attributes:
|
||||||
|
advisory:
|
||||||
|
created_at: Creation date
|
||||||
|
advisory_id: Identifier
|
||||||
|
description: Description
|
||||||
|
references: References
|
|
@ -0,0 +1,22 @@
|
||||||
|
ru:
|
||||||
|
layout:
|
||||||
|
advisories:
|
||||||
|
list_header: Бюллетени
|
||||||
|
form_header: Новый бюллетень
|
||||||
|
project_name: Проект
|
||||||
|
affected_versions: Применен в версиях
|
||||||
|
ref_comment: Вставляйте ссылки по одной на строку
|
||||||
|
|
||||||
|
flash:
|
||||||
|
advisories:
|
||||||
|
|
||||||
|
activerecord:
|
||||||
|
models:
|
||||||
|
advisory: Бюллетень
|
||||||
|
|
||||||
|
attributes:
|
||||||
|
advisory:
|
||||||
|
created_at: Дата создания
|
||||||
|
advisory_id: Идентификатор
|
||||||
|
description: Описание проблемы
|
||||||
|
references: Ссылки
|
|
@ -18,10 +18,8 @@ en:
|
||||||
additional_repos: Additional repositories
|
additional_repos: Additional repositories
|
||||||
include_repos: Included repositories
|
include_repos: Included repositories
|
||||||
created_at: Created on
|
created_at: Created on
|
||||||
pl: Repository for package storage
|
save_to_platform: Repository for package storage
|
||||||
pl_id: Repository for package storage
|
build_for_platform: Platform
|
||||||
bpl: Platform
|
|
||||||
bpl_id: Platform
|
|
||||||
update_type: Update type
|
update_type: Update type
|
||||||
build_requires: Build with all the required packages
|
build_requires: Build with all the required packages
|
||||||
auto_publish: Automated publising
|
auto_publish: Automated publising
|
||||||
|
@ -38,6 +36,12 @@ en:
|
||||||
version: Version
|
version: Version
|
||||||
build_list: Build list
|
build_list: Build list
|
||||||
|
|
||||||
|
build_list/package:
|
||||||
|
name: Name
|
||||||
|
fullname: Fullname
|
||||||
|
release: Release
|
||||||
|
version: Version
|
||||||
|
|
||||||
layout:
|
layout:
|
||||||
build_lists:
|
build_lists:
|
||||||
filter_header: Filter
|
filter_header: Filter
|
||||||
|
@ -50,6 +54,7 @@ en:
|
||||||
project_name_search: Search by project name
|
project_name_search: Search by project name
|
||||||
bs_id_not_set: Id has not been configured yet
|
bs_id_not_set: Id has not been configured yet
|
||||||
items_header: Build items
|
items_header: Build items
|
||||||
|
packages_header: Container data
|
||||||
no_items_data: No data
|
no_items_data: No data
|
||||||
show: Show
|
show: Show
|
||||||
cancel_success: 'Build canceled'
|
cancel_success: 'Build canceled'
|
||||||
|
@ -62,9 +67,13 @@ en:
|
||||||
action: Action
|
action: Action
|
||||||
new_header: New build
|
new_header: New build
|
||||||
main_data: Main data
|
main_data: Main data
|
||||||
|
|
||||||
human_current_duration: Build currently takes %{hours} h. %{minutes} min.
|
human_current_duration: Build currently takes %{hours} h. %{minutes} min.
|
||||||
human_duration: Builded in %{hours} h. %{minutes} min.
|
human_duration: Builded in %{hours} h. %{minutes} min.
|
||||||
|
|
||||||
|
attached_advisory: Attached advisory
|
||||||
|
create_advisory: Create new advisory
|
||||||
|
|
||||||
ownership:
|
ownership:
|
||||||
header: Build list ownership
|
header: Build list ownership
|
||||||
owned: My
|
owned: My
|
||||||
|
@ -107,8 +116,8 @@ en:
|
||||||
|
|
||||||
flash:
|
flash:
|
||||||
build_list:
|
build_list:
|
||||||
saved: Build list for project version '%{project_version}', platform '%{bpl}' and architecture '%{arch}' has been created successfully
|
saved: Build list for project version '%{project_version}', platform '%{build_for_platform}' and architecture '%{arch}' has been created successfully
|
||||||
save_error: Build list for project version '%{project_version}', platform '%{bpl}' and architecture '%{arch}' could not been created
|
save_error: Build list for project version '%{project_version}', platform '%{build_for_platform}' and architecture '%{arch}' could not been created
|
||||||
no_project_version_selected: Select any version of the project
|
no_project_version_selected: Select any version of the project
|
||||||
no_project_version_found: Project version '%{project_version}' not found
|
no_project_version_found: Project version '%{project_version}' not found
|
||||||
no_arch_or_platform_selected: At least one of architecture of platform must selected
|
no_arch_or_platform_selected: At least one of architecture of platform must selected
|
||||||
|
|
|
@ -18,10 +18,8 @@ ru:
|
||||||
additional_repos: Дополнительные репозитории
|
additional_repos: Дополнительные репозитории
|
||||||
include_repos: Подключаемые репозитории
|
include_repos: Подключаемые репозитории
|
||||||
created_at: Создан
|
created_at: Создан
|
||||||
pl: Репозиторий для сохранения пакетов
|
save_to_platform: Репозиторий для сохранения пакетов
|
||||||
pl_id: Репозиторий для сохранения пакетов
|
build_for_platform: Платформа
|
||||||
bpl: Платформа
|
|
||||||
bpl_id: Платформа
|
|
||||||
update_type: Критичность обновления
|
update_type: Критичность обновления
|
||||||
build_requires: Пересборка с зависимостями
|
build_requires: Пересборка с зависимостями
|
||||||
auto_publish: Автоматическая публикация
|
auto_publish: Автоматическая публикация
|
||||||
|
@ -37,6 +35,12 @@ ru:
|
||||||
version: Версия
|
version: Версия
|
||||||
build_list: Сборочный лист
|
build_list: Сборочный лист
|
||||||
|
|
||||||
|
build_list/package:
|
||||||
|
name: Название
|
||||||
|
fullname: Полное имя
|
||||||
|
release: Релиз
|
||||||
|
version: Версия
|
||||||
|
|
||||||
layout:
|
layout:
|
||||||
build_lists:
|
build_lists:
|
||||||
filter_header: Фильтр
|
filter_header: Фильтр
|
||||||
|
@ -49,6 +53,7 @@ ru:
|
||||||
project_name_search: Поиск по названию проекта
|
project_name_search: Поиск по названию проекта
|
||||||
bs_id_not_set: Id еще не присвоен
|
bs_id_not_set: Id еще не присвоен
|
||||||
items_header: Элементы сборки
|
items_header: Элементы сборки
|
||||||
|
packages_header: Данные о контейнере
|
||||||
no_items_data: Данных нет
|
no_items_data: Данных нет
|
||||||
show: Просмотр
|
show: Просмотр
|
||||||
cancel_success: 'Сборка отменена.'
|
cancel_success: 'Сборка отменена.'
|
||||||
|
@ -65,6 +70,9 @@ ru:
|
||||||
human_current_duration: Сборка длится уже %{hours} ч. %{minutes} мин.
|
human_current_duration: Сборка длится уже %{hours} ч. %{minutes} мин.
|
||||||
human_duration: Собрано за %{hours} ч. %{minutes} мин.
|
human_duration: Собрано за %{hours} ч. %{minutes} мин.
|
||||||
|
|
||||||
|
attached_advisory: Связанный бюллетень
|
||||||
|
create_advisory: Создать новый бюллетень
|
||||||
|
|
||||||
ownership:
|
ownership:
|
||||||
header: Принадлежность заданий
|
header: Принадлежность заданий
|
||||||
owned: Мне
|
owned: Мне
|
||||||
|
@ -107,8 +115,8 @@ ru:
|
||||||
|
|
||||||
flash:
|
flash:
|
||||||
build_list:
|
build_list:
|
||||||
saved: Билд лист для версии '%{project_version}', платформы '%{bpl}' и архитектуры '%{arch}' создан успешно
|
saved: Билд лист для версии '%{project_version}', платформы '%{build_for_platform}' и архитектуры '%{arch}' создан успешно
|
||||||
save_error: Не удалось сохранить билд лист для версии '%{project_version}', платформы '%{bpl}' и архитектуры '%{arch}'
|
save_error: Не удалось сохранить билд лист для версии '%{project_version}', платформы '%{build_for_platform}' и архитектуры '%{arch}'
|
||||||
no_project_version_selected: Выберите какую-нибудь версию
|
no_project_version_selected: Выберите какую-нибудь версию
|
||||||
no_project_version_found: Выбранная версия '%{project_version}' не найдена
|
no_project_version_found: Выбранная версия '%{project_version}' не найдена
|
||||||
no_arch_or_platform_selected: Выберите хотя бы одну архитектуру и платформу
|
no_arch_or_platform_selected: Выберите хотя бы одну архитектуру и платформу
|
||||||
|
|
|
@ -88,3 +88,6 @@ en:
|
||||||
group: Group
|
group: Group
|
||||||
default_branch: Default branch
|
default_branch: Default branch
|
||||||
is_rpm: Project is a packet
|
is_rpm: Project is a packet
|
||||||
|
errors:
|
||||||
|
project:
|
||||||
|
uname: The name can only use lower case Latin letters (a-z), numbers (0-9) and underscore (_)
|
||||||
|
|
|
@ -88,3 +88,6 @@ ru:
|
||||||
group: Группа
|
group: Группа
|
||||||
default_branch: Ветка по умолчанию
|
default_branch: Ветка по умолчанию
|
||||||
is_rpm: Проект является пакетом
|
is_rpm: Проект является пакетом
|
||||||
|
errors:
|
||||||
|
project:
|
||||||
|
uname: В имени можно использовать только строчные символы латинского алфавита (a-z), цифры (0-9) и символ нижнего подчеркивания (_)
|
||||||
|
|
|
@ -3,26 +3,29 @@ en:
|
||||||
'Editing'
|
'Editing'
|
||||||
at: at
|
at: at
|
||||||
users:
|
users:
|
||||||
profile:
|
settings:
|
||||||
title: 'Your Profile'
|
profile:
|
||||||
build_lists:
|
title: 'Your Profile'
|
||||||
index:
|
projects:
|
||||||
title: 'Projects Monitoring'
|
build_lists:
|
||||||
product_build_lists:
|
|
||||||
index:
|
|
||||||
title: 'Products Monitoring'
|
|
||||||
git:
|
|
||||||
commits:
|
|
||||||
index:
|
index:
|
||||||
title: 'Commit History'
|
title: 'Projects Monitoring'
|
||||||
issues:
|
git:
|
||||||
index:
|
commits:
|
||||||
title: 'Tracker'
|
index:
|
||||||
wiki:
|
title: 'Commit History'
|
||||||
compare:
|
issues:
|
||||||
title: 'Compare Revisions'
|
index:
|
||||||
searching:
|
title: 'Tracker'
|
||||||
title: 'Search in Wiki'
|
wiki:
|
||||||
|
compare:
|
||||||
|
title: 'Compare Revisions'
|
||||||
|
searching:
|
||||||
|
title: 'Search in Wiki'
|
||||||
|
platforms:
|
||||||
|
product_build_lists:
|
||||||
|
index:
|
||||||
|
title: 'Products Monitoring'
|
||||||
pull_requests:
|
pull_requests:
|
||||||
index:
|
index:
|
||||||
title: 'Pull Requests'
|
title: 'Pull Requests'
|
||||||
|
|
|
@ -3,26 +3,29 @@ ru:
|
||||||
'Редактирование'
|
'Редактирование'
|
||||||
at: at
|
at: at
|
||||||
users:
|
users:
|
||||||
profile:
|
settings:
|
||||||
title: 'Ваш профиль'
|
profile:
|
||||||
build_lists:
|
title: 'Ваш профиль'
|
||||||
index:
|
projects:
|
||||||
title: 'Мониторинг проектов'
|
build_lists:
|
||||||
product_build_lists:
|
|
||||||
index:
|
|
||||||
title: 'Мониторинг продуктов'
|
|
||||||
git:
|
|
||||||
commits:
|
|
||||||
index:
|
index:
|
||||||
title: 'История коммитов'
|
title: 'Мониторинг проектов'
|
||||||
issues:
|
git:
|
||||||
index:
|
commits:
|
||||||
title: 'Трекер'
|
index:
|
||||||
wiki:
|
title: 'История коммитов'
|
||||||
compare:
|
issues:
|
||||||
title: 'Сравнение версий'
|
index:
|
||||||
searching:
|
title: 'Трекер'
|
||||||
title: 'Поиск в вики'
|
wiki:
|
||||||
|
compare:
|
||||||
|
title: 'Сравнение версий'
|
||||||
|
searching:
|
||||||
|
title: 'Поиск в вики'
|
||||||
|
platforms:
|
||||||
|
product_build_lists:
|
||||||
|
index:
|
||||||
|
title: 'Мониторинг продуктов'
|
||||||
pull_requests:
|
pull_requests:
|
||||||
index:
|
index:
|
||||||
title: 'Запросы на слияние'
|
title: 'Запросы на слияние'
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
en:
|
||||||
|
tour:
|
||||||
|
read_more: more...
|
||||||
|
projects: Project Management
|
||||||
|
sources: Source Code
|
||||||
|
builds: Package Building
|
||||||
|
|
||||||
|
repo: Personal repository
|
||||||
|
monitoring: Task monitoring
|
||||||
|
source: Source code online
|
||||||
|
history: File history
|
||||||
|
annotation: File blame
|
||||||
|
edit: Online editor
|
||||||
|
control: Project Management
|
||||||
|
git: Git Wiki
|
||||||
|
tracker: Lightweight task tracker
|
||||||
|
|
||||||
|
projects_header: Every git repository in ABF is accompanied by tools necessary to manage a project, be it a public project or a private one.
|
||||||
|
sources_header: ABF is full-functional git-hosting with convenient Web interface.
|
||||||
|
builds_header: |
|
||||||
|
ABF is not just a hosting for source code, but a system to build and publish packages.
|
||||||
|
Build your projects for large variety of distributions and hardware platforms in your personal repository!
|
||||||
|
|
||||||
|
repo_description: |
|
||||||
|
Personal repository provides you with an easy way to distribute your software among great number of Linux users by means of standard ways of software delivery.
|
||||||
|
ABF will take care of package dependencies from both main repositories or extra and personal ones. Published a new package version?
|
||||||
|
Users will be automatically notified about available update.
|
||||||
|
builds_description: |
|
||||||
|
ABF provides you with power to build projects for large variety of distributions and hardware platforms. No additional efforts from your side!
|
||||||
|
monitoring_description: |
|
||||||
|
It is easy to get lost in large amount of tasks, but smart monitoring will focus your attention on those tasks that really matter for you.
|
||||||
|
source_description: |
|
||||||
|
We have focused on making access to the source code easy and transparent. Every file pushed to git repository will instantly become available for online access,
|
||||||
|
so you can share it with other developers even if they don't use Git. Home page of every project contains list of project files,
|
||||||
|
as well as information about recent changes. You can immediately see the most important part of your project: the code.
|
||||||
|
history_description: |
|
||||||
|
Every file in git repository has history of modifications which can be easily looked through using ABF to see who and when modified the file
|
||||||
|
and which changes were introduced by particular commits.
|
||||||
|
annotation_description: 'Looking for the author of a particular code fragment? Just open the file blame to see who modified that fragment for the last time and in which commit.'
|
||||||
|
edit_description: Need to quickly edit some file? Want to fix syntax error from your mobile phone? No problem. We provide you with a simple editor for every file in git repository.
|
||||||
|
control_description: |
|
||||||
|
There are 3 possible levels of privileges for project members: read-only, read/write, and administration level. A project member can designate a real user
|
||||||
|
or a group of developers. Both projects and groups may have unlimited number of members (every of which can be in turn a user or a group).
|
||||||
|
git_description: |
|
||||||
|
Project wiki is based on Gollum — open wiki engine developed by GitHub. In fact, this is a full-function git repository which can be cloned, used offline,
|
||||||
|
modified and pushed back to server, as if it were a usual source code. Convenient web editor allows to modify wiki online.
|
||||||
|
Now information about your project will be never lost and will be always available for modifications in any editor!
|
||||||
|
<br/><br/>Note: for private projects, wiki is accessible by project team only. Wiki of a public project can be read by everyone.
|
||||||
|
tracker_description: |
|
||||||
|
Every project may use a lightweight and simple task tracker. Labels and assignments will allow not to get lost in tasks,
|
||||||
|
while convenient interface will allow to concentrate on a real work, not filling huge forms.
|
|
@ -0,0 +1,61 @@
|
||||||
|
ru:
|
||||||
|
tour:
|
||||||
|
read_more: Читать далее...
|
||||||
|
projects: Управление проектами
|
||||||
|
sources: Исходный код
|
||||||
|
builds: Сборка пакетов
|
||||||
|
|
||||||
|
repo: Персональный репозиторий
|
||||||
|
monitoring: Мониторинг
|
||||||
|
source: Исходный код онлайн
|
||||||
|
history: История файла
|
||||||
|
annotation: Аннотация файла
|
||||||
|
edit: Редактирования онлайн
|
||||||
|
control: Управление проектами
|
||||||
|
git: Git Wiki
|
||||||
|
tracker: Легкий трекер задач
|
||||||
|
|
||||||
|
projects_header: |
|
||||||
|
Каждый git-репозиторий на ABF поставляется с инструментами, необходимыми для управления проектами,
|
||||||
|
вне зависимости от того, публичный или приватный проект.
|
||||||
|
sources_header: ABF — полноценный git-хостинг с удобным веб-интерфейсом.
|
||||||
|
builds_header: |
|
||||||
|
ABF — это не только хостинг исходного кода, но и система сборки и хостинга пакетов.
|
||||||
|
Собирайте свои проекты под множество дистрибутивов и архитектур в свой персональный репозиторий.
|
||||||
|
|
||||||
|
repo_description: |
|
||||||
|
Персональный репозиторий — быстрый и легкий способ распространить свое ПО множеству Linux пользователей
|
||||||
|
различных дистрибутивов, используя стандартный механизм доставки ПО.
|
||||||
|
ABF позаботится о зависимостях ПО из основных репозиториев и/или дополнительных персональных репозиториев.
|
||||||
|
Опубликовали новую версию? Пользователи автоматически получат оповещение о доступности обновления.
|
||||||
|
builds_description: |
|
||||||
|
ABF позволяет собрать ваши проекты под множество архитектур и дистрибутивов, используя свои вычислительные мощности.
|
||||||
|
Никаких затрат с вашей стороны!
|
||||||
|
monitoring_description: |
|
||||||
|
В большом числе сборочных заданий легко потеряться, поэтому мониторинг сборки фокусирует ваше внимание только на том,
|
||||||
|
что действительно важно.
|
||||||
|
source_description: |
|
||||||
|
Мы сфокусировались на том, чтобы сделать исходный код доступным и прозрачным. Все, что вы выложите в git-репозиторий,
|
||||||
|
мгновенно станет доступным для просмотра в режиме онлайн, чтобы вы могли поделиться им с людьми, даже если они не
|
||||||
|
используют Git. На главной странице каждого проекта есть список файлов проекта, а также информация о последнем изменении.
|
||||||
|
Вы можете сразу увидеть самое важное в вашем проекте: код.
|
||||||
|
history_description: 'Каждый файл в git-репозитории имеет историю, которую вы легко можете посмотреть: кто, когда и что в нем поменял.'
|
||||||
|
annotation_description: |
|
||||||
|
Ищете автора фрагмента кода? Откройте аннотацию файла (Blame), чтобы увидеть:
|
||||||
|
кто и в каком коммите последний изменял данный фрагмент.
|
||||||
|
edit_description: |
|
||||||
|
Вам нужно быстро внести изменение в файл? Исправить орфографические ошибки c вашего мобильного телефона?
|
||||||
|
Мы предлагаем простой редактор для каждого файла в git-репозитории.
|
||||||
|
control: |
|
||||||
|
Существует 3 возможных роли для участника проекта: только чтение, чтение/запись и административный уровень.
|
||||||
|
Участником проекта может выступать как пользователь, так и группа. Проект, как и группа, может иметь неограниченное
|
||||||
|
число участников (пользователей, групп или всех вместе).
|
||||||
|
git: |
|
||||||
|
Вики проекта создана с помощью Gollum — открытого вики-движка, созданного GitHub. В основе своей это полноценный
|
||||||
|
git-репозиторий, который можно клонировать, использовать в режиме офлайн, изменять и загружать изменения обратно на
|
||||||
|
сервер, как в случае с обычным кодом. Удобный веб-редактор позволит работать с ней в онлайн. Теперь данные о проекте не
|
||||||
|
пропадут и доступны для редактирования в любимом редакторе!
|
||||||
|
<br/><br/>Примечание: для приватного проекта вики доступна только его участникам. Для публичного — всем для чтения.
|
||||||
|
tracker: |
|
||||||
|
Каждый проект также может использовать легкий и простой трекер задач. Метки и назначения позволят не потеряться среди
|
||||||
|
задач, а понятный интерфейс позволит сконцентрироваться на работе, а не на заполнении огромных формуляров.
|
151
config/routes.rb
|
@ -9,6 +9,7 @@ Rosa::Application.routes.draw do
|
||||||
|
|
||||||
get '/forbidden' => 'pages#forbidden', :as => 'forbidden'
|
get '/forbidden' => 'pages#forbidden', :as => 'forbidden'
|
||||||
get '/terms-of-service' => 'pages#tos', :as => 'tos'
|
get '/terms-of-service' => 'pages#tos', :as => 'tos'
|
||||||
|
get '/tour/:id' => 'pages#tour_inside', :as => 'tour_inside', :id => /projects|sources|builds/
|
||||||
|
|
||||||
get '/activity_feeds.:format' => 'activity_feeds#index', :as => 'atom_activity_feeds', :format => /atom/
|
get '/activity_feeds.:format' => 'activity_feeds#index', :as => 'atom_activity_feeds', :format => /atom/
|
||||||
if APP_CONFIG['anonymous_access']
|
if APP_CONFIG['anonymous_access']
|
||||||
|
@ -20,6 +21,22 @@ Rosa::Application.routes.draw do
|
||||||
root :to => 'activity_feeds#index'
|
root :to => 'activity_feeds#index'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
namespace :admin do
|
||||||
|
resources :users do
|
||||||
|
get :list, :on => :collection
|
||||||
|
end
|
||||||
|
resources :register_requests, :only => [:index] do
|
||||||
|
put :update, :on => :collection
|
||||||
|
member do
|
||||||
|
get :approve
|
||||||
|
get :reject
|
||||||
|
end
|
||||||
|
end
|
||||||
|
resources :event_logs, :only => :index
|
||||||
|
end
|
||||||
|
|
||||||
|
resources :advisories, :only => [:index, :show]
|
||||||
|
|
||||||
scope :module => 'platforms' do
|
scope :module => 'platforms' do
|
||||||
resources :platforms do
|
resources :platforms do
|
||||||
resources :private_users, :except => [:show, :destroy, :update]
|
resources :private_users, :except => [:show, :destroy, :update]
|
||||||
|
@ -49,20 +66,6 @@ Rosa::Application.routes.draw do
|
||||||
resources :product_build_lists, :only => [:index]
|
resources :product_build_lists, :only => [:index]
|
||||||
end
|
end
|
||||||
|
|
||||||
namespace :admin do
|
|
||||||
resources :users do
|
|
||||||
get :list, :on => :collection
|
|
||||||
end
|
|
||||||
resources :register_requests, :only => [:index] do
|
|
||||||
put :update, :on => :collection
|
|
||||||
member do
|
|
||||||
get :approve
|
|
||||||
get :reject
|
|
||||||
end
|
|
||||||
end
|
|
||||||
resources :event_logs, :only => :index
|
|
||||||
end
|
|
||||||
|
|
||||||
scope :module => 'users' do
|
scope :module => 'users' do
|
||||||
resources :settings, :only => [] do
|
resources :settings, :only => [] do
|
||||||
collection do
|
collection do
|
||||||
|
@ -82,6 +85,8 @@ Rosa::Application.routes.draw do
|
||||||
end
|
end
|
||||||
|
|
||||||
scope :module => 'groups' do
|
scope :module => 'groups' do
|
||||||
|
get '/groups/new' => 'profile#new' # need to force next route exclude :id => 'new'
|
||||||
|
get '/groups/:id' => redirect("/%{id}"), :as => :profile_group # override default group show route
|
||||||
resources :groups, :controller => 'profile' do
|
resources :groups, :controller => 'profile' do
|
||||||
get :autocomplete_group_uname, :on => :collection
|
get :autocomplete_group_uname, :on => :collection
|
||||||
delete :remove_user, :on => :member
|
delete :remove_user, :on => :member
|
||||||
|
@ -105,79 +110,70 @@ Rosa::Application.routes.draw do
|
||||||
match 'build_lists/new_bbdt', :to => "build_lists#new_bbdt"
|
match 'build_lists/new_bbdt', :to => "build_lists#new_bbdt"
|
||||||
match 'product_status', :to => 'product_build_lists#status_build'
|
match 'product_status', :to => 'product_build_lists#status_build'
|
||||||
|
|
||||||
resources :build_lists, :only => [:index, :show] do
|
resources :build_lists, :only => [:index, :show, :update] do
|
||||||
member do
|
member do
|
||||||
put :cancel
|
put :cancel
|
||||||
put :publish
|
|
||||||
put :reject_publish
|
|
||||||
end
|
end
|
||||||
collection { post :search }
|
collection { post :search }
|
||||||
end
|
end
|
||||||
|
|
||||||
resources :projects, :only => [:index, :new, :create]
|
resources :projects, :only => [:index, :new, :create]
|
||||||
end
|
|
||||||
scope ':owner_name' do # Owner
|
|
||||||
constraints OwnerConstraint.new(User) do
|
|
||||||
get '/' => 'users/profile#show', :as => :user
|
|
||||||
end
|
|
||||||
constraints OwnerConstraint.new(Group, true) do
|
|
||||||
get '/' => 'groups/profile#show', :as => :group_profile
|
|
||||||
end
|
|
||||||
scope ':project_name', :as => 'project', :module => 'projects' do
|
|
||||||
resources :wiki do
|
|
||||||
collection do
|
|
||||||
match '_history' => 'wiki#wiki_history', :as => :history, :via => :get
|
|
||||||
match '_access' => 'wiki#git', :as => :git, :via => :get
|
|
||||||
match '_revert/:sha1/:sha2' => 'wiki#revert_wiki', :as => :revert, :via => [:get, :post]
|
|
||||||
match '_compare' => 'wiki#compare_wiki', :as => :compare, :via => :post
|
|
||||||
#match '_compare/:versions' => 'wiki#compare_wiki', :versions => /.*/, :as => :compare_versions, :via => :get
|
|
||||||
match '_compare/:versions' => 'wiki#compare_wiki', :versions => /([a-f0-9\^]{6,40})(\.\.\.[a-f0-9\^]{6,40})/, :as => :compare_versions, :via => :get
|
|
||||||
post :preview
|
|
||||||
get :search
|
|
||||||
get :pages
|
|
||||||
end
|
|
||||||
member do
|
|
||||||
get :history
|
|
||||||
get :edit
|
|
||||||
match 'revert/:sha1/:sha2' => 'wiki#revert', :as => :revert_page, :via => [:get, :post]
|
|
||||||
match ':ref' => 'wiki#show', :as => :versioned, :via => :get
|
|
||||||
|
|
||||||
post :compare
|
scope ':owner_name/:project_name', :constraints => {:project_name => Project::NAME_REGEXP} do # project
|
||||||
#match 'compare/*versions' => 'wiki#compare', :as => :compare_versions, :via => :get
|
scope :as => 'project' do
|
||||||
match 'compare/:versions' => 'wiki#compare', :versions => /([a-f0-9\^]{6,40})(\.\.\.[a-f0-9\^]{6,40})/, :as => :compare_versions, :via => :get
|
resources :wiki do
|
||||||
|
collection do
|
||||||
|
match '_history' => 'wiki#wiki_history', :as => :history, :via => :get
|
||||||
|
match '_access' => 'wiki#git', :as => :git, :via => :get
|
||||||
|
match '_revert/:sha1/:sha2' => 'wiki#revert_wiki', :as => :revert, :via => [:get, :post]
|
||||||
|
match '_compare' => 'wiki#compare_wiki', :as => :compare, :via => :post
|
||||||
|
#match '_compare/:versions' => 'wiki#compare_wiki', :versions => /.*/, :as => :compare_versions, :via => :get
|
||||||
|
match '_compare/:versions' => 'wiki#compare_wiki', :versions => /([a-f0-9\^]{6,40})(\.\.\.[a-f0-9\^]{6,40})/, :as => :compare_versions, :via => :get
|
||||||
|
post :preview
|
||||||
|
get :search
|
||||||
|
get :pages
|
||||||
|
end
|
||||||
|
member do
|
||||||
|
get :history
|
||||||
|
get :edit
|
||||||
|
match 'revert/:sha1/:sha2' => 'wiki#revert', :as => :revert_page, :via => [:get, :post]
|
||||||
|
match ':ref' => 'wiki#show', :as => :versioned, :via => :get
|
||||||
|
|
||||||
|
post :compare
|
||||||
|
#match 'compare/*versions' => 'wiki#compare', :as => :compare_versions, :via => :get
|
||||||
|
match 'compare/:versions' => 'wiki#compare', :versions => /([a-f0-9\^]{6,40})(\.\.\.[a-f0-9\^]{6,40})/, :as => :compare_versions, :via => :get
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
resources :issues, :except => :edit do
|
||||||
resources :issues, :except => :edit do
|
resources :comments, :only => [:edit, :create, :update, :destroy]
|
||||||
resources :comments, :only => [:edit, :create, :update, :destroy]
|
resources :subscribes, :only => [:create, :destroy]
|
||||||
resources :subscribes, :only => [:create, :destroy]
|
collection do
|
||||||
collection do
|
post :create_label
|
||||||
post :create_label
|
get :search_collaborators
|
||||||
get :search_collaborators
|
end
|
||||||
end
|
end
|
||||||
end
|
post "/labels/:label_id" => "issues#destroy_label", :as => :issues_delete_label
|
||||||
post "/labels/:label_id" => "issues#destroy_label", :as => :issues_delete_label
|
post "/labels/:label_id/update" => "issues#update_label", :as => :issues_update_label
|
||||||
post "/labels/:label_id/update" => "issues#update_label", :as => :issues_update_label
|
resources :build_lists, :only => [:index, :new, :create] do
|
||||||
resources :build_lists, :only => [:index, :new, :create] do
|
collection { post :search }
|
||||||
collection { post :search }
|
|
||||||
end
|
|
||||||
resources :collaborators do
|
|
||||||
get :find, :on => :collection
|
|
||||||
end
|
|
||||||
resources :pull_requests, :except => [:destroy, :new] do
|
|
||||||
collection do
|
|
||||||
post '/new' => 'pull_requests#new'
|
|
||||||
get :autocomplete_base_project_name
|
|
||||||
get :autocomplete_head_project_name
|
|
||||||
get :autocomplete_base_ref
|
|
||||||
get :autocomplete_head_ref
|
|
||||||
end
|
end
|
||||||
member do
|
resources :collaborators do
|
||||||
put :merge, :as => 'merge'
|
get :find, :on => :collection
|
||||||
|
end
|
||||||
|
resources :pull_requests, :except => [:destroy, :new] do
|
||||||
|
collection do
|
||||||
|
post '/new' => 'pull_requests#new'
|
||||||
|
get :autocomplete_base_project_name
|
||||||
|
get :autocomplete_head_project_name
|
||||||
|
get :autocomplete_base_ref
|
||||||
|
get :autocomplete_head_ref
|
||||||
|
end
|
||||||
|
member do
|
||||||
|
put :merge, :as => 'merge'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
|
||||||
scope ':project_name', :module => 'projects' do
|
|
||||||
# Resource
|
# Resource
|
||||||
get '/edit' => 'projects#edit', :as => :edit_project
|
get '/edit' => 'projects#edit', :as => :edit_project
|
||||||
put '/' => 'projects#update'
|
put '/' => 'projects#update'
|
||||||
|
@ -214,4 +210,13 @@ Rosa::Application.routes.draw do
|
||||||
get '/archive/:format/tree/:treeish' => "git/trees#archive", :defaults => {:treeish => :master}, :as => :archive, :format => /zip|tar/
|
get '/archive/:format/tree/:treeish' => "git/trees#archive", :defaults => {:treeish => :master}, :as => :archive, :format => /zip|tar/
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
scope ':uname' do # project owner profile
|
||||||
|
constraints OwnerConstraint.new(User) do
|
||||||
|
get '/' => 'users/profile#show', :as => :user
|
||||||
|
end
|
||||||
|
constraints OwnerConstraint.new(Group, true) do
|
||||||
|
get '/' => 'groups/profile#show', :as => :group
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,3 +10,7 @@
|
||||||
every 1.day, :at => '4:00 am' do
|
every 1.day, :at => '4:00 am' do
|
||||||
rake "import:sync:all", :output => 'log/sync.log'
|
rake "import:sync:all", :output => 'log/sync.log'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
every 1.day, :at => '3:50 am' do
|
||||||
|
rake "buildlist:clear:outdated", :output => 'log/build_list_clear.log'
|
||||||
|
end
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
class CreateAdvisories < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
create_table :advisories do |t|
|
||||||
|
t.string :advisory_id
|
||||||
|
t.integer :project_id
|
||||||
|
t.text :description, :default => ''
|
||||||
|
t.text :references, :default => ''
|
||||||
|
t.text :update_type, :default => ''
|
||||||
|
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
add_index :advisories, :advisory_id, :unique => true
|
||||||
|
add_index :advisories, :project_id
|
||||||
|
add_index :advisories, :update_type
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,18 @@
|
||||||
|
class CreateAdvisoriesPlatforms < ActiveRecord::Migration
|
||||||
|
def up
|
||||||
|
create_table :advisories_platforms, :id => false do |t|
|
||||||
|
t.integer :advisory_id
|
||||||
|
t.integer :platform_id
|
||||||
|
end
|
||||||
|
add_index :advisories_platforms, :advisory_id
|
||||||
|
add_index :advisories_platforms, :platform_id
|
||||||
|
add_index :advisories_platforms, [:advisory_id, :platform_id], :name => :advisory_platform_index, :unique => true
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
remove_index :advisories_platforms, :column => :advisory_id
|
||||||
|
remove_index :advisories_platforms, :column => :platform_id
|
||||||
|
remove_index :advisories_platforms, :name => :advisory_platform_index
|
||||||
|
drop_table :advisories_platforms
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,7 @@
|
||||||
|
class AddAdvisoryIdToBuildLists < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
add_column :build_lists, :advisory_id, :integer
|
||||||
|
add_index :build_lists, :advisory_id
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,15 @@
|
||||||
|
class RenamePlBplInBuildList < ActiveRecord::Migration
|
||||||
|
def up
|
||||||
|
change_table :build_lists do |t|
|
||||||
|
t.rename :pl_id, :save_to_platform_id
|
||||||
|
t.rename :bpl_id, :build_for_platform_id
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
change_table :build_lists do |t|
|
||||||
|
t.rename :save_to_platform_id, :pl_id
|
||||||
|
t.rename :build_for_platform_id, :bpl_id
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,11 @@
|
||||||
|
class AddBuildPriorityToUsers < ActiveRecord::Migration
|
||||||
|
def up
|
||||||
|
add_column :users, :build_priority, :integer, :default => 50
|
||||||
|
User.update_all :build_priority => 50
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
remove_column :users, :build_priority
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,19 @@
|
||||||
|
class CreateBuildListPackages < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
create_table :build_list_packages do |t|
|
||||||
|
t.references :build_list
|
||||||
|
t.references :project
|
||||||
|
t.references :platform
|
||||||
|
t.string :fullname
|
||||||
|
t.string :name
|
||||||
|
t.string :version
|
||||||
|
t.string :release
|
||||||
|
t.string :package_type
|
||||||
|
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
add_index :build_list_packages, :build_list_id
|
||||||
|
add_index :build_list_packages, :project_id
|
||||||
|
add_index :build_list_packages, :platform_id
|
||||||
|
end
|
||||||
|
end
|
73
db/schema.rb
|
@ -11,7 +11,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended to check this file into your version control system.
|
# It's strongly recommended to check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(:version => 20120425190938) do
|
ActiveRecord::Schema.define(:version => 20120512102707) do
|
||||||
|
|
||||||
create_table "activity_feeds", :force => true do |t|
|
create_table "activity_feeds", :force => true do |t|
|
||||||
t.integer "user_id", :null => false
|
t.integer "user_id", :null => false
|
||||||
|
@ -21,6 +21,29 @@ ActiveRecord::Schema.define(:version => 20120425190938) do
|
||||||
t.datetime "updated_at", :null => false
|
t.datetime "updated_at", :null => false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
create_table "advisories", :force => true do |t|
|
||||||
|
t.string "advisory_id"
|
||||||
|
t.integer "project_id"
|
||||||
|
t.text "description", :default => ""
|
||||||
|
t.text "references", :default => ""
|
||||||
|
t.text "update_type", :default => ""
|
||||||
|
t.datetime "created_at", :null => false
|
||||||
|
t.datetime "updated_at", :null => false
|
||||||
|
end
|
||||||
|
|
||||||
|
add_index "advisories", ["advisory_id"], :name => "index_advisories_on_advisory_id", :unique => true
|
||||||
|
add_index "advisories", ["project_id"], :name => "index_advisories_on_project_id"
|
||||||
|
add_index "advisories", ["update_type"], :name => "index_advisories_on_update_type"
|
||||||
|
|
||||||
|
create_table "advisories_platforms", :id => false, :force => true do |t|
|
||||||
|
t.integer "advisory_id"
|
||||||
|
t.integer "platform_id"
|
||||||
|
end
|
||||||
|
|
||||||
|
add_index "advisories_platforms", ["advisory_id"], :name => "index_advisories_platforms_on_advisory_id"
|
||||||
|
add_index "advisories_platforms", ["advisory_id", "platform_id"], :name => "advisory_platform_index", :unique => true
|
||||||
|
add_index "advisories_platforms", ["platform_id"], :name => "index_advisories_platforms_on_platform_id"
|
||||||
|
|
||||||
create_table "arches", :force => true do |t|
|
create_table "arches", :force => true do |t|
|
||||||
t.string "name", :null => false
|
t.string "name", :null => false
|
||||||
t.datetime "created_at", :null => false
|
t.datetime "created_at", :null => false
|
||||||
|
@ -52,6 +75,23 @@ ActiveRecord::Schema.define(:version => 20120425190938) do
|
||||||
|
|
||||||
add_index "build_list_items", ["build_list_id"], :name => "index_build_list_items_on_build_list_id"
|
add_index "build_list_items", ["build_list_id"], :name => "index_build_list_items_on_build_list_id"
|
||||||
|
|
||||||
|
create_table "build_list_packages", :force => true do |t|
|
||||||
|
t.integer "build_list_id"
|
||||||
|
t.integer "project_id"
|
||||||
|
t.integer "platform_id"
|
||||||
|
t.string "fullname"
|
||||||
|
t.string "name"
|
||||||
|
t.string "version"
|
||||||
|
t.string "release"
|
||||||
|
t.string "package_type"
|
||||||
|
t.datetime "created_at", :null => false
|
||||||
|
t.datetime "updated_at", :null => false
|
||||||
|
end
|
||||||
|
|
||||||
|
add_index "build_list_packages", ["build_list_id"], :name => "index_build_list_packages_on_build_list_id"
|
||||||
|
add_index "build_list_packages", ["platform_id"], :name => "index_build_list_packages_on_platform_id"
|
||||||
|
add_index "build_list_packages", ["project_id"], :name => "index_build_list_packages_on_project_id"
|
||||||
|
|
||||||
create_table "build_lists", :force => true do |t|
|
create_table "build_lists", :force => true do |t|
|
||||||
t.integer "bs_id"
|
t.integer "bs_id"
|
||||||
t.string "container_path"
|
t.string "container_path"
|
||||||
|
@ -60,25 +100,27 @@ ActiveRecord::Schema.define(:version => 20120425190938) do
|
||||||
t.integer "project_id"
|
t.integer "project_id"
|
||||||
t.integer "arch_id"
|
t.integer "arch_id"
|
||||||
t.datetime "notified_at"
|
t.datetime "notified_at"
|
||||||
t.datetime "created_at", :null => false
|
t.datetime "created_at", :null => false
|
||||||
t.datetime "updated_at", :null => false
|
t.datetime "updated_at", :null => false
|
||||||
t.boolean "is_circle", :default => false
|
t.boolean "is_circle", :default => false
|
||||||
t.text "additional_repos"
|
t.text "additional_repos"
|
||||||
t.string "name"
|
t.string "name"
|
||||||
t.boolean "build_requires", :default => false
|
t.boolean "build_requires", :default => false
|
||||||
t.string "update_type"
|
t.string "update_type"
|
||||||
t.integer "bpl_id"
|
t.integer "build_for_platform_id"
|
||||||
t.integer "pl_id"
|
t.integer "save_to_platform_id"
|
||||||
t.text "include_repos"
|
t.text "include_repos"
|
||||||
t.integer "user_id"
|
t.integer "user_id"
|
||||||
t.boolean "auto_publish", :default => true
|
t.boolean "auto_publish", :default => true
|
||||||
t.string "package_version"
|
t.string "package_version"
|
||||||
t.string "commit_hash"
|
t.string "commit_hash"
|
||||||
t.integer "priority", :default => 0, :null => false
|
t.integer "priority", :default => 0, :null => false
|
||||||
t.datetime "started_at"
|
t.datetime "started_at"
|
||||||
t.integer "duration"
|
t.integer "duration"
|
||||||
|
t.integer "advisory_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
add_index "build_lists", ["advisory_id"], :name => "index_build_lists_on_advisory_id"
|
||||||
add_index "build_lists", ["arch_id"], :name => "index_build_lists_on_arch_id"
|
add_index "build_lists", ["arch_id"], :name => "index_build_lists_on_arch_id"
|
||||||
add_index "build_lists", ["bs_id"], :name => "index_build_lists_on_bs_id", :unique => true
|
add_index "build_lists", ["bs_id"], :name => "index_build_lists_on_bs_id", :unique => true
|
||||||
add_index "build_lists", ["project_id"], :name => "index_build_lists_on_project_id"
|
add_index "build_lists", ["project_id"], :name => "index_build_lists_on_project_id"
|
||||||
|
@ -331,8 +373,8 @@ ActiveRecord::Schema.define(:version => 20120425190938) do
|
||||||
|
|
||||||
create_table "users", :force => true do |t|
|
create_table "users", :force => true do |t|
|
||||||
t.string "name"
|
t.string "name"
|
||||||
t.string "email", :default => "", :null => false
|
t.string "email", :default => "", :null => false
|
||||||
t.string "encrypted_password", :limit => 128, :default => "", :null => false
|
t.string "encrypted_password", :default => "", :null => false
|
||||||
t.string "reset_password_token"
|
t.string "reset_password_token"
|
||||||
t.datetime "reset_password_sent_at"
|
t.datetime "reset_password_sent_at"
|
||||||
t.datetime "remember_created_at"
|
t.datetime "remember_created_at"
|
||||||
|
@ -341,9 +383,11 @@ ActiveRecord::Schema.define(:version => 20120425190938) do
|
||||||
t.text "ssh_key"
|
t.text "ssh_key"
|
||||||
t.string "uname"
|
t.string "uname"
|
||||||
t.string "role"
|
t.string "role"
|
||||||
t.string "language", :default => "en"
|
t.string "language", :default => "en"
|
||||||
t.datetime "reset_password_sent_at"
|
t.integer "own_projects_count", :default => 0, :null => false
|
||||||
t.integer "own_projects_count", :default => 0, :null => false
|
t.string "confirmation_token"
|
||||||
|
t.datetime "confirmed_at"
|
||||||
|
t.datetime "confirmation_sent_at"
|
||||||
t.text "professional_experience"
|
t.text "professional_experience"
|
||||||
t.string "site"
|
t.string "site"
|
||||||
t.string "company"
|
t.string "company"
|
||||||
|
@ -356,6 +400,7 @@ ActiveRecord::Schema.define(:version => 20120425190938) do
|
||||||
t.string "unlock_token"
|
t.string "unlock_token"
|
||||||
t.datetime "locked_at"
|
t.datetime "locked_at"
|
||||||
t.string "authentication_token"
|
t.string "authentication_token"
|
||||||
|
t.integer "build_priority", :default => 50
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "users", ["authentication_token"], :name => "index_users_on_authentication_token"
|
add_index "users", ["authentication_token"], :name => "index_users_on_authentication_token"
|
||||||
|
|
|
@ -7,6 +7,6 @@ class OwnerConstraint
|
||||||
end
|
end
|
||||||
|
|
||||||
def matches?(request)
|
def matches?(request)
|
||||||
@class_name.send(@finder, request.params[:owner_name]).present?
|
@class_name.send(@finder, request.params[:uname]).present?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -23,6 +23,7 @@ class ReservedNameValidator < ActiveModel::EachValidator
|
||||||
unfollow unsubscribe url user
|
unfollow unsubscribe url user
|
||||||
widget widgets wiki
|
widget widgets wiki
|
||||||
xfn xmpp
|
xfn xmpp
|
||||||
|
tour
|
||||||
}
|
}
|
||||||
|
|
||||||
def reserved_names
|
def reserved_names
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
|
||||||
|
namespace :buildlist do
|
||||||
|
|
||||||
|
namespace :clear do
|
||||||
|
desc 'Remove outdated unpublished BuildLists'
|
||||||
|
task :outdated => :environment do
|
||||||
|
say "Removing outdated BuildLists"
|
||||||
|
outdated = BuildList.outdated
|
||||||
|
say "There are #{outdated.count} outdated BuildLists at #{Time.now}"
|
||||||
|
|
||||||
|
BuildList.outdated.destroy_all
|
||||||
|
|
||||||
|
say "Outdated BuildLists was successfully removed"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,13 @@
|
||||||
|
namespace :downloads do
|
||||||
|
|
||||||
|
desc "Migrate from mount to symlinks"
|
||||||
|
task :migrate => :environment do
|
||||||
|
Platform.opened.each do |pl|
|
||||||
|
system("sudo umount #{pl.symlink_path}")
|
||||||
|
system("sudo rm -Rf #{pl.symlink_path}")
|
||||||
|
|
||||||
|
pl.symlink_directory
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -3,7 +3,7 @@ require 'spec_helper'
|
||||||
|
|
||||||
describe Groups::MembersController do
|
describe Groups::MembersController do
|
||||||
before(:each) do
|
before(:each) do
|
||||||
stub_rsync_methods
|
stub_symlink_methods
|
||||||
@group = FactoryGirl.create(:group)
|
@group = FactoryGirl.create(:group)
|
||||||
@user = @group.owner
|
@user = @group.owner
|
||||||
set_session_for @user
|
set_session_for @user
|
||||||
|
|