Commit 70c44a0d authored by Hannes Rosenögger's avatar Hannes Rosenögger

Fix tests, merge conflicts, some minor issues and make the project avatar feature mergable

parent 42bac7f9
...@@ -34,7 +34,7 @@ v 7.8.0 ...@@ -34,7 +34,7 @@ v 7.8.0
- -
- -
- -
- - Add Project Avatars (Steven Thonus and Hannes Rosenögger)
- -
- -
- Password reset token validity increased from 2 hours to 2 days since it is also send on account creation. - Password reset token validity increased from 2 hours to 2 days since it is also send on account creation.
......
...@@ -96,6 +96,7 @@ class Dispatcher ...@@ -96,6 +96,7 @@ class Dispatcher
new Profile() new Profile()
when 'projects' when 'projects'
new Project() new Project()
new ProjectAvatar()
switch path[1] switch path[1]
when 'edit' when 'edit'
shortcut_handler = new ShortcutsNavigation() shortcut_handler = new ShortcutsNavigation()
......
...@@ -18,13 +18,3 @@ class @Project ...@@ -18,13 +18,3 @@ class @Project
$.cookie('hide_no_ssh_message', 'false', { path: path }) $.cookie('hide_no_ssh_message', 'false', { path: path })
$(@).parents('.no-ssh-key-message').hide() $(@).parents('.no-ssh-key-message').hide()
e.preventDefault() e.preventDefault()
# avatar
$('.js-choose-project-avatar-button').bind "click", ->
form = $(this).closest("form")
form.find(".js-project-avatar-input").click()
$('.js-project-avatar-input').bind "change", ->
form = $(this).closest("form")
filename = $(this).val().replace(/^.*[\\\/]/, '')
form.find(".js-avatar-filename").text(filename)
class @ProjectAvatar
constructor: ->
$('.js-choose-project-avatar-button').bind 'click', ->
form = $(this).closest('form')
form.find('.js-project-avatar-input').click()
$('.js-project-avatar-input').bind 'change', ->
form = $(this).closest('form')
filename = $(this).val().replace(/^.*[\\\/]/, '')
form.find('.js-avatar-filename').text(filename)
...@@ -14,7 +14,7 @@ class ProjectsController < ApplicationController ...@@ -14,7 +14,7 @@ class ProjectsController < ApplicationController
end end
def edit def edit
render 'edit', layout: "project_settings" render 'edit', layout: 'project_settings'
end end
def create def create
...@@ -36,7 +36,7 @@ class ProjectsController < ApplicationController ...@@ -36,7 +36,7 @@ class ProjectsController < ApplicationController
format.html { redirect_to edit_project_path(@project), notice: 'Project was successfully updated.' } format.html { redirect_to edit_project_path(@project), notice: 'Project was successfully updated.' }
format.js format.js
else else
format.html { render "edit", layout: "project_settings" } format.html { render 'edit', layout: 'project_settings' }
format.js format.js
end end
end end
...@@ -66,17 +66,17 @@ class ProjectsController < ApplicationController ...@@ -66,17 +66,17 @@ class ProjectsController < ApplicationController
format.html do format.html do
if @project.repository_exists? if @project.repository_exists?
if @project.empty_repo? if @project.empty_repo?
render "projects/empty", layout: user_layout render 'projects/empty', layout: user_layout
else else
@last_push = current_user.recent_push(@project.id) if current_user @last_push = current_user.recent_push(@project.id) if current_user
render :show, layout: user_layout render :show, layout: user_layout
end end
else else
render "projects/no_repo", layout: user_layout render 'projects/no_repo', layout: user_layout
end end
end end
format.json { pager_json("events/_events", @events.count) } format.json { pager_json('events/_events', @events.count) }
end end
end end
...@@ -87,9 +87,9 @@ class ProjectsController < ApplicationController ...@@ -87,9 +87,9 @@ class ProjectsController < ApplicationController
respond_to do |format| respond_to do |format|
format.html do format.html do
flash[:alert] = "Project deleted." flash[:alert] = 'Project deleted.'
if request.referer.include?("/admin") if request.referer.include?('/admin')
redirect_to admin_projects_path redirect_to admin_projects_path
else else
redirect_to projects_dashboard_path redirect_to projects_dashboard_path
...@@ -141,7 +141,7 @@ class ProjectsController < ApplicationController ...@@ -141,7 +141,7 @@ class ProjectsController < ApplicationController
if link_to_image if link_to_image
format.json { render json: { link: link_to_image } } format.json { render json: { link: link_to_image } }
else else
format.json { render json: "Invalid file.", status: :unprocessable_entity } format.json { render json: 'Invalid file.', status: :unprocessable_entity }
end end
end end
end end
...@@ -172,14 +172,14 @@ class ProjectsController < ApplicationController ...@@ -172,14 +172,14 @@ class ProjectsController < ApplicationController
end end
def user_layout def user_layout
current_user ? "projects" : "public_projects" current_user ? 'projects' : 'public_projects'
end end
def project_params def project_params
params.require(:project).permit( params.require(:project).permit(
:name, :path, :description, :issues_tracker, :tag_list, :name, :path, :description, :issues_tracker, :tag_list,
:issues_enabled, :merge_requests_enabled, :snippets_enabled, :issues_tracker_id, :default_branch, :issues_enabled, :merge_requests_enabled, :snippets_enabled, :issues_tracker_id, :default_branch,
:wiki_enabled, :visibility_level, :import_url, :last_activity_at, :namespace_id :wiki_enabled, :visibility_level, :import_url, :last_activity_at, :namespace_id, :avatar
) )
end end
......
...@@ -54,10 +54,10 @@ module ApplicationHelper ...@@ -54,10 +54,10 @@ module ApplicationHelper
project = Project.find_with_namespace(project_id) project = Project.find_with_namespace(project_id)
if project.avatar.present? if project.avatar.present?
image_tag project.avatar.url, options image_tag project.avatar.url, options
elsif options[:only_uploaded]
image_tag '/assets/no_project_icon.png', options
elsif project.avatar_in_git elsif project.avatar_in_git
image_tag project_avatar_path(project), options image_tag project_avatar_path(project), options
elsif options[:only_uploaded]
image_tag '/assets/no_project_icon.png', options
else # generated icon else # generated icon
project_identicon(project, options) project_identicon(project, options)
end end
...@@ -107,24 +107,24 @@ module ApplicationHelper ...@@ -107,24 +107,24 @@ module ApplicationHelper
if project.repo_exists? if project.repo_exists?
time_ago_with_tooltip(project.repository.commit.committed_date) time_ago_with_tooltip(project.repository.commit.committed_date)
else else
"Never" 'Never'
end end
rescue rescue
"Never" 'Never'
end end
def grouped_options_refs def grouped_options_refs
repository = @project.repository repository = @project.repository
options = [ options = [
["Branches", repository.branch_names], ['Branches', repository.branch_names],
["Tags", VersionSorter.rsort(repository.tag_names)] ['Tags', VersionSorter.rsort(repository.tag_names)]
] ]
# If reference is commit id - we should add it to branch/tag selectbox # If reference is commit id - we should add it to branch/tag selectbox
if(@ref && !options.flatten.include?(@ref) && if(@ref && !options.flatten.include?(@ref) &&
@ref =~ /^[0-9a-zA-Z]{6,52}$/) @ref =~ /^[0-9a-zA-Z]{6,52}$/)
options << ["Commit", [@ref]] options << ['Commit', [@ref]]
end end
grouped_options_for_select(options, @ref || @project.default_branch) grouped_options_for_select(options, @ref || @project.default_branch)
...@@ -186,7 +186,7 @@ module ApplicationHelper ...@@ -186,7 +186,7 @@ module ApplicationHelper
path = controller.controller_path.split('/') path = controller.controller_path.split('/')
namespace = path.first if path.second namespace = path.first if path.second
[namespace, controller.controller_name, controller.action_name].compact.join(":") [namespace, controller.controller_name, controller.action_name].compact.join(':')
end end
# shortcut for gitlab config # shortcut for gitlab config
...@@ -201,13 +201,13 @@ module ApplicationHelper ...@@ -201,13 +201,13 @@ module ApplicationHelper
def search_placeholder def search_placeholder
if @project && @project.persisted? if @project && @project.persisted?
"Search in this project" 'Search in this project'
elsif @snippet || @snippets || @show_snippets elsif @snippet || @snippets || @show_snippets
'Search snippets' 'Search snippets'
elsif @group && @group.persisted? elsif @group && @group.persisted?
"Search in this group" 'Search in this group'
else else
"Search" 'Search'
end end
end end
...@@ -218,7 +218,7 @@ module ApplicationHelper ...@@ -218,7 +218,7 @@ module ApplicationHelper
def time_ago_with_tooltip(date, placement = 'top', html_class = 'time_ago') def time_ago_with_tooltip(date, placement = 'top', html_class = 'time_ago')
capture_haml do capture_haml do
haml_tag :time, date.to_s, haml_tag :time, date.to_s,
class: html_class, datetime: date.getutc.iso8601, title: date.stamp("Aug 21, 2011 9:23pm"), class: html_class, datetime: date.getutc.iso8601, title: date.stamp('Aug 21, 2011 9:23pm'),
data: { toggle: 'tooltip', placement: placement } data: { toggle: 'tooltip', placement: placement }
haml_tag :script, "$('." + html_class + "').timeago().tooltip()" haml_tag :script, "$('." + html_class + "').timeago().tooltip()"
...@@ -241,8 +241,8 @@ module ApplicationHelper ...@@ -241,8 +241,8 @@ module ApplicationHelper
end end
def spinner(text = nil, visible = false) def spinner(text = nil, visible = false)
css_class = "loading" css_class = 'loading'
css_class << " hide" unless visible css_class << ' hide' unless visible
content_tag :div, class: css_class do content_tag :div, class: css_class do
content_tag(:i, nil, class: 'fa fa-spinner fa-spin') + text content_tag(:i, nil, class: 'fa fa-spinner fa-spin') + text
...@@ -259,17 +259,17 @@ module ApplicationHelper ...@@ -259,17 +259,17 @@ module ApplicationHelper
absolute_uri = nil absolute_uri = nil
end end
# Add "nofollow" only to external links # Add 'nofollow' only to external links
if host && host != Gitlab.config.gitlab.host && absolute_uri if host && host != Gitlab.config.gitlab.host && absolute_uri
if html_options if html_options
if html_options[:rel] if html_options[:rel]
html_options[:rel] << " nofollow" html_options[:rel] << ' nofollow'
else else
html_options.merge!(rel: "nofollow") html_options.merge!(rel: 'nofollow')
end end
else else
html_options = Hash.new html_options = Hash.new
html_options[:rel] = "nofollow" html_options[:rel] = 'nofollow'
end end
end end
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
# merge_requests_enabled :boolean default(TRUE), not null # merge_requests_enabled :boolean default(TRUE), not null
# wiki_enabled :boolean default(TRUE), not null # wiki_enabled :boolean default(TRUE), not null
# namespace_id :integer # namespace_id :integer
# issues_tracker :string(255) default("gitlab"), not null # issues_tracker :string(255) default('gitlab'), not null
# issues_tracker_id :string(255) # issues_tracker_id :string(255)
# snippets_enabled :boolean default(TRUE), not null # snippets_enabled :boolean default(TRUE), not null
# last_activity_at :datetime # last_activity_at :datetime
...@@ -29,6 +29,9 @@ ...@@ -29,6 +29,9 @@
# avatar :string(255) # avatar :string(255)
# #
require 'carrierwave/orm/activerecord'
require 'file_size_validator'
class Project < ActiveRecord::Base class Project < ActiveRecord::Base
include Gitlab::ShellAdapter include Gitlab::ShellAdapter
include Gitlab::VisibilityLevel include Gitlab::VisibilityLevel
...@@ -50,8 +53,8 @@ class Project < ActiveRecord::Base ...@@ -50,8 +53,8 @@ class Project < ActiveRecord::Base
attr_accessor :new_default_branch attr_accessor :new_default_branch
# Relations # Relations
belongs_to :creator, foreign_key: "creator_id", class_name: "User" belongs_to :creator, foreign_key: 'creator_id', class_name: 'User'
belongs_to :group, -> { where(type: Group) }, foreign_key: "namespace_id" belongs_to :group, -> { where(type: Group) }, foreign_key: 'namespace_id'
belongs_to :namespace belongs_to :namespace
has_one :last_event, -> {order 'events.created_at DESC'}, class_name: 'Event', foreign_key: 'project_id' has_one :last_event, -> {order 'events.created_at DESC'}, class_name: 'Event', foreign_key: 'project_id'
...@@ -71,20 +74,20 @@ class Project < ActiveRecord::Base ...@@ -71,20 +74,20 @@ class Project < ActiveRecord::Base
has_one :bamboo_service, dependent: :destroy has_one :bamboo_service, dependent: :destroy
has_one :teamcity_service, dependent: :destroy has_one :teamcity_service, dependent: :destroy
has_one :pushover_service, dependent: :destroy has_one :pushover_service, dependent: :destroy
has_one :forked_project_link, dependent: :destroy, foreign_key: "forked_to_project_id" has_one :forked_project_link, dependent: :destroy, foreign_key: 'forked_to_project_id'
has_one :forked_from_project, through: :forked_project_link has_one :forked_from_project, through: :forked_project_link
# Merge Requests for target project should be removed with it # Merge Requests for target project should be removed with it
has_many :merge_requests, dependent: :destroy, foreign_key: "target_project_id" has_many :merge_requests, dependent: :destroy, foreign_key: 'target_project_id'
# Merge requests from source project should be kept when source project was removed # Merge requests from source project should be kept when source project was removed
has_many :fork_merge_requests, foreign_key: "source_project_id", class_name: MergeRequest has_many :fork_merge_requests, foreign_key: 'source_project_id', class_name: MergeRequest
has_many :issues, -> { order 'issues.state DESC, issues.created_at DESC' }, dependent: :destroy has_many :issues, -> { order 'issues.state DESC, issues.created_at DESC' }, dependent: :destroy
has_many :labels, dependent: :destroy has_many :labels, dependent: :destroy
has_many :services, dependent: :destroy has_many :services, dependent: :destroy
has_many :events, dependent: :destroy has_many :events, dependent: :destroy
has_many :milestones, dependent: :destroy has_many :milestones, dependent: :destroy
has_many :notes, dependent: :destroy has_many :notes, dependent: :destroy
has_many :snippets, dependent: :destroy, class_name: "ProjectSnippet" has_many :snippets, dependent: :destroy, class_name: 'ProjectSnippet'
has_many :hooks, dependent: :destroy, class_name: "ProjectHook" has_many :hooks, dependent: :destroy, class_name: 'ProjectHook'
has_many :protected_branches, dependent: :destroy has_many :protected_branches, dependent: :destroy
has_many :project_members, dependent: :destroy, as: :source, class_name: 'ProjectMember' has_many :project_members, dependent: :destroy, as: :source, class_name: 'ProjectMember'
has_many :users, through: :project_members has_many :users, through: :project_members
...@@ -116,27 +119,27 @@ class Project < ActiveRecord::Base ...@@ -116,27 +119,27 @@ class Project < ActiveRecord::Base
validates_uniqueness_of :name, scope: :namespace_id validates_uniqueness_of :name, scope: :namespace_id
validates_uniqueness_of :path, scope: :namespace_id validates_uniqueness_of :path, scope: :namespace_id
validates :import_url, validates :import_url,
format: { with: URI::regexp(%w(git http https)), message: "should be a valid url" }, format: { with: URI::regexp(%w(git http https)), message: 'should be a valid url' },
if: :import? if: :import?
validates :star_count, numericality: { greater_than_or_equal_to: 0 } validates :star_count, numericality: { greater_than_or_equal_to: 0 }
validate :check_limit, on: :create validate :check_limit, on: :create
validate :avatar_type, validate :avatar_type,
if: ->(project) { project.avatar && project.avatar_changed? } if: ->(project) { project.avatar && project.avatar_changed? }
validates :avatar, file_size: { maximum: 100.kilobytes.to_i } validates :avatar, file_size: { maximum: 200.kilobytes.to_i }
mount_uploader :avatar, AttachmentUploader mount_uploader :avatar, AttachmentUploader
# Scopes # Scopes
scope :without_user, ->(user) { where("projects.id NOT IN (:ids)", ids: user.authorized_projects.map(&:id) ) } scope :without_user, ->(user) { where('projects.id NOT IN (:ids)', ids: user.authorized_projects.map(&:id) ) }
scope :without_team, ->(team) { team.projects.present? ? where("projects.id NOT IN (:ids)", ids: team.projects.map(&:id)) : scoped } scope :without_team, ->(team) { team.projects.present? ? where('projects.id NOT IN (:ids)', ids: team.projects.map(&:id)) : scoped }
scope :not_in_group, ->(group) { where("projects.id NOT IN (:ids)", ids: group.project_ids ) } scope :not_in_group, ->(group) { where('projects.id NOT IN (:ids)', ids: group.project_ids ) }
scope :in_team, ->(team) { where("projects.id IN (:ids)", ids: team.projects.map(&:id)) } scope :in_team, ->(team) { where('projects.id IN (:ids)', ids: team.projects.map(&:id)) }
scope :in_namespace, ->(namespace) { where(namespace_id: namespace.id) } scope :in_namespace, ->(namespace) { where(namespace_id: namespace.id) }
scope :in_group_namespace, -> { joins(:group) } scope :in_group_namespace, -> { joins(:group) }
scope :sorted_by_activity, -> { reorder("projects.last_activity_at DESC") } scope :sorted_by_activity, -> { reorder('projects.last_activity_at DESC') }
scope :sorted_by_stars, -> { reorder("projects.star_count DESC") } scope :sorted_by_stars, -> { reorder('projects.star_count DESC') }
scope :personal, ->(user) { where(namespace_id: user.namespace_id) } scope :personal, ->(user) { where(namespace_id: user.namespace_id) }
scope :joined, ->(user) { where("namespace_id != ?", user.namespace_id) } scope :joined, ->(user) { where('namespace_id != ?', user.namespace_id) }
scope :public_only, -> { where(visibility_level: Project::PUBLIC) } scope :public_only, -> { where(visibility_level: Project::PUBLIC) }
scope :public_and_internal_only, -> { where(visibility_level: Project.public_and_internal_levels) } scope :public_and_internal_only, -> { where(visibility_level: Project.public_and_internal_levels) }
scope :non_archived, -> { where(archived: false) } scope :non_archived, -> { where(archived: false) }
...@@ -187,26 +190,26 @@ class Project < ActiveRecord::Base ...@@ -187,26 +190,26 @@ class Project < ActiveRecord::Base
end end
def active def active
joins(:issues, :notes, :merge_requests).order("issues.created_at, notes.created_at, merge_requests.created_at DESC") joins(:issues, :notes, :merge_requests).order('issues.created_at, notes.created_at, merge_requests.created_at DESC')
end end
def search(query) def search(query)
joins(:namespace).where("projects.archived = ?", false). joins(:namespace).where('projects.archived = ?', false).
where("LOWER(projects.name) LIKE :query OR where('LOWER(projects.name) LIKE :query OR
LOWER(projects.path) LIKE :query OR LOWER(projects.path) LIKE :query OR
LOWER(namespaces.name) LIKE :query OR LOWER(namespaces.name) LIKE :query OR
LOWER(projects.description) LIKE :query", LOWER(projects.description) LIKE :query',
query: "%#{query.try(:downcase)}%") query: "%#{query.try(:downcase)}%")
end end
def search_by_title(query) def search_by_title(query)
where("projects.archived = ?", false).where("LOWER(projects.name) LIKE :query", query: "%#{query.downcase}%") where('projects.archived = ?', false).where('LOWER(projects.name) LIKE :query', query: "%#{query.downcase}%")
end end
def find_with_namespace(id) def find_with_namespace(id)
return nil unless id.include?("/") return nil unless id.include?('/')
id = id.split("/") id = id.split('/')
namespace = Namespace.find_by(path: id.first) namespace = Namespace.find_by(path: id.first)
return nil unless namespace return nil unless namespace
...@@ -224,7 +227,7 @@ class Project < ActiveRecord::Base ...@@ -224,7 +227,7 @@ class Project < ActiveRecord::Base
when 'recently_updated' then reorder('projects.updated_at DESC') when 'recently_updated' then reorder('projects.updated_at DESC')
when 'last_updated' then reorder('projects.updated_at ASC') when 'last_updated' then reorder('projects.updated_at ASC')
when 'largest_repository' then reorder('projects.repository_size DESC') when 'largest_repository' then reorder('projects.repository_size DESC')
else reorder("namespaces.path, projects.name ASC") else reorder('namespaces.path, projects.name ASC')
end end
end end
end end
...@@ -274,19 +277,19 @@ class Project < ActiveRecord::Base ...@@ -274,19 +277,19 @@ class Project < ActiveRecord::Base
end end
def to_param def to_param
namespace.path + "/" + path namespace.path + '/' + path
end end
def web_url def web_url
[gitlab_config.url, path_with_namespace].join("/") [gitlab_config.url, path_with_namespace].join('/')
end end
def web_url_without_protocol def web_url_without_protocol
web_url.split("://")[1] web_url.split('://')[1]
end end
def build_commit_note(commit) def build_commit_note(commit)
notes.new(commit_id: commit.id, noteable_type: "Commit") notes.new(commit_id: commit.id, noteable_type: 'Commit')
end end
def last_activity def last_activity
...@@ -345,8 +348,8 @@ class Project < ActiveRecord::Base ...@@ -345,8 +348,8 @@ class Project < ActiveRecord::Base
end end
def avatar_type def avatar_type
unless avatar.image? unless self.avatar.image?
errors.add :avatar, 'only images allowed' self.errors.add :avatar, 'only images allowed'
end end
end end
...@@ -384,7 +387,7 @@ class Project < ActiveRecord::Base ...@@ -384,7 +387,7 @@ class Project < ActiveRecord::Base
end end
def team_member_by_name_or_email(name = nil, email = nil) def team_member_by_name_or_email(name = nil, email = nil)
user = users.where("name like ? or email like ?", name, email).first user = users.where('name like ? or email like ?', name, email).first
project_members.where(user: user) if user project_members.where(user: user) if user
end end
...@@ -396,7 +399,7 @@ class Project < ActiveRecord::Base ...@@ -396,7 +399,7 @@ class Project < ActiveRecord::Base
def name_with_namespace def name_with_namespace
@name_with_namespace ||= begin @name_with_namespace ||= begin
if namespace if namespace
namespace.human_name + " / " + name namespace.human_name + ' / ' + name
else else
name name
end end
...@@ -431,7 +434,7 @@ class Project < ActiveRecord::Base ...@@ -431,7 +434,7 @@ class Project < ActiveRecord::Base
def valid_repo? def valid_repo?
repository.exists? repository.exists?
rescue rescue
errors.add(:path, "Invalid repository path") errors.add(:path, 'Invalid repository path')
false false
end end
...@@ -490,7 +493,7 @@ class Project < ActiveRecord::Base ...@@ -490,7 +493,7 @@ class Project < ActiveRecord::Base
end end
def http_url_to_repo def http_url_to_repo
[gitlab_config.url, "/", path_with_namespace, ".git"].join('') [gitlab_config.url, '/', path_with_namespace, '.git'].join('')
end end
# Check if current branch name is marked as protected in the system # Check if current branch name is marked as protected in the system
...@@ -618,7 +621,7 @@ class Project < ActiveRecord::Base ...@@ -618,7 +621,7 @@ class Project < ActiveRecord::Base
if gitlab_shell.add_repository(path_with_namespace) if gitlab_shell.add_repository(path_with_namespace)
true true
else else
errors.add(:base, "Failed to create repository") errors.add(:base, 'Failed to create repository')
false false
end end
end end
...@@ -631,7 +634,7 @@ class Project < ActiveRecord::Base ...@@ -631,7 +634,7 @@ class Project < ActiveRecord::Base
ProjectWiki.new(self, self.owner).wiki ProjectWiki.new(self, self.owner).wiki
true true
rescue ProjectWiki::CouldNotCreateWikiError => ex rescue ProjectWiki::CouldNotCreateWikiError => ex
errors.add(:base, "Failed create wiki") errors.add(:base, 'Failed create wiki')
false false
end end
end end
...@@ -14,7 +14,7 @@ module Projects ...@@ -14,7 +14,7 @@ module Projects
project.name = @from_project.name project.name = @from_project.name
project.path = @from_project.path project.path = @from_project.path
project.creator = @current_user project.creator = @current_user
if @from_project.avatar && @from_project.avatar.image? if @from_project.avatar.present? && @from_project.avatar.image?
project.avatar = @from_project.avatar project.avatar = @from_project.avatar
end end
...@@ -42,16 +42,16 @@ module Projects ...@@ -42,16 +42,16 @@ module Projects
end end
#Now fork the repo #Now fork the repo
unless gitlab_shell.fork_repository(@from_project.path_with_namespace, project.namespace.path) unless gitlab_shell.fork_repository(@from_project.path_with_namespace, project.namespace.path)
raise "forking failed in gitlab-shell" raise 'forking failed in gitlab-shell'
end end
project.ensure_satellite_exists project.ensure_satellite_exists
end end
rescue => ex rescue => ex
project.errors.add(:base, "Fork transaction failed.") project.errors.add(:base, 'Fork transaction failed.')
project.destroy project.destroy
end end
else else
project.errors.add(:base, "Invalid fork destination") project.errors.add(:base, 'Invalid fork destination')
end end
project project
......
...@@ -12,6 +12,8 @@ ...@@ -12,6 +12,8 @@
- projects.each do |project| - projects.each do |project|
%li.project-row %li.project-row
= link_to project_path(project), class: dom_class(project) do = link_to project_path(project), class: dom_class(project) do
.dash-project-avatar
= project_icon(project.to_param, alt: '', class: 'avatar s24')
.dash-project-access-icon .dash-project-access-icon
= visibility_level_icon(project.visibility_level) = visibility_level_icon(project.visibility_level)
%span.str-truncated %span.str-truncated
......
...@@ -87,7 +87,10 @@ ...@@ -87,7 +87,10 @@
.form-group .form-group
.col-sm-2 .col-sm-2
.col-sm-10 .col-sm-10
= project_icon(@project.to_param, alt: '', class: 'avatar s160', only_uploaded: true) - if @project.avatar?
= project_icon(@project.to_param, alt: '', class: 'avatar s160')
- else
= project_icon(@project.to_param, alt: '', class: 'avatar s160', only_uploaded: true)
%p.light %p.light
- if @project.avatar_in_git - if @project.avatar_in_git
Project avatar in repository: #{ @project.avatar_in_git } Project avatar in repository: #{ @project.avatar_in_git }
...@@ -102,7 +105,7 @@ ...@@ -102,7 +105,7 @@
&nbsp; &nbsp;
%span.file_name.js-avatar-filename File name... %span.file_name.js-avatar-filename File name...
= f.file_field :avatar, class: "js-project-avatar-input hidden" = f.file_field :avatar, class: "js-project-avatar-input hidden"
.light The maximum file size allowed is 100KB. .light The maximum file size allowed is 200KB.
- if @project.avatar? - if @project.avatar?
%hr %hr
= link_to 'Remove avatar', project_avatar_path(@project), data: { confirm: "Project avatar will be removed. Are you sure?"}, method: :delete, class: "btn btn-remove btn-small remove-avatar" = link_to 'Remove avatar', project_avatar_path(@project), data: { confirm: "Project avatar will be removed. Are you sure?"}, method: :delete, class: "btn btn-remove btn-small remove-avatar"
......
...@@ -10,8 +10,8 @@ Gitlab::Application.routes.draw do ...@@ -10,8 +10,8 @@ Gitlab::Application.routes.draw do
# #
# Search # Search
# #
get 'search' => "search#show" get 'search' => 'search#show'
get 'search/autocomplete' => "search#autocomplete", as: :search_autocomplete get 'search/autocomplete' => 'search#autocomplete', as: :search_autocomplete
# API # API
API::API.logger Rails.logger API::API.logger Rails.logger
...@@ -20,9 +20,9 @@ Gitlab::Application.routes.draw do ...@@ -20,9 +20,9 @@ Gitlab::Application.routes.draw do
# Get all keys of user # Get all keys of user
get ':username.keys' => 'profiles/keys#get_keys' , constraints: { username: /.*/ } get ':username.keys' => 'profiles/keys#get_keys' , constraints: { username: /.*/ }
constraint = lambda { |request| request.env["warden"].authenticate? and request.env['warden'].user.admin? } constraint = lambda { |request| request.env['warden'].authenticate? and request.env['warden'].user.admin? }
constraints constraint do constraints constraint do
mount Sidekiq::Web, at: "/admin/sidekiq", as: :sidekiq mount Sidekiq::Web, at: '/admin/sidekiq', as: :sidekiq
end end
# Enable Grack support # Enable Grack support
...@@ -46,10 +46,10 @@ Gitlab::Application.routes.draw do ...@@ -46,10 +46,10 @@ Gitlab::Application.routes.draw do
# #
resources :snippets do resources :snippets do
member do member do
get "raw" get 'raw'
end end
end end
get "/s/:username" => "snippets#user_index", as: :user_snippets, constraints: { username: /.*/ } get '/s/:username' => 'snippets#user_index', as: :user_snippets, constraints: { username: /.*/ }
# #
# Github importer area # Github importer area
...@@ -72,12 +72,12 @@ Gitlab::Application.routes.draw do ...@@ -72,12 +72,12 @@ Gitlab::Application.routes.draw do
end end
resources :groups, only: [:index] resources :groups, only: [:index]
root to: "projects#trending" root to: 'projects#trending'
end end
# Compatibility with old routing # Compatibility with old routing
get 'public' => "explore/projects#index" get 'public' => 'explore/projects#index'
get 'public/projects' => "explore/projects#index" get 'public/projects' => 'explore/projects#index'
# #
# Attachments serving # Attachments serving
...@@ -122,7 +122,7 @@ Gitlab::Application.routes.draw do ...@@ -122,7 +122,7 @@ Gitlab::Application.routes.draw do
resource :application_settings, only: [:show, :update] resource :application_settings, only: [:show, :update]
root to: "dashboard#index" root to: 'dashboard#index'
end end
# #
...@@ -163,7 +163,7 @@ Gitlab::Application.routes.draw do ...@@ -163,7 +163,7 @@ Gitlab::Application.routes.draw do
# #
# Dashboard Area # Dashboard Area
# #
resource :dashboard, controller: "dashboard", only: [:show] do resource :dashboard, controller: 'dashboard', only: [:show] do
member do member do
get :projects get :projects
get :issues get :issues
...@@ -194,12 +194,12 @@ Gitlab::Application.routes.draw do ...@@ -194,12 +194,12 @@ Gitlab::Application.routes.draw do
devise_for :users, controllers: { omniauth_callbacks: :omniauth_callbacks, registrations: :registrations , passwords: :passwords, sessions: :sessions, confirmations: :confirmations } devise_for :users, controllers: { omniauth_callbacks: :omniauth_callbacks, registrations: :registrations , passwords: :passwords, sessions: :sessions, confirmations: :confirmations }
devise_scope :user do devise_scope :user do
get "/users/auth/:provider/omniauth_error" => "omniauth_callbacks#omniauth_error", as: :omniauth_error get '/users/auth/:provider/omniauth_error' => 'omniauth_callbacks#omniauth_error', as: :omniauth_error
end end
# #
# Project Area # Project Area
# #
resources :projects, constraints: { id: /[a-zA-Z.0-9_\-]+\/[a-zA-Z.0-9_\-]+/ }, except: [:new, :create, :index], path: "/" do resources :projects, constraints: { id: /[a-zA-Z.0-9_\-]+\/[a-zA-Z.0-9_\-]+/ }, except: [:new, :create, :index], path: '/' do
member do member do
put :transfer put :transfer
post :archive post :archive
...@@ -220,6 +220,7 @@ Gitlab::Application.routes.draw do ...@@ -220,6 +220,7 @@ Gitlab::Application.routes.draw do
# Cannot be GET to differentiate from GET paths that end in preview. # Cannot be GET to differentiate from GET paths that end in preview.
post :preview, on: :member post :preview, on: :member
end end
resource :avatar, only: [:show, :destroy]
resources :new_tree, only: [:show, :update], constraints: {id: /.+/}, path: 'new' resources :new_tree, only: [:show, :update], constraints: {id: /.+/}, path: 'new'
resources :commit, only: [:show], constraints: {id: /[[:alnum:]]{6,40}/} resources :commit, only: [:show], constraints: {id: /[[:alnum:]]{6,40}/}
resources :commits, only: [:show], constraints: {id: /(?:[^.]|\.(?!atom$))+/, format: /atom/} resources :commits, only: [:show], constraints: {id: /(?:[^.]|\.(?!atom$))+/, format: /atom/}
...@@ -237,7 +238,7 @@ Gitlab::Application.routes.draw do ...@@ -237,7 +238,7 @@ Gitlab::Application.routes.draw do
resources :snippets, constraints: {id: /\d+/} do resources :snippets, constraints: {id: /\d+/} do
member do member do
get "raw" get 'raw'
end end
end end
...@@ -249,7 +250,7 @@ Gitlab::Application.routes.draw do ...@@ -249,7 +250,7 @@ Gitlab::Application.routes.draw do
end end
member do member do
get "history" get 'history'
end end
end end
...@@ -258,7 +259,7 @@ Gitlab::Application.routes.draw do ...@@ -258,7 +259,7 @@ Gitlab::Application.routes.draw do
resource :repository, only: [:show, :create] do resource :repository, only: [:show, :create] do
member do member do
get "archive", constraints: { format: Gitlab::Regex.archive_formats_regex } get 'archive', constraints: { format: Gitlab::Regex.archive_formats_regex }
end end
end end
...@@ -281,13 +282,13 @@ Gitlab::Application.routes.draw do ...@@ -281,13 +282,13 @@ Gitlab::Application.routes.draw do
resources :refs, only: [] do resources :refs, only: [] do
collection do collection do
get "switch" get 'switch'
end end
member do member do
# tree viewer logs # tree viewer logs
get "logs_tree", constraints: { id: Gitlab::Regex.git_reference_regex } get 'logs_tree', constraints: { id: Gitlab::Regex.git_reference_regex }
get "logs_tree/:path" => "refs#logs_tree", get 'logs_tree/:path' => 'refs#logs_tree',
as: :logs_file, as: :logs_file,
constraints: { constraints: {
id: Gitlab::Regex.git_reference_regex, id: Gitlab::Regex.git_reference_regex,
...@@ -354,11 +355,10 @@ Gitlab::Application.routes.draw do ...@@ -354,11 +355,10 @@ Gitlab::Application.routes.draw do
end end
end end
resource :avatar, only: [:show, :destroy]
end end
end end
get ':id' => "namespaces#show", constraints: {id: /(?:[^.]|\.(?!atom$))+/, format: /atom/} get ':id' => 'namespaces#show', constraints: {id: /(?:[^.]|\.(?!atom$))+/, format: /atom/}
root to: "dashboard#show" root to: 'dashboard#show'
end end
...@@ -68,7 +68,7 @@ class Spinach::Features::Project < Spinach::FeatureSteps ...@@ -68,7 +68,7 @@ class Spinach::Features::Project < Spinach::FeatureSteps
step 'I should see project "Shop" version' do step 'I should see project "Shop" version' do
within '.project-side' do within '.project-side' do
page.should have_content "Version: 6.7.0.pre" page.should have_content 'Version: 6.7.0.pre'
end end
end end
...@@ -86,12 +86,12 @@ class Spinach::Features::Project < Spinach::FeatureSteps ...@@ -86,12 +86,12 @@ class Spinach::Features::Project < Spinach::FeatureSteps
end end
step 'I should see project "Forum" README' do step 'I should see project "Forum" README' do
page.should have_link "README.md" page.should have_link 'README.md'
page.should have_content "Sample repo for testing gitlab features" page.should have_content 'Sample repo for testing gitlab features'
end end
step 'I should see project "Shop" README' do step 'I should see project "Shop" README' do
page.should have_link "README.md" page.should have_link 'README.md'
page.should have_content "testme" page.should have_content 'testme'
end end
end end
This diff is collapsed.
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
# merge_requests_enabled :boolean default(TRUE), not null # merge_requests_enabled :boolean default(TRUE), not null
# wiki_enabled :boolean default(TRUE), not null # wiki_enabled :boolean default(TRUE), not null
# namespace_id :integer # namespace_id :integer
# issues_tracker :string(255) default("gitlab"), not null # issues_tracker :string(255) default('gitlab'), not null
# issues_tracker_id :string(255) # issues_tracker_id :string(255)
# snippets_enabled :boolean default(TRUE), not null # snippets_enabled :boolean default(TRUE), not null
# last_activity_at :datetime # last_activity_at :datetime
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
require 'spec_helper' require 'spec_helper'
describe Project do describe Project do
describe "Associations" do describe 'Associations' do
it { should belong_to(:group) } it { should belong_to(:group) }
it { should belong_to(:namespace) } it { should belong_to(:namespace) }
it { should belong_to(:creator).class_name('User') } it { should belong_to(:creator).class_name('User') }
...@@ -53,10 +53,10 @@ describe Project do ...@@ -53,10 +53,10 @@ describe Project do
it { should have_one(:pushover_service).dependent(:destroy) } it { should have_one(:pushover_service).dependent(:destroy) }
end end
describe "Mass assignment" do describe 'Mass assignment' do
end end
describe "Validation" do describe 'Validation' do
let!(:project) { create(:project) } let!(:project) { create(:project) }
it { should validate_presence_of(:name) } it { should validate_presence_of(:name) }
...@@ -71,7 +71,7 @@ describe Project do ...@@ -71,7 +71,7 @@ describe Project do
it { should ensure_length_of(:issues_tracker_id).is_within(0..255) } it { should ensure_length_of(:issues_tracker_id).is_within(0..255) }
it { should validate_presence_of(:namespace) } it { should validate_presence_of(:namespace) }
it "should not allow new projects beyond user limits" do it 'should not allow new projects beyond user limits' do
project2 = build(:project) project2 = build(:project)
project2.stub(:creator).and_return(double(can_create_project?: false, projects_limit: 0).as_null_object) project2.stub(:creator).and_return(double(can_create_project?: false, projects_limit: 0).as_null_object)
project2.should_not be_valid project2.should_not be_valid
...@@ -79,7 +79,7 @@ describe Project do ...@@ -79,7 +79,7 @@ describe Project do
end end
end end
describe "Respond to" do describe 'Respond to' do
it { should respond_to(:url_to_repo) } it { should respond_to(:url_to_repo) }
it { should respond_to(:repo_exists?) } it { should respond_to(:repo_exists?) }
it { should respond_to(:satellite) } it { should respond_to(:satellite) }
...@@ -90,27 +90,27 @@ describe Project do ...@@ -90,27 +90,27 @@ describe Project do
it { should respond_to(:path_with_namespace) } it { should respond_to(:path_with_namespace) }
end end
it "should return valid url to repo" do it 'should return valid url to repo' do
project = Project.new(path: "somewhere") project = Project.new(path: 'somewhere')
project.url_to_repo.should == Gitlab.config.gitlab_shell.ssh_path_prefix + "somewhere.git" project.url_to_repo.should == Gitlab.config.gitlab_shell.ssh_path_prefix + 'somewhere.git'
end end
it "returns the full web URL for this repo" do it 'returns the full web URL for this repo' do
project = Project.new(path: "somewhere") project = Project.new(path: 'somewhere')
project.web_url.should == "#{Gitlab.config.gitlab.url}/somewhere" project.web_url.should == "#{Gitlab.config.gitlab.url}/somewhere"
end end
it "returns the web URL without the protocol for this repo" do it 'returns the web URL without the protocol for this repo' do
project = Project.new(path: "somewhere") project = Project.new(path: 'somewhere')
project.web_url_without_protocol.should == "#{Gitlab.config.gitlab.url.split("://")[1]}/somewhere" project.web_url_without_protocol.should == "#{Gitlab.config.gitlab.url.split('://')[1]}/somewhere"
end end
describe "last_activity methods" do describe 'last_activity methods' do
let(:project) { create(:project) } let(:project) { create(:project) }
let(:last_event) { double(created_at: Time.now) } let(:last_event) { double(created_at: Time.now) }
describe "last_activity" do describe 'last_activity' do
it "should alias last_activity to last_event" do it 'should alias last_activity to last_event' do
project.stub(last_event: last_event) project.stub(last_event: last_event)
project.last_activity.should == last_event project.last_activity.should == last_event
end end
...@@ -135,13 +135,13 @@ describe Project do ...@@ -135,13 +135,13 @@ describe Project do
let(:prev_commit_id) { merge_request.commits.last.id } let(:prev_commit_id) { merge_request.commits.last.id }
let(:commit_id) { merge_request.commits.first.id } let(:commit_id) { merge_request.commits.first.id }
it "should close merge request if last commit from source branch was pushed to target branch" do it 'should close merge request if last commit from source branch was pushed to target branch' do
project.update_merge_requests(prev_commit_id, commit_id, "refs/heads/#{merge_request.target_branch}", key.user) project.update_merge_requests(prev_commit_id, commit_id, "refs/heads/#{merge_request.target_branch}", key.user)
merge_request.reload merge_request.reload
merge_request.merged?.should be_true merge_request.merged?.should be_true
end end
it "should update merge request commits with new one if pushed to source branch" do it 'should update merge request commits with new one if pushed to source branch' do
project.update_merge_requests(prev_commit_id, commit_id, "refs/heads/#{merge_request.source_branch}", key.user) project.update_merge_requests(prev_commit_id, commit_id, "refs/heads/#{merge_request.source_branch}", key.user)
merge_request.reload merge_request.reload
merge_request.last_commit.id.should == commit_id merge_request.last_commit.id.should == commit_id
...@@ -167,14 +167,14 @@ describe Project do ...@@ -167,14 +167,14 @@ describe Project do
@project = create(:project, name: 'gitlabhq', namespace: @group) @project = create(:project, name: 'gitlabhq', namespace: @group)
end end
it { @project.to_param.should == "gitlab/gitlabhq" } it { @project.to_param.should == 'gitlab/gitlabhq' }
end end
end end
describe :repository do describe :repository do
let(:project) { create(:project) } let(:project) { create(:project) }
it "should return valid repo" do it 'should return valid repo' do
project.repository.should be_kind_of(Repository) project.repository.should be_kind_of(Repository)
end end
end end
...@@ -185,15 +185,15 @@ describe Project do ...@@ -185,15 +185,15 @@ describe Project do
let(:not_existed_issue) { create(:issue) } let(:not_existed_issue) { create(:issue) }
let(:ext_project) { create(:redmine_project) } let(:ext_project) { create(:redmine_project) }
it "should be true or if used internal tracker and issue exists" do it 'should be true or if used internal tracker and issue exists' do
project.issue_exists?(existed_issue.iid).should be_true project.issue_exists?(existed_issue.iid).should be_true
end end
it "should be false or if used internal tracker and issue not exists" do it 'should be false or if used internal tracker and issue not exists' do
project.issue_exists?(not_existed_issue.iid).should be_false project.issue_exists?(not_existed_issue.iid).should be_false
end end
it "should always be true if used other tracker" do it 'should always be true if used other tracker' do
ext_project.issue_exists?(rand(100)).should be_true ext_project.issue_exists?(rand(100)).should be_true
end end
end end
...@@ -202,11 +202,11 @@ describe Project do ...@@ -202,11 +202,11 @@ describe Project do
let(:project) { create(:project) } let(:project) { create(:project) }
let(:ext_project) { create(:redmine_project) } let(:ext_project) { create(:redmine_project) }
it "should be true if used internal tracker" do it 'should be true if used internal tracker' do
project.used_default_issues_tracker?.should be_true project.used_default_issues_tracker?.should be_true
end end
it "should be false if used other tracker" do it 'should be false if used other tracker' do
ext_project.used_default_issues_tracker?.should be_false ext_project.used_default_issues_tracker?.should be_false
end end
end end
...@@ -215,15 +215,15 @@ describe Project do ...@@ -215,15 +215,15 @@ describe Project do
let(:project) { create(:project) } let(:project) { create(:project) }
let(:ext_project) { create(:redmine_project) } let(:ext_project) { create(:redmine_project) }
it "should be true for projects with external issues tracker if issues enabled" do it 'should be true for projects with external issues tracker if issues enabled' do
ext_project.can_have_issues_tracker_id?.should be_true ext_project.can_have_issues_tracker_id?.should be_true
end end
it "should be false for projects with internal issue tracker if issues enabled" do it 'should be false for projects with internal issue tracker if issues enabled' do
project.can_have_issues_tracker_id?.should be_false project.can_have_issues_tracker_id?.should be_false
end end
it "should be always false if issues disabled" do it 'should be always false if issues disabled' do
project.issues_enabled = false project.issues_enabled = false
ext_project.issues_enabled = false ext_project.issues_enabled = false
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment