Merge branch 'master' into ui/sidebar

# Conflicts:
#	app/assets/stylesheets/framework/sidebar.scss
This commit is contained in:
Douwe Maan 2015-12-03 13:29:19 +01:00
commit 66a9579712
88 changed files with 379 additions and 349 deletions

View File

@ -116,23 +116,8 @@ GEM
activemodel (>= 3.2.0)
activesupport (>= 3.2.0)
json (>= 1.7)
celluloid (0.17.2)
celluloid-essentials
celluloid-extras
celluloid-fsm
celluloid-pool
celluloid-supervision
timers (>= 4.1.1)
celluloid-essentials (0.20.5)
timers (>= 4.1.1)
celluloid-extras (0.20.5)
timers (>= 4.1.1)
celluloid-fsm (0.20.5)
timers (>= 4.1.1)
celluloid-pool (0.20.5)
timers (>= 4.1.1)
celluloid-supervision (0.20.5)
timers (>= 4.1.1)
celluloid (0.16.0)
timers (~> 4.0.0)
charlock_holmes (0.7.3)
chunky_png (1.3.5)
cliver (0.3.2)
@ -757,7 +742,7 @@ GEM
thor (0.19.1)
thread_safe (0.3.5)
tilt (1.4.1)
timers (4.1.1)
timers (4.0.4)
hitimes
timfel-krb5-auth (0.8.3)
tinder (1.10.1)

View File

@ -1,9 +1,9 @@
@import "framework/fonts";
@import "framework/variables";
@import "framework/mixins";
@import "framework/layout";
@import 'framework/tw_bootstrap_variables';
@import 'framework/tw_bootstrap';
@import "framework/layout";
@import "framework/avatar.scss";
@import "framework/blocks.scss";
@ -25,6 +25,7 @@
@import "framework/markdown_area.scss";
@import "framework/mobile.scss";
@import "framework/pagination.scss";
@import "framework/panels.scss";
@import "framework/selects.scss";
@import "framework/sidebar.scss";
@import "framework/tables.scss";

View File

@ -68,6 +68,10 @@
.oneline {
line-height: 42px;
}
> p:last-child {
margin-bottom: 0;
}
}
.cover-block {
@ -114,3 +118,7 @@
right: 10px;
}
}
.block-connector {
margin-top: -1px;
}

View File

@ -7,7 +7,7 @@
/** COMMON CLASSES **/
.prepend-top-10 { margin-top:10px }
.prepend-top-default { margin-top: $gl-padding; }
.prepend-top-default { margin-top: $gl-padding !important; }
.prepend-top-20 { margin-top:20px }
.prepend-left-10 { margin-left:10px }
.prepend-left-20 { margin-left:20px }
@ -52,6 +52,10 @@ pre {
}
}
hr {
margin: $gl-padding 0;
}
.dropdown-menu > li > a {
text-shadow: none;
}
@ -433,3 +437,7 @@ table {
.space-right {
margin-right: 10px;
}
.alert, .progress {
margin-bottom: $gl-padding;
}

View File

@ -8,7 +8,6 @@
border: none;
border-top: 1px solid #E7E9EE;
border-bottom: 1px solid #E7E9EE;
margin-bottom: 1em;
&.readme-holder {
border-bottom: 0;
@ -25,7 +24,7 @@
text-shadow: 0 1px 1px #fff;
margin: 0;
text-align: left;
padding: 10px 15px;
padding: 10px $gl-padding;
.file-actions {
float: right;
@ -171,4 +170,3 @@
}
}
}

View File

@ -22,9 +22,10 @@ input[type='text'].danger {
}
.form-actions {
padding: 17px 20px 18px;
margin-top: 18px;
margin-bottom: 18px;
margin: -$gl-padding;
margin-top: 0;
margin-bottom: -$gl-padding;
padding: $gl-padding;
background-color: $background-color;
border-top: 1px solid $border-color;
}
@ -73,6 +74,8 @@ label {
.form-control {
@include box-shadow(none);
height: 42px;
padding: 8px $gl-padding;
}
.wiki-content {
@ -92,3 +95,7 @@ label {
background-color: #f7f8fa;
}
}
.help-block {
margin-bottom: 0;
}

View File

@ -7,8 +7,9 @@
.issue-box {
@include border-radius(2px);
display: inline-block;
padding: 10px $gl-padding;
display: block;
float: left;
padding: 0 $gl-padding;
font-weight: normal;
margin-right: 10px;
font-size: $gl-font-size;

View File

@ -2,10 +2,10 @@ html {
overflow-y: scroll;
&.touch .tooltip { display: none !important; }
}
body {
padding-top: $header-height;
}
body {
background-color: #EAEBEC !important;
}
.container {
@ -18,6 +18,7 @@ html {
}
.navless-container {
padding-top: $header-height;
margin-top: 30px;
}

View File

@ -0,0 +1,15 @@
.panel {
margin-bottom: $gl-padding;
.panel-heading {
padding: 10px $gl-padding;
}
.panel-body {
padding: $gl-padding;
.form-actions {
margin: -$gl-padding;
margin-top: $gl-padding;
}
}
}

View File

@ -20,15 +20,12 @@
}
.content-wrapper {
min-height: 100vh;
width: 100%;
padding: 20px;
background: #EAEBEC;
.container-fluid {
background: #FFF;
padding: $gl-padding;
min-height: 90vh;
&.container-blank {
background: none;

View File

@ -6,6 +6,8 @@
table {
&.table {
margin-bottom: $gl-padding;
.dropdown-menu a {
text-decoration: none;
}

View File

@ -181,6 +181,10 @@ body {
line-height: 1.3;
font-size: 1.25em;
font-weight: 600;
&:last-child {
margin-bottom: 0;
}
}
.page-title-empty {

View File

@ -2,10 +2,6 @@
display: block;
}
.commit-title{
margin-bottom: 10px;
}
.commit-author, .commit-committer{
display: block;
color: #999;
@ -41,6 +37,8 @@
.commit-box {
.commit-title {
margin: 0;
font-size: 23px;
color: #313236;
}
.commit-description {
@ -108,16 +106,3 @@
z-index: 2;
}
}
.commit-ci-menu {
padding: 0;
margin: 0;
list-style: none;
margin-top: 5px;
height: 56px;
margin: -16px;
padding: 16px;
text-align: center;
margin-top: 0px;
margin-bottom: 2px;
}

View File

@ -19,48 +19,38 @@
color: #B94A48;
}
}
.commit-button-annotation {
display: inline-block;
margin: 0;
padding: 2px;
> * {
float: left;
}
.message {
display: inline-block;
margin: 5px 8px 0 8px;
}
}
.file-title {
@extend .monospace;
line-height: 42px;
padding-top: 7px;
padding-bottom: 7px;
}
.editor-ref {
background: $background-color;
padding: 11px 15px;
padding-right: $gl-padding;
border-right: 1px solid $border-color;
display: inline-block;
margin: -5px -5px;
display: block;
float: left;
margin-right: 10px;
}
.editor-file-name {
.new-file-name {
display: inline-block;
width: 450px;
}
.form-control {
margin-top: -3px;
}
@extend .monospace;
float: left;
margin-right: 10px;
}
.form-actions {
margin: -$gl-padding;
margin-top: 0;
padding: $gl-padding
.new-file-name {
display: inline-block;
width: 450px;
float: left;
}
.select2 {
float: right;
}
}

View File

@ -51,11 +51,12 @@
.issuable-details {
.page-title {
margin-top: -15px;
padding: 10px 0;
margin-top: -$gl-padding;
padding: 7px 0;
margin-bottom: 0;
color: #5c5d5e;
font-size: 16px;
line-height: 42px;
.author {
color: #5c5d5e;

View File

@ -1,5 +1,7 @@
/* Login Page */
.login-page {
background-color: white;
.container {
max-width: 960px;
}

View File

@ -4,7 +4,6 @@
*/
.mr-state-widget {
background: #F7F8FA;
margin-bottom: 20px;
color: $gl-gray;
border: 1px solid #dce0e6;
@include border-radius(2px);
@ -87,7 +86,7 @@
.mr-widget-body,
.ci_widget,
.mr-widget-footer {
padding: 15px;
padding: $gl-padding;
}
.normal {
@ -116,26 +115,8 @@
}
}
.merge-request .merge-request-tabs {
@include nav-menu;
margin: -$gl-padding;
padding: $gl-padding;
text-align: center;
margin-bottom: 1px;
}
// Mobile
@media (max-width: 480px) {
.merge-request .merge-request-tabs {
margin: 0;
padding: 0;
li {
a {
padding: 0;
}
}
}
.merge-request-details {
margin-bottom: $gl-padding;
}
.mr_source_commit,

View File

@ -7,6 +7,7 @@
}
.reply-btn {
@extend .btn-primary;
margin: 10px $gl-padding;
}
.diff-file .diff-content {
tr.line_holder:hover {
@ -38,9 +39,8 @@
}
.new_note, .edit_note {
.buttons {
margin-top: 8px;
margin-bottom: 3px;
.note-form-actions {
margin-top: $gl-padding;
}
.note-preview-holder {
@ -79,8 +79,8 @@
padding: $gl-padding;
margin-left: -$gl-padding;
margin-right: -$gl-padding;
border-right: 1px solid #ECEEF1;
border-top: 1px solid #ECEEF1;
border-right: 1px solid $border-color;
border-top: 1px solid $border-color;
margin-bottom: -$gl-padding;
}
@ -150,7 +150,6 @@
.discussion-reply-holder {
background: $background-color;
padding: 10px 15px;
border-top: 1px solid $border-color;
}
}

View File

@ -18,10 +18,6 @@
}
}
.project-edit-content {
padding: 7px;
}
.project-name-holder {
.help-inline {
vertical-align: top;
@ -30,12 +26,6 @@
}
.project-home-panel {
text-align: center;
background: #f7f8fa;
margin: -$gl-padding;
padding: $gl-padding;
padding: 44px 0 17px 0;
.project-identicon-holder {
margin-bottom: 16px;
@ -105,7 +95,6 @@
display: inline-table;
position: relative;
top: 17px;
margin-bottom: 44px;
}
.project-repo-buttons {
@ -376,7 +365,7 @@ table.table.protected-branches-list tr.no-border {
.project-stats {
text-align: center;
margin-top: 15px;
margin-top: $gl-padding;
margin-bottom: 0;
padding-top: 10px;
padding-bottom: 4px;

View File

@ -27,56 +27,22 @@
}
.snippet-holder {
.snippet-details {
.page-title {
margin-top: -15px;
padding: 10px 0;
margin-bottom: 0;
color: #5c5d5e;
font-size: 16px;
.author {
color: #5c5d5e;
}
.snippet-id {
color: #5c5d5e;
}
}
.snippet-title {
margin: 0;
font-size: 23px;
color: #313236;
}
@media (max-width: $screen-md-max) {
.new-snippet-link {
display: none;
}
}
@media (max-width: $screen-sm-max) {
.creator,
.page-title .btn-close {
display: none;
}
}
}
margin-bottom: -$gl-padding;
.file-holder {
border-top: 0;
}
}
.snippet-box {
@include border-radius(2px);
display: inline-block;
padding: 10px $gl-padding;
display: block;
float: left;
padding: 0 $gl-padding;
font-weight: normal;
margin-right: 10px;
font-size: $gl-font-size;
border: 1px solid;
line-height: 40px;
}

View File

@ -5,14 +5,20 @@ class Admin::ImpersonationController < Admin::ApplicationController
before_action :authorize_impersonator!
def create
session[:impersonator_id] = current_user.username
session[:impersonator_return_to] = request.env['HTTP_REFERER']
if @user.blocked?
flash[:alert] = "You cannot impersonate a blocked user"
warden.set_user(user, scope: 'user')
redirect_to admin_user_path(@user)
else
session[:impersonator_id] = current_user.username
session[:impersonator_return_to] = admin_user_path(@user)
flash[:alert] = "You are impersonating #{user.username}."
warden.set_user(user, scope: 'user')
redirect_to root_path
flash[:alert] = "You are impersonating #{user.username}."
redirect_to root_path
end
end
def destroy

View File

@ -60,7 +60,7 @@ module BlobHelper
if Gitlab::MarkupHelper.previewable?(filename)
'Preview'
else
'Preview changes'
'Preview Changes'
end
end

View File

@ -109,7 +109,7 @@ module CommitsHelper
)
elsif @path.present?
return link_to(
"Browse Dir »",
"Browse Directory »",
namespace_project_tree_path(project.namespace, project,
tree_join(commit.id, @path)),
class: "pull-right"
@ -117,7 +117,7 @@ module CommitsHelper
end
end
link_to(
"Browse Code »",
"Browse Files »",
namespace_project_tree_path(project.namespace, project, commit),
class: "pull-right"
)

View File

@ -146,9 +146,9 @@ module DiffHelper
def submodule_link(blob, ref, repository = @repository)
tree, commit = submodule_links(blob, ref, repository)
commit_id = if commit.nil?
blob.id[0..10]
Commit.truncate_sha(blob.id)
else
link_to "#{blob.id[0..10]}", commit
link_to Commit.truncate_sha(blob.id), commit
end
[

View File

@ -37,7 +37,7 @@ class BuildkiteService < CiService
def compose_service_hook
hook = service_hook || build_service_hook
hook.url = webhook_url
hook.enable_ssl_verification = enable_ssl_verification
hook.enable_ssl_verification = !!enable_ssl_verification
hook.save
end

View File

@ -34,7 +34,7 @@ class DroneCiService < CiService
hook = service_hook || build_service_hook
# If using a service template, project may not be available
hook.url = [drone_url, "/api/hook", "?owner=#{project.namespace.path}", "&name=#{project.path}", "&access_token=#{token}"].join if project
hook.enable_ssl_verification = enable_ssl_verification
hook.enable_ssl_verification = !!enable_ssl_verification
hook.save
end

View File

@ -690,7 +690,7 @@ class User < ActiveRecord::Base
end
def starred?(project)
starred_projects.exists?(project)
starred_projects.exists?(project.id)
end
def toggle_star(project)
@ -794,4 +794,9 @@ class User < ActiveRecord::Base
Gitlab::SQL::Union.new([personal_projects.select(:id), groups.select(:id),
other.select(:id)])
end
# Added according to https://github.com/plataformatec/devise/blob/7df57d5081f9884849ca15e4fde179ef164a575f/README.md#activejob-integration
def send_devise_notification(notification, *args)
devise_mailer.send(notification, self, *args).deliver_later
end
end

View File

@ -2,4 +2,4 @@
= render_colored_label(label)
.pull-right
= link_to 'Edit', edit_admin_label_path(label), class: 'btn btn-sm'
= link_to 'Remove', admin_label_path(label), class: 'btn btn-sm btn-remove remove-row', method: :delete, remote: true, data: {confirm: "Remove this label? Are you sure?"}
= link_to 'Delete', admin_label_path(label), class: 'btn btn-sm btn-remove remove-row', method: :delete, remote: true, data: {confirm: "Delete this label? Are you sure?"}

View File

@ -6,7 +6,7 @@
%span.cred (Admin)
.pull-right
- unless @user == current_user
- unless @user == current_user || @user.blocked?
= link_to 'Impersonate', impersonate_admin_user_path(@user), method: :post, class: "btn btn-grouped btn-info"
= link_to edit_admin_user_path(@user), class: "btn btn-grouped" do
%i.fa.fa-pencil-square-o

View File

@ -7,7 +7,7 @@
= @project.name
%p
Commit: #{link_to @build.short_sha, namespace_project_commit_path(@build.gl_project.namespace, @build.gl_project, @build.sha)}
Commit: #{link_to @build.short_sha, namespace_project_commit_url(@build.gl_project.namespace, @build.gl_project, @build.sha)}
%p
Author: #{@build.commit.git_author_name}
%p

View File

@ -8,8 +8,8 @@
= link_to new_group_path, class: "btn btn-new" do
%i.fa.fa-plus
New Group
.title Welcome to the groups!
Group members have access to all group projects.
.oneline
Group members have access to all group projects.
%ul.content-list
- @group_members.each do |group_member|

View File

@ -3,7 +3,7 @@
.form-group
= search_field_tag :search, params[:search], placeholder: "Filter by name", class: "form-control search-text-input", id: "projects_search", spellcheck: false
.form-group
= button_tag 'Search', class: "btn btn-success"
= button_tag 'Search', class: "btn"
.pull-right.hidden-sm.hidden-xs
- if current_user

View File

@ -1,4 +1,5 @@
- page_title "Bitbucket import"
- header_title "Projects", root_path
%h3.page-title
%i.fa.fa-bitbucket
Import projects from Bitbucket

View File

@ -1,4 +1,5 @@
- page_title "FogBugz Import"
- header_title "Projects", root_path
%h3.page-title
%i.fa.fa-bug
Import projects from FogBugz

View File

@ -1,4 +1,5 @@
- page_title 'User map', 'FogBugz import'
- header_title "Projects", root_path
%h3.page-title
%i.fa.fa-bug
Import projects from FogBugz

View File

@ -1,4 +1,5 @@
- page_title "FogBugz import"
- header_title "Projects", root_path
%h3.page-title
%i.fa.fa-bug
Import projects from FogBugz

View File

@ -1,4 +1,5 @@
- page_title "GitHub import"
- header_title "Projects", root_path
%h3.page-title
%i.fa.fa-github
Import projects from GitHub

View File

@ -1,4 +1,5 @@
- page_title "GitLab.com import"
- header_title "Projects", root_path
%h3.page-title
%i.fa.fa-heart
Import projects from GitLab.com

View File

@ -1,4 +1,5 @@
- page_title "Gitorious import"
- header_title "Projects", root_path
%h3.page-title
%i.icon-gitorious.icon-gitorious-big
Import projects from Gitorious.org

View File

@ -1,4 +1,5 @@
- page_title "Google Code import"
- header_title "Projects", root_path
%h3.page-title
%i.fa.fa-google
Import projects from Google Code
@ -6,7 +7,7 @@
= form_tag callback_import_google_code_path, class: 'form-horizontal', multipart: true do
%p
Follow the steps below to export your Google Code project data.
Follow the steps below to export your Google Code project data.
In the next step, you'll be able to select the projects you want to import.
%ol
%li

View File

@ -1,4 +1,5 @@
- page_title "User map", "Google Code import"
- header_title "Projects", root_path
%h3.page-title
%i.fa.fa-google
Import projects from Google Code
@ -8,31 +9,31 @@
%p
Customize how Google Code email addresses and usernames are imported into GitLab.
In the next step, you'll be able to select the projects you want to import.
%p
%p
The user map is a JSON document mapping the Google Code users that participated on your projects to the way their email addresses and usernames will be imported into GitLab. You can change this by changing the value on the right hand side of <code>:</code>. Be sure to preserve the surrounding double quotes, other punctuation and the email address or username on the left hand side.
%ul
%li
%strong Default: Directly import the Google Code email address or username
%p
<code>"johnsmith@example.com": "johnsm...@example.com"</code>
will add "By johnsm...@example.com" to all issues and comments originally created by johnsmith@example.com.
<code>"johnsmith@example.com": "johnsm...@example.com"</code>
will add "By johnsm...@example.com" to all issues and comments originally created by johnsmith@example.com.
The email address or username is masked to ensure the user's privacy.
%li
%strong Map a Google Code user to a GitLab user
%p
<code>"johnsmith@example.com": "@johnsmith"</code>
will add "By <a href="#">@johnsmith</a>" to all issues and comments originally created by johnsmith@example.com,
<code>"johnsmith@example.com": "@johnsmith"</code>
will add "By <a href="#">@johnsmith</a>" to all issues and comments originally created by johnsmith@example.com,
and will set <a href="#">@johnsmith</a> as the assignee on all issues originally assigned to johnsmith@example.com.
%li
%strong Map a Google Code user to a full name
%p
<code>"johnsmith@example.com": "John Smith"</code>
<code>"johnsmith@example.com": "John Smith"</code>
will add "By John Smith" to all issues and comments originally created by johnsmith@example.com.
%li
%strong Map a Google Code user to a full email address
%p
<code>"johnsmith@example.com": "johnsmith@example.com"</code>
will add "By <a href="#">johnsmith@example.com</a>" to all issues and comments originally created by johnsmith@example.com.
<code>"johnsmith@example.com": "johnsmith@example.com"</code>
will add "By <a href="#">johnsmith@example.com</a>" to all issues and comments originally created by johnsmith@example.com.
By default, the email address or username is masked to ensure the user's privacy. Use this option if you want to show the full email address.
.form-group

View File

@ -1,4 +1,5 @@
- page_title "Google Code import"
- header_title "Projects", root_path
%h3.page-title
%i.fa.fa-google
Import projects from Google Code

View File

@ -15,24 +15,25 @@
.pull-right
= link_to 'New Application', new_oauth_application_path, class: 'btn btn-success'
- if @applications.any?
%table.table.table-striped
%thead
%tr
%th Name
%th Callback URL
%th Clients
%th
%th
%tbody
- @applications.each do |application|
%tr{:id => "application_#{application.id}"}
%td= link_to application.name, oauth_application_path(application)
%td
- application.redirect_uri.split.each do |uri|
%div= uri
%td= application.access_tokens.count
%td= link_to 'Edit', edit_oauth_application_path(application), class: 'btn btn-link btn-sm'
%td= render 'doorkeeper/applications/delete_form', application: application
.table-holder
%table.table.table-striped
%thead
%tr
%th Name
%th Callback URL
%th Clients
%th
%th
%tbody
- @applications.each do |application|
%tr{:id => "application_#{application.id}"}
%td= link_to application.name, oauth_application_path(application)
%td
- application.redirect_uri.split.each do |uri|
%div= uri
%td= application.access_tokens.count
%td= link_to 'Edit', edit_oauth_application_path(application), class: 'btn btn-link btn-sm'
%td= render 'doorkeeper/applications/delete_form', application: application
.oauth-authorized-applications.prepend-top-20
- if user_oauth_applications?
@ -40,29 +41,30 @@
Authorized applications
- if @authorized_tokens.any?
%table.table.table-striped
%thead
%tr
%th Name
%th Authorized At
%th Scope
%th
%tbody
- @authorized_apps.each do |app|
- token = app.authorized_tokens.order('created_at desc').first
%tr{:id => "application_#{app.id}"}
%td= app.name
%td= token.created_at
%td= token.scopes
%td= render 'doorkeeper/authorized_applications/delete_form', application: app
- @authorized_anonymous_tokens.each do |token|
.table-holder
%table.table.table-striped
%thead
%tr
%td
Anonymous
%div.help-block
%em Authorization was granted by entering your username and password in the application.
%td= token.created_at
%td= token.scopes
%td= render 'doorkeeper/authorized_applications/delete_form', token: token
%th Name
%th Authorized At
%th Scope
%th
%tbody
- @authorized_apps.each do |app|
- token = app.authorized_tokens.order('created_at desc').first
%tr{:id => "application_#{app.id}"}
%td= app.name
%td= token.created_at
%td= token.scopes
%td= render 'doorkeeper/authorized_applications/delete_form', application: app
- @authorized_anonymous_tokens.each do |token|
%tr
%td
Anonymous
%div.help-block
%em Authorization was granted by entering your username and password in the application.
%td= token.created_at
%td= token.scopes
%td= render 'doorkeeper/authorized_applications/delete_form', token: token
- else
%p.light You don't have any authorized applications

View File

@ -1,6 +1,6 @@
- is_admin = defined?(admin) ? true : false
.panel.panel-default
- if @keys.any?
- if @keys.any?
.table-holder
%table.table
%thead.panel-heading
%tr
@ -11,9 +11,9 @@
%tbody
- @keys.each do |key|
= render 'profiles/keys/key', key: key, is_admin: is_admin
- else
.nothing-here-block
- if is_admin
User has no ssh keys
- else
There are no SSH keys with access to your account.
- else
.nothing-here-block
- if is_admin
User has no ssh keys
- else
There are no SSH keys with access to your account.

View File

@ -3,7 +3,9 @@
.gray-content-block.top-block
.pull-right
= link_to "Add SSH Key", new_profile_key_path, class: "btn btn-new"
= link_to new_profile_key_path, class: "btn btn-new" do
= icon('plus')
Add SSH Key
.oneline
Before you can add an SSH key you need to
= link_to "generate it.", help_page_path("ssh", "README")

View File

@ -50,12 +50,10 @@
Watch
%p You will receive notifications for any activity
.form-actions
.gray-content-block
= f.submit 'Save changes', class: "btn btn-create"
.clearfix
%hr
.row.all-notifications
.row.all-notifications.prepend-top-default
.col-md-6
%p
You can also specify notification level per group or per project.

View File

@ -7,15 +7,16 @@
= cache(readme_cache_key) do
= render_readme(readme)
- else
%h3.page-title
This project does not have README yet
- if can?(current_user, :push_code, @project)
%p.slead
A
%code README
file contains information about other files in a repository and is commonly
distributed with computer software, forming part of its documentation.
%br
We recommend you to
= link_to "add README", new_readme_path, class: 'underlined-link'
file to the repository and GitLab will render it here instead of this message.
.gray-content-block.second-block.center
%h3.page-title
This project does not have README yet
- if can?(current_user, :push_code, @project)
%p
A
%code README
file contains information about other files in a repository and is commonly
distributed with computer software, forming part of its documentation.
%p
We recommend you to
= link_to "add README", new_readme_path, class: 'underlined-link'
file to the repository and GitLab will render it here instead of this message.

View File

@ -6,7 +6,7 @@
#tree-holder.tree-holder
.file-holder
.file-title
%i.fa.fa-file
= blob_icon @blob.mode, @blob.name
%strong
= @path
%small= number_to_human_size @blob.size
@ -43,4 +43,3 @@
- blame_group[:lines].each do |line|
:erb
<%= highlight(@blob.name, line, nowrap: true, continue: true).html_safe %>

View File

@ -1,19 +1,19 @@
.file-holder.file
.file-title
.file-holder.file.append-bottom-default
.file-title.clearfix
.editor-ref
%i.fa.fa-code-fork
= icon('code-fork')
= ref
%span.editor-file-name
- if @path
%span.monospace
= @path
= @path
- if current_action?(:new) || current_action?(:create)
- if current_action?(:new) || current_action?(:create)
%span.editor-file-name
\/
= text_field_tag 'file_name', params[:file_name], placeholder: "File name",
required: true, class: 'form-control new-file-name js-quick-submit'
.pull-right
= select_tag :encoding, options_for_select([ "base64", "text" ], "text"), class: 'form-control'
= text_field_tag 'file_name', params[:file_name], placeholder: "File name",
required: true, class: 'form-control new-file-name js-quick-submit'
.pull-right
= select_tag :encoding, options_for_select([ "base64", "text" ], "text"), class: 'select2'
.file-content.code
%pre.js-edit-mode-pane#editor

View File

@ -5,12 +5,12 @@
%ul.center-top-menu.no-bottom.js-edit-mode
%li.active
= link_to '#editor' do
%i.fa.fa-edit
Edit file
= icon('edit')
Edit File
%li
= link_to '#preview', 'data-preview-url' => namespace_project_preview_blob_path(@project.namespace, @project, @id) do
%i.fa.fa-eye
= icon('eye')
= editing_preview_title(@blob.name)
= form_tag(namespace_project_update_blob_path(@project.namespace, @project, @id), method: :put, class: 'form-horizontal js-requires-input js-edit-blob-form') do

View File

@ -1,5 +1,5 @@
.branch-commit
= link_to commit.short_id, namespace_project_commit_path(project.namespace, project, commit), class: "commit-id"
= link_to commit.short_id, namespace_project_commit_path(project.namespace, project, commit), class: "commit-id monospace"
&middot;
%span.str-truncated
= link_to_gfm commit.title, namespace_project_commit_path(project.namespace, project, commit.id), class: "commit-row-message"

View File

@ -5,7 +5,7 @@
.pull-right
- if can? current_user, :push_code, @project
= link_to new_namespace_project_branch_path(@project.namespace, @project), class: 'btn btn-create' do
%i.fa.fa-add-sign
= icon('plus')
New branch
&nbsp;
.dropdown.inline

View File

@ -1,4 +1,4 @@
%ul.center-top-menu.commit-ci-menu
%ul.center-top-menu.no-top.no-bottom.commit-ci-menu
= nav_link(path: 'commit#show') do
= link_to namespace_project_commit_path(@project.namespace, @project, @commit.id) do
Changes

View File

@ -13,8 +13,9 @@
- unless @commit.parents.length > 1
%li= link_to "Email Patches", namespace_project_commit_path(@project.namespace, @project, @commit, format: :patch)
%li= link_to "Plain Diff", namespace_project_commit_path(@project.namespace, @project, @commit, format: :diff)
= link_to namespace_project_tree_path(@project.namespace, @project, @commit), class: "btn btn-primary btn-grouped" do
%span Browse Code »
= link_to namespace_project_tree_path(@project.namespace, @project, @commit), class: "btn btn-grouped" do
= icon('files-o')
Browse Files
%div
%p

View File

@ -1,6 +1,9 @@
- page_title "#{@commit.title} (#{@commit.short_id})", "Commits"
= render "projects/commits/header_title"
= render "commit_box"
= render "ci_menu" if @ci_commit
- if @ci_commit
= render "ci_menu"
- else
%div.block-connector
= render "projects/diffs/diffs", diffs: @diffs, project: @project
= render "projects/notes/notes_with_form"

View File

@ -7,11 +7,11 @@
= render "form"
- if @commits.present?
.prepend-top-20
.prepend-top-default
= render "projects/commits/commit_list"
= render "projects/diffs/diffs", diffs: @diffs, project: @project
- else
.light-well.prepend-top-20
.light-well.prepend-top-default
.center
%h4
There isn't anything to compare.

View File

@ -3,7 +3,7 @@
- diff_files = safe_diff_files(diffs)
.gray-content-block.second-block.oneline-block
.gray-content-block.middle-block.oneline-block
.inline-parallel-buttons
.btn-group
= inline_diff_btn

View File

@ -2,19 +2,27 @@
.diff-header{id: "file-path-#{hexdigest(diff_file.file_path)}"}
- if diff_file.diff.submodule?
%span
= icon('archive fw')
- submodule_item = project.repository.blob_at(@commit.id, diff_file.file_path)
= submodule_link(submodule_item, @commit.id, project.repository)
%strong
= submodule_link(submodule_item, @commit.id, project.repository)
- else
%span
= blob_icon blob.mode, blob.name
= link_to "#diff-#{i}" do
%strong
= diff_file.new_path
- if diff_file.deleted_file
= "#{diff_file.old_path} deleted"
deleted
- elsif diff_file.renamed_file
= "#{diff_file.old_path} renamed to #{diff_file.new_path}"
- else
= diff_file.new_path
renamed from
%strong
= diff_file.old_path
- if diff_file.mode_changed?
%span.file-mode= "#{diff_file.diff.a_mode} → #{diff_file.diff.b_mode}"
%small
= "#{diff_file.diff.a_mode} → #{diff_file.diff.b_mode}"
.diff-controls
- if blob.text?

View File

@ -5,17 +5,16 @@
= render "home_panel"
.gray-content-block.center
.gray-content-block.second-block.center
%h3.page-title
The repository for this project is empty
- if can?(current_user, :download_code, @project)
- if can?(current_user, :push_code, @project)
%p
If you already have files you can push them using command line instructions below.
%br
- if can?(current_user, :push_code, @project)
Otherwise you can start with
= link_to "adding README", new_readme_path, class: 'underlined-link'
file to this project.
%p
Otherwise you can start with
= link_to "adding README", new_readme_path, class: 'underlined-link'
file to this project.
- if can?(current_user, :download_code, @project)
.prepend-top-20

View File

@ -7,4 +7,4 @@
- if can? current_user, :admin_label, @project
= link_to 'Edit', edit_namespace_project_label_path(@project.namespace, @project, label), class: 'btn btn-sm'
= link_to 'Remove', namespace_project_label_path(@project.namespace, @project, label), class: 'btn btn-sm btn-remove remove-row', method: :delete, remote: true, data: {confirm: "Remove this label? Are you sure?"}
= link_to 'Delete', namespace_project_label_path(@project.namespace, @project, label), class: 'btn btn-sm btn-remove remove-row', method: :delete, remote: true, data: {confirm: "Remove this label? Are you sure?"}

View File

@ -4,6 +4,7 @@
.gray-content-block.top-block
- if can? current_user, :admin_label, @project
= link_to new_namespace_project_label_path(@project.namespace, @project), class: "pull-right btn btn-new" do
= icon('plus')
New label
.oneline
Labels can be applied to issues and merge requests.

View File

@ -7,7 +7,7 @@
= render 'shared/show_aside'
.gray-content-block.second-block.oneline-block
.gray-content-block.middle-block.oneline-block
.row
.col-md-9
.votes-holder.pull-right

View File

@ -37,7 +37,7 @@
%h4 Compare failed
%p We can't compare selected branches. It may be because of huge diff. Please try again or select different branches.
- else
.light-well.append-bottom-10
.light-well.append-bottom-default
.center
%h4
There isn't anything to merge.
@ -86,4 +86,3 @@
return;
}
});

View File

@ -19,7 +19,7 @@
= f.hidden_field :target_branch
.mr-compare.merge-request
%ul.merge-request-tabs
%ul.merge-request-tabs.center-top-menu.no-top.no-bottom
%li.commits-tab
= link_to url_for(params), data: {target: '#commits', action: 'commits', toggle: 'tab'} do
Commits
@ -31,7 +31,7 @@
.tab-content
#commits.commits.tab-pane
= render "projects/commits/commits", project: @project
= render "projects/merge_requests/show/commits"
#diffs.diffs.tab-pane.active
- if @diffs.present?
= render "projects/diffs/diffs", diffs: @diffs, project: @project
@ -57,4 +57,3 @@
diffs_loaded: true,
commits_loaded: true
});

View File

@ -8,7 +8,7 @@
.merge-request-details.issuable-details
= render "projects/merge_requests/show/mr_title"
= render "projects/merge_requests/show/mr_box"
.append-bottom-20.mr-source-target.prepend-top-default
.append-bottom-default.mr-source-target.prepend-top-default
- if @merge_request.open?
.pull-right
- if @merge_request.source_branch_exists?
@ -40,7 +40,7 @@
= link_to "command line", "#modal_merge_info", class: "how_to_merge_link vlink", title: "How To Merge", "data-toggle" => "modal"
- if @commits.present?
%ul.merge-request-tabs
%ul.merge-request-tabs.center-top-menu.no-top.no-bottom
%li.notes-tab
= link_to namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: {target: '#notes', action: 'notes', toggle: 'tab'} do
Discussion

View File

@ -1,4 +1,4 @@
.gray-content-block.second-block.oneline-block
.gray-content-block.middle-block.oneline-block
= icon("sort-amount-desc")
Most recent commits displayed first

View File

@ -31,4 +31,4 @@
= link_to 'Close Milestone', namespace_project_milestone_path(@project.namespace, @project, milestone, milestone: {state_event: :close }), method: :put, remote: true, class: "btn btn-xs btn-close"
= link_to namespace_project_milestone_path(milestone.project.namespace, milestone.project, milestone), data: { confirm: 'Are you sure?' }, method: :delete, class: "btn btn-xs btn-remove" do
%i.fa.fa-trash-o
Remove
Delete

View File

@ -23,7 +23,7 @@
= link_to 'Reopen Milestone', namespace_project_milestone_path(@project.namespace, @project, @milestone, milestone: {state_event: :activate }), method: :put, class: "btn btn-reopen btn-grouped"
= link_to namespace_project_milestone_path(@project.namespace, @project, @milestone), data: { confirm: 'Are you sure?' }, method: :delete, class: "btn btn-grouped btn-remove" do
%i.fa.fa-trash-o
Remove
Delete
%hr
- if @milestone.issues.any? && @milestone.can_be_closed?

View File

@ -14,6 +14,6 @@
= render 'projects/zen', f: f, attr: :description, classes: 'description js-quick-submit form-control'
= render 'projects/notes/hints'
.error-alert
.prepend-top-default
.form-actions.prepend-top-default
= f.submit 'Save changes', class: 'btn btn-save'
= link_to "Cancel", namespace_project_tag_path(@project.namespace, @project, @tag.name), class: "btn btn-default btn-cancel"

View File

@ -3,10 +3,10 @@
- split_button = split_button || false
- if split_button == true
%span.btn-group{class: btn_class}
= link_to archive_namespace_project_repository_path(@project.namespace, @project, ref: ref, format: 'zip'), class: 'btn btn-success col-xs-10', rel: 'nofollow' do
= link_to archive_namespace_project_repository_path(@project.namespace, @project, ref: ref, format: 'zip'), class: 'btn col-xs-10', rel: 'nofollow' do
%i.fa.fa-download
%span Download zip
%a.col-xs-2.btn.btn-success.dropdown-toggle{ 'data-toggle' => 'dropdown' }
%a.col-xs-2.btn.dropdown-toggle{ 'data-toggle' => 'dropdown' }
%span.caret
%span.sr-only
Select Archive Format

View File

@ -11,7 +11,7 @@
= render "home_panel"
.project-stats.gray-content-block
.project-stats.gray-content-block.second-block
%ul.nav.nav-pills
%li
= link_to namespace_project_commits_path(@project.namespace, @project, current_ref) do

View File

@ -6,7 +6,7 @@
- if can? current_user, :push_code, @project
.pull-right
= link_to new_namespace_project_tag_path(@project.namespace, @project), class: 'btn btn-create new-tag-btn' do
%i.fa.fa-add-sign
= icon('plus')
New tag
.oneline
Tags give the ability to mark specific points in history as being important

View File

@ -12,7 +12,7 @@
%i.fa.fa-angle-right
&nbsp;
%small.light
= link_to @commit.short_id, namespace_project_commit_path(@project.namespace, @project, @commit)
= link_to @commit.short_id, namespace_project_commit_path(@project.namespace, @project, @commit), class: "monospace"
&ndash;
= truncate(@commit.title, length: 50)
= link_to 'History', namespace_project_commits_path(@project.namespace, @project, @id), class: 'pull-right'

View File

@ -1,5 +1,5 @@
= form_for [@project.namespace.becomes(Namespace), @project, issuable], remote: true, html: {class: 'issuable-context-form inline-update js-issuable-update'} do |f|
%div.prepend-top-20
%div.prepend-top-default
.issuable-context-title
%label
Assignee:
@ -11,7 +11,7 @@
- if can?(current_user, :"admin_#{issuable.to_ability_name}", @project)
= users_select_tag("#{issuable.class.table_name.singularize}[assignee_id]", placeholder: 'Select assignee', class: 'custom-form-control js-select2 js-assignee', selected: issuable.assignee_id, project: @target_project, null_user: true, current_user: true)
%div.prepend-top-20.clearfix
%div.prepend-top-default.clearfix
.issuable-context-title
%label
Milestone:
@ -31,7 +31,7 @@
- if current_user
- subscribed = issuable.subscribed?(current_user)
%div.prepend-top-20.clearfix
%div.prepend-top-default.clearfix
.issuable-context-title
%label
Subscription:

View File

@ -93,7 +93,8 @@
%p.help-block
= link_to 'Change branches', mr_change_branches_path(@merge_request)
.form-actions
- is_footer = !(issuable.is_a?(MergeRequest) && issuable.new_record?)
.gray-content-block{class: (is_footer ? "footer-block" : "middle-block")}
- if !issuable.project.empty_repo? && (guide_url = contribution_guide_path(issuable.project)) && !issuable.persisted?
%p
Please review the

View File

@ -1,9 +1,9 @@
.snippet-details
.issuable-details
.page-title
.snippet-box{class: visibility_level_color(@snippet.visibility_level)}
= visibility_level_icon(@snippet.visibility_level)
= visibility_level_label(@snippet.visibility_level)
%span.snippet-id Snippet ##{@snippet.id}
Snippet ##{@snippet.id}
%span.creator
&middot; created by #{link_to_member(@project, @snippet.author, size: 24)}
&middot;
@ -19,6 +19,7 @@
= render "projects/snippets/actions"
- else
= render "snippets/actions"
.gray-content-block.middle-block
%h2.snippet-title
%h2.issue-title
= gfm escape_once(@snippet.title)

View File

@ -32,7 +32,7 @@ Rails.application.configure do
# config.force_ssl = true
# See everything in the log (default is :info)
# config.log_level = :debug
config.log_level = :info
# Suppress 'Rendered template ...' messages in the log
# source: http://stackoverflow.com/a/16369363

View File

@ -6,6 +6,9 @@ If a user is both in a project group and in the project itself, the highest perm
If a user is a GitLab administrator they receive all permissions.
On public projects the Guest role is not enforced.
All users will be able to create issues, leave comments, and pull or download the project code.
To add or import a user, you can follow the [project users and members
documentation](doc/workflow/add-user/add-user.md).
@ -15,8 +18,8 @@ documentation](doc/workflow/add-user/add-user.md).
|---------------------------------------|---------|------------|-------------|----------|--------|
| Create new issue | ✓ | ✓ | ✓ | ✓ | ✓ |
| Leave comments | ✓ | ✓ | ✓ | ✓ | ✓ |
| Pull project code | | ✓ | ✓ | ✓ | ✓ |
| Download project | | ✓ | ✓ | ✓ | ✓ |
| Pull project code | | ✓ | ✓ | ✓ | ✓ |
| Download project | | ✓ | ✓ | ✓ | ✓ |
| Create code snippets | | ✓ | ✓ | ✓ | ✓ |
| Manage issue tracker | | ✓ | ✓ | ✓ | ✓ |
| Manage labels | | ✓ | ✓ | ✓ | ✓ |

View File

@ -6,7 +6,8 @@ For example from 7.14.0 to 7.14.3, also see the [semantic versioning specificati
### 0. Backup
It's useful to make a backup just in case things go south:
(With MySQL, this may require granting "LOCK TABLES" privileges to the GitLab user on the database version)
(With MySQL, this may require granting "LOCK TABLES" privileges to the GitLab
user on the database version)
```bash
cd /home/git/gitlab
@ -15,19 +16,23 @@ sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production
### 1. Stop server
sudo service gitlab stop
```bash
sudo service gitlab stop
```
### 2. Get latest code for the stable branch
In the commands below, replace `LATEST_TAG` with the latest GitLab tag you want
to update to, for example `v8.0.3`. Use `git tag -l 'v*.[0-9]' --sort='v:refname'`
to see a list of all tags. Make sure to update patch versions only (check your
current version with `cat VERSION`).
```bash
cd /home/git/gitlab
sudo -u git -H git fetch --all
sudo -u git -H git checkout -- Gemfile.lock db/schema.rb
sudo -u git -H git checkout LATEST_TAG -b LATEST_TAG
```
Replace `LATEST_TAG` with the latest GitLab tag you want to update to, for example `v8.0.3`.
Use `git tag -l 'v*.[0-9]' --sort='v:refname'` to see a list of all tags.
Make sure to update patch versions only (check your current version with `cat VERSION`)
### 3. Update gitlab-shell to the corresponding version
@ -37,12 +42,20 @@ sudo -u git -H git fetch
sudo -u git -H git checkout v`cat /home/git/gitlab/GITLAB_SHELL_VERSION` -b v`cat /home/git/gitlab/GITLAB_SHELL_VERSION`
```
### 4. Install libs, migrations, etc.
### 4. Update gitlab-workhorse to the corresponding version
```bash
cd /home/git/gitlab-workhorse
sudo -u git -H git fetch
sudo -u git -H git checkout v`cat /home/git/gitlab/GITLAB_WORKHORSE_VERSION` -b v`cat /home/git/gitlab/GITLAB_WORKHORSE_VERSION`
```
### 5. Install libs, migrations, etc.
```bash
cd /home/git/gitlab
#PostgreSQL
# PostgreSQL
sudo -u git -H bundle install --without development test mysql --deployment
# MySQL
@ -52,19 +65,25 @@ sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production
sudo -u git -H bundle exec rake assets:clean assets:precompile cache:clear RAILS_ENV=production
```
### 5. Start application
### 6. Start application
sudo service gitlab start
sudo service nginx restart
```bash
sudo service gitlab start
sudo service nginx restart
```
### 6. Check application status
### 7. Check application status
Check if GitLab and its environment are configured correctly:
sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production
```bash
sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production
```
To make sure you didn't miss anything run a more thorough check with:
sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production
```bash
sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production
```
If all items are green, then congratulations upgrade complete!

View File

@ -17,7 +17,7 @@ class Spinach::Features::AdminIssuesLabels < Spinach::FeatureSteps
step 'I remove label \'bug\'' do
page.within "#label_#{bug_label.id}" do
click_link 'Remove'
click_link 'Delete'
end
end

View File

@ -9,7 +9,7 @@ class Spinach::Features::ProjectIssuesLabels < Spinach::FeatureSteps
step 'I remove label \'bug\'' do
page.within "#label_#{bug_label.id}" do
click_link 'Remove'
click_link 'Delete'
end
end

View File

@ -63,7 +63,7 @@ class Spinach::Features::ProjectIssuesMilestones < Spinach::FeatureSteps
end
step 'I click link to remove milestone' do
click_link 'Remove'
click_link 'Delete'
end
step 'I should see no milestones' do

View File

@ -87,7 +87,7 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps
end
step 'I click link "Diff"' do
click_link 'Preview changes'
click_link 'Preview Changes'
end
step 'I click on "Commit Changes"' do
@ -192,7 +192,7 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps
end
step 'I see Browse dir link' do
expect(page).to have_link 'Browse Dir »'
expect(page).to have_link 'Browse Directory »'
expect(page).not_to have_link 'Browse Code »'
end
@ -204,13 +204,13 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps
step 'I see Browse file link' do
expect(page).to have_link 'Browse File »'
expect(page).not_to have_link 'Browse Code »'
expect(page).not_to have_link 'Browse Files »'
end
step 'I see Browse code link' do
expect(page).to have_link 'Browse Code »'
expect(page).to have_link 'Browse Files »'
expect(page).not_to have_link 'Browse File »'
expect(page).not_to have_link 'Browse Dir »'
expect(page).not_to have_link 'Browse Directory »'
end
step 'I click on Permalink' do

View File

@ -260,7 +260,7 @@ module Gitlab
end
def link_to_project(object)
if object && !object.projects.exists?(@project)
if object && !object.projects.exists?(@project.id)
object.projects << @project
object.save
end

View File

@ -0,0 +1,19 @@
require 'spec_helper'
describe Admin::ImpersonationController do
let(:admin) { create(:admin) }
before do
sign_in(admin)
end
describe 'CREATE #impersonation when blocked' do
let(:blocked_user) { create(:user, state: :blocked) }
it 'does not allow impersonation' do
post :create, id: blocked_user.username
expect(flash[:alert]).to eq 'You cannot impersonate a blocked user'
end
end
end

View File

@ -128,6 +128,16 @@ describe "Admin::Users", feature: true do
expect(page).not_to have_content('Impersonate')
end
it 'should not show impersonate button for blocked user' do
another_user.block
visit admin_user_path(another_user)
expect(page).not_to have_content('Impersonate')
another_user.activate
end
end
context 'when impersonating' do

View File

@ -247,7 +247,7 @@ describe Notify do
end
describe 'that have been reassigned' do
subject { Notify.reassigned_issue_email(recipient.id, issue.id, previous_assignee.id, current_user) }
subject { Notify.reassigned_issue_email(recipient.id, issue.id, previous_assignee.id, current_user.id) }
it_behaves_like 'a multiple recipients email'
it_behaves_like 'an answer to an existing thread', 'issue'
@ -278,7 +278,7 @@ describe Notify do
describe 'status changed' do
let(:status) { 'closed' }
subject { Notify.issue_status_changed_email(recipient.id, issue.id, status, current_user) }
subject { Notify.issue_status_changed_email(recipient.id, issue.id, status, current_user.id) }
it_behaves_like 'an answer to an existing thread', 'issue'
it_behaves_like 'it should show Gmail Actions View Issue link'
@ -382,7 +382,7 @@ describe Notify do
describe 'status changed' do
let(:status) { 'reopened' }
subject { Notify.merge_request_status_email(recipient.id, merge_request.id, status, current_user) }
subject { Notify.merge_request_status_email(recipient.id, merge_request.id, status, current_user.id) }
it_behaves_like 'an answer to an existing thread', 'merge_request'
it_behaves_like 'it should show Gmail Actions View Merge request link'
@ -597,8 +597,10 @@ describe Notify do
let(:user) { create(:user, email: 'old-email@mail.com') }
before do
user.email = "new-email@mail.com"
user.save
perform_enqueued_jobs do
user.email = "new-email@mail.com"
user.save
end
end
subject { ActionMailer::Base.deliveries.last }

View File

@ -444,7 +444,9 @@ describe Project do
before do
2.times do
create(:note_on_commit, project: project2, created_at: date)
# Little fix for special issue related to Fractional Seconds support for MySQL.
# See: https://github.com/rails/rails/pull/14359/files
create(:note_on_commit, project: project2, created_at: date + 1)
end
end