2012-11-19 18:24:05 +00:00
# == Schema Information
#
# Table name: projects
#
# id :integer not null, primary key
# name :string(255)
# path :string(255)
# description :text
2014-04-09 12:05:03 +00:00
# created_at :datetime
# updated_at :datetime
2013-01-03 19:09:18 +00:00
# creator_id :integer
2012-11-19 18:24:05 +00:00
# issues_enabled :boolean default(TRUE), not null
# wall_enabled :boolean default(TRUE), not null
# merge_requests_enabled :boolean default(TRUE), not null
# wiki_enabled :boolean default(TRUE), not null
2012-11-24 20:16:51 +00:00
# namespace_id :integer
2013-03-15 13:16:02 +00:00
# issues_tracker :string(255) default("gitlab"), not null
# issues_tracker_id :string(255)
2013-03-27 16:26:37 +00:00
# snippets_enabled :boolean default(TRUE), not null
2013-04-04 19:11:51 +00:00
# last_activity_at :datetime
2013-08-21 09:34:02 +00:00
# import_url :string(255)
2013-11-06 15:13:21 +00:00
# visibility_level :integer default(0), not null
2014-04-09 12:05:03 +00:00
# archived :boolean default(FALSE), not null
# import_status :string(255)
2014-08-25 09:25:02 +00:00
# repository_size :float default(0.0)
# star_count :integer default(0), not null
2012-11-19 18:24:05 +00:00
#
2011-10-08 21:36:38 +00:00
class Project < ActiveRecord :: Base
2013-03-21 19:01:14 +00:00
include Gitlab :: ShellAdapter
2013-11-06 15:13:21 +00:00
include Gitlab :: VisibilityLevel
2014-06-26 20:24:17 +00:00
include Gitlab :: ConfigHelper
extend Gitlab :: ConfigHelper
2013-01-23 14:13:28 +00:00
extend Enumerize
2013-11-27 08:49:59 +00:00
2014-02-28 07:57:19 +00:00
default_value_for :archived , false
2014-06-26 20:24:17 +00:00
default_value_for :visibility_level , gitlab_config_features . visibility_level
default_value_for :issues_enabled , gitlab_config_features . issues
default_value_for :merge_requests_enabled , gitlab_config_features . merge_requests
default_value_for :wiki_enabled , gitlab_config_features . wiki
2014-06-15 06:40:24 +00:00
default_value_for :wall_enabled , false
2014-06-26 20:24:17 +00:00
default_value_for :snippets_enabled , gitlab_config_features . snippets
2014-02-27 13:55:22 +00:00
2013-10-02 13:18:28 +00:00
ActsAsTaggableOn . strict_case_match = true
2014-07-29 16:19:26 +00:00
acts_as_taggable_on :tags
2013-04-16 09:45:45 +00:00
2013-11-06 16:45:39 +00:00
attr_accessor :new_default_branch
2012-06-07 12:44:57 +00:00
# Relations
2013-01-19 17:06:50 +00:00
belongs_to :creator , foreign_key : " creator_id " , class_name : " User "
2013-12-09 18:29:39 +00:00
belongs_to :group , - > { where ( type : Group ) } , foreign_key : " namespace_id "
2012-11-22 18:34:16 +00:00
belongs_to :namespace
2012-12-05 15:06:15 +00:00
2013-12-09 18:29:39 +00:00
has_one :last_event , - > { order 'events.created_at DESC' } , class_name : 'Event' , foreign_key : 'project_id'
2014-05-28 08:35:43 +00:00
# Project services
has_many :services
2012-11-19 19:34:05 +00:00
has_one :gitlab_ci_service , dependent : :destroy
2013-05-22 14:59:59 +00:00
has_one :campfire_service , dependent : :destroy
2013-12-17 10:42:40 +00:00
has_one :emails_on_push_service , dependent : :destroy
2013-09-24 22:56:25 +00:00
has_one :pivotaltracker_service , dependent : :destroy
2013-05-23 18:10:32 +00:00
has_one :hipchat_service , dependent : :destroy
2013-08-19 09:11:36 +00:00
has_one :flowdock_service , dependent : :destroy
2013-11-21 12:18:02 +00:00
has_one :assembla_service , dependent : :destroy
2014-02-18 23:09:16 +00:00
has_one :gemnasium_service , dependent : :destroy
2014-03-18 17:27:03 +00:00
has_one :slack_service , dependent : :destroy
2014-08-18 10:54:51 +00:00
has_one :buildbox_service , dependent : :destroy
2014-10-16 16:34:19 +00:00
has_one :bamboo_service , dependent : :destroy
2014-10-01 00:48:41 +00:00
has_one :pushover_service , dependent : :destroy
2013-03-19 15:37:50 +00:00
has_one :forked_project_link , dependent : :destroy , foreign_key : " forked_to_project_id "
has_one :forked_from_project , through : :forked_project_link
2013-12-12 09:32:16 +00:00
# Merge Requests for target project should be removed with it
2013-04-25 14:15:33 +00:00
has_many :merge_requests , dependent : :destroy , foreign_key : " target_project_id "
2013-12-12 09:32:16 +00:00
# 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
2014-08-14 14:17:19 +00:00
has_many :issues , - > { order 'issues.state DESC, issues.created_at DESC' } , dependent : :destroy
2014-07-29 16:19:26 +00:00
has_many :labels , dependent : :destroy
2013-12-12 09:32:16 +00:00
has_many :services , dependent : :destroy
has_many :events , dependent : :destroy
2013-01-19 17:06:50 +00:00
has_many :milestones , dependent : :destroy
has_many :notes , dependent : :destroy
2013-03-24 18:31:14 +00:00
has_many :snippets , dependent : :destroy , class_name : " ProjectSnippet "
2013-01-19 17:06:50 +00:00
has_many :hooks , dependent : :destroy , class_name : " ProjectHook "
has_many :protected_branches , dependent : :destroy
2014-09-14 16:51:54 +00:00
has_many :project_members , dependent : :destroy , as : :source , class_name : 'ProjectMember'
has_many :users , through : :project_members
2013-05-06 12:10:55 +00:00
has_many :deploy_keys_projects , dependent : :destroy
has_many :deploy_keys , through : :deploy_keys_projects
2014-06-26 07:49:14 +00:00
has_many :users_star_projects , dependent : :destroy
has_many :starrers , through : :users_star_projects , source : :user
2013-05-06 12:10:55 +00:00
2012-10-02 16:01:40 +00:00
delegate :name , to : :owner , allow_nil : true , prefix : true
2013-06-21 21:06:21 +00:00
delegate :members , to : :team , prefix : true
2012-10-02 16:01:40 +00:00
2012-10-09 00:10:04 +00:00
# Validations
2013-12-18 18:58:16 +00:00
validates :creator , presence : true , on : :create
2013-12-06 15:05:34 +00:00
validates :description , length : { maximum : 2000 } , allow_blank : true
2012-12-25 22:50:41 +00:00
validates :name , presence : true , length : { within : 0 .. 255 } ,
format : { with : Gitlab :: Regex . project_name_regex ,
2014-06-26 07:53:01 +00:00
message : Gitlab :: Regex . project_regex_message }
2012-11-23 18:11:09 +00:00
validates :path , presence : true , length : { within : 0 .. 255 } ,
2013-06-12 19:11:35 +00:00
exclusion : { in : Gitlab :: Blacklist . path } ,
2012-11-28 03:14:05 +00:00
format : { with : Gitlab :: Regex . path_regex ,
2014-06-26 07:53:01 +00:00
message : Gitlab :: Regex . path_regex_message }
2014-06-13 11:24:54 +00:00
validates :issues_enabled , :merge_requests_enabled ,
2012-10-09 00:10:04 +00:00
:wiki_enabled , inclusion : { in : [ true , false ] }
2014-06-30 13:43:32 +00:00
validates :visibility_level ,
exclusion : { in : gitlab_config . restricted_visibility_levels } ,
if : - > { gitlab_config . restricted_visibility_levels . any? }
2013-12-06 15:05:34 +00:00
validates :issues_tracker_id , length : { maximum : 255 } , allow_blank : true
2013-09-17 13:12:10 +00:00
validates :namespace , presence : true
2012-11-23 18:11:09 +00:00
validates_uniqueness_of :name , scope : :namespace_id
validates_uniqueness_of :path , scope : :namespace_id
2013-02-11 21:13:21 +00:00
validates :import_url ,
2013-06-20 08:23:40 +00:00
format : { with : URI :: regexp ( %w( git http https ) ) , message : " should be a valid url " } ,
2013-02-11 21:13:21 +00:00
if : :import?
2014-07-14 13:17:59 +00:00
validates :star_count , numericality : { greater_than_or_equal_to : 0 }
2013-08-13 09:04:11 +00:00
validate :check_limit , on : :create
2012-10-09 00:10:04 +00:00
2012-06-07 12:44:57 +00:00
# Scopes
2013-04-03 03:06:18 +00:00
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 :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 ) ) }
2012-12-26 10:22:12 +00:00
scope :in_namespace , - > ( namespace ) { where ( namespace_id : namespace . id ) }
2013-04-02 22:28:12 +00:00
scope :in_group_namespace , - > { joins ( :group ) }
2013-06-22 10:39:34 +00:00
scope :sorted_by_activity , - > { reorder ( " projects.last_activity_at DESC " ) }
2014-09-25 16:41:49 +00:00
scope :sorted_by_stars , - > { reorder ( " projects.star_count DESC " ) }
2012-11-30 03:14:05 +00:00
scope :personal , - > ( user ) { where ( namespace_id : user . namespace_id ) }
scope :joined , - > ( user ) { where ( " namespace_id != ? " , user . namespace_id ) }
2014-02-25 12:36:36 +00:00
scope :public_only , - > { where ( visibility_level : Project :: PUBLIC ) }
scope :public_and_internal_only , - > { where ( visibility_level : Project . public_and_internal_levels ) }
2013-11-29 16:10:59 +00:00
scope :non_archived , - > { where ( archived : false ) }
2013-04-03 02:05:00 +00:00
enumerize :issues_tracker , in : ( Gitlab . config . issues_tracker . keys ) . append ( :gitlab ) , default : :gitlab
2013-01-23 14:13:28 +00:00
2014-03-12 15:15:03 +00:00
state_machine :import_status , initial : :none do
event :import_start do
2014-11-29 22:50:25 +00:00
transition [ :none , :finished ] = > :started
2014-03-12 15:15:03 +00:00
end
event :import_finish do
transition :started = > :finished
end
event :import_fail do
2014-03-12 17:26:09 +00:00
transition :started = > :failed
end
event :import_retry do
transition :failed = > :started
2014-03-12 15:15:03 +00:00
end
state :started
state :finished
2014-03-12 17:26:09 +00:00
state :failed
after_transition any = > :started , :do = > :add_import_job
2014-03-12 15:15:03 +00:00
end
2012-10-09 00:10:04 +00:00
class << self
2014-02-25 12:36:36 +00:00
def public_and_internal_levels
[ Project :: PUBLIC , Project :: INTERNAL ]
end
2013-01-14 07:37:29 +00:00
def abandoned
2013-06-11 13:57:52 +00:00
where ( 'projects.last_activity_at < ?' , 6 . months . ago )
2013-01-14 07:37:29 +00:00
end
2014-02-25 12:36:36 +00:00
2014-02-13 20:45:51 +00:00
def publicish ( user )
visibility_levels = [ Project :: PUBLIC ]
visibility_levels += [ Project :: INTERNAL ] if user
where ( visibility_level : visibility_levels )
end
2014-02-25 12:36:36 +00:00
2013-01-14 07:44:27 +00:00
def with_push
2014-10-20 14:22:39 +00:00
joins ( :events ) . where ( 'events.action = ?' , Event :: PUSHED )
2013-01-14 07:44:27 +00:00
end
2012-10-09 00:10:04 +00:00
def active
joins ( :issues , :notes , :merge_requests ) . order ( " issues.created_at, notes.created_at, merge_requests.created_at DESC " )
end
2012-06-11 05:52:44 +00:00
2014-08-27 09:47:30 +00:00
def search ( query )
2013-11-29 16:10:59 +00:00
joins ( :namespace ) . where ( " projects.archived = ? " , false ) . where ( " projects.name LIKE :query OR projects.path LIKE :query OR namespaces.name LIKE :query OR projects.description LIKE :query " , query : " % #{ query } % " )
2012-10-09 00:10:04 +00:00
end
2012-06-11 05:52:44 +00:00
2014-08-27 09:47:30 +00:00
def search_by_title ( query )
2014-01-18 14:22:57 +00:00
where ( " projects.archived = ? " , false ) . where ( " LOWER(projects.name) LIKE :query " , query : " % #{ query . downcase } % " )
2014-01-18 12:16:46 +00:00
end
2012-11-24 20:00:30 +00:00
def find_with_namespace ( id )
2014-03-14 13:58:10 +00:00
return nil unless id . include? ( " / " )
id = id . split ( " / " )
namespace = Namespace . find_by ( path : id . first )
return nil unless namespace
where ( namespace_id : namespace . id ) . find_by ( path : id . second )
2012-11-24 20:00:30 +00:00
end
2013-11-27 09:51:46 +00:00
2013-11-06 15:13:21 +00:00
def visibility_levels
Gitlab :: VisibilityLevel . options
end
2013-12-29 10:58:00 +00:00
def sort ( method )
case method . to_s
when 'newest' then reorder ( 'projects.created_at DESC' )
when 'oldest' then reorder ( 'projects.created_at ASC' )
when 'recently_updated' then reorder ( 'projects.updated_at DESC' )
when 'last_updated' then reorder ( 'projects.updated_at ASC' )
2014-05-02 14:02:57 +00:00
when 'largest_repository' then reorder ( 'projects.repository_size DESC' )
2013-12-29 10:58:00 +00:00
else reorder ( " namespaces.path, projects.name ASC " )
end
end
2012-07-05 18:59:37 +00:00
end
2013-01-03 19:09:18 +00:00
def team
2013-01-19 18:52:55 +00:00
@team || = ProjectTeam . new ( self )
2013-01-03 19:09:18 +00:00
end
def repository
2013-11-06 16:45:39 +00:00
@repository || = Repository . new ( path_with_namespace )
2013-01-03 19:09:18 +00:00
end
2012-07-05 18:59:37 +00:00
def saved?
2013-02-14 11:58:33 +00:00
id && persisted?
2012-06-11 05:52:44 +00:00
end
2014-03-12 17:26:09 +00:00
def add_import_job
RepositoryImportWorker . perform_in ( 2 . seconds , id )
end
2013-02-11 21:13:21 +00:00
def import?
import_url . present?
end
2013-08-12 15:21:47 +00:00
def imported?
2014-03-12 17:26:09 +00:00
import_finished?
end
def import_in_progress?
import? && import_status == 'started'
end
def import_failed?
import_status == 'failed'
end
def import_finished?
import_status == 'finished'
2013-08-12 15:21:47 +00:00
end
2012-06-07 12:44:57 +00:00
def check_limit
2014-04-09 15:27:34 +00:00
unless creator . can_create_project? or namespace . kind == 'group'
2014-04-04 20:17:21 +00:00
errors [ :limit_reached ] << ( " Your project limit is #{ creator . projects_limit } projects! Please contact your administrator to increase it " )
2012-06-07 12:44:57 +00:00
end
rescue
2012-08-10 23:47:54 +00:00
errors [ :base ] << ( " Can't check your ability to create project " )
2011-10-08 21:36:38 +00:00
end
2012-06-07 12:44:57 +00:00
def to_param
2013-09-17 13:12:10 +00:00
namespace . path + " / " + path
2011-11-06 20:38:08 +00:00
end
2012-06-07 12:44:57 +00:00
def web_url
2014-06-26 20:24:17 +00:00
[ gitlab_config . url , path_with_namespace ] . join ( " / " )
2011-12-13 21:24:31 +00:00
end
2014-01-20 11:26:34 +00:00
def web_url_without_protocol
2013-12-30 22:44:11 +00:00
web_url . split ( " :// " ) [ 1 ]
2013-12-30 20:14:15 +00:00
end
2011-11-10 23:28:26 +00:00
def build_commit_note ( commit )
2012-12-18 18:02:00 +00:00
notes . new ( commit_id : commit . id , noteable_type : " Commit " )
2011-10-08 21:36:38 +00:00
end
2011-10-26 13:46:25 +00:00
2011-11-15 08:34:30 +00:00
def last_activity
2012-10-17 19:02:52 +00:00
last_event
2011-10-31 20:57:16 +00:00
end
def last_activity_date
2013-04-03 03:06:18 +00:00
last_activity_at || updated_at
2012-03-01 18:40:32 +00:00
end
2011-12-20 06:24:14 +00:00
2012-03-05 22:26:40 +00:00
def project_id
self . id
end
2012-10-09 17:39:06 +00:00
2013-02-11 11:41:12 +00:00
def issue_exists? ( issue_id )
if used_default_issues_tracker?
2013-08-20 14:31:26 +00:00
self . issues . where ( iid : issue_id ) . first . present?
2013-02-11 11:41:12 +00:00
else
true
end
end
def used_default_issues_tracker?
self . issues_tracker == Project . issues_tracker . default_value
end
2013-02-11 14:17:43 +00:00
def can_have_issues_tracker_id?
self . issues_enabled && ! self . used_default_issues_tracker?
end
2013-05-22 13:58:44 +00:00
def build_missing_services
available_services_names . each do | service_name |
service = services . find { | service | service . to_param == service_name }
# If service is available but missing in db
# we should create an instance. Ex `create_gitlab_ci_service`
service = self . send :" create_ #{ service_name } _service " if service . nil?
end
end
def available_services_names
2014-10-16 16:34:19 +00:00
%w( gitlab_ci campfire hipchat pivotaltracker flowdock assembla emails_on_push gemnasium slack pushover buildbox bamboo )
2012-11-20 12:22:00 +00:00
end
2012-11-20 17:34:05 +00:00
def gitlab_ci?
gitlab_ci_service && gitlab_ci_service . active
end
2012-11-22 18:34:16 +00:00
2014-05-28 08:35:43 +00:00
def ci_services
services . select { | service | service . category == :ci }
end
def ci_service
2014-06-03 15:46:47 +00:00
@ci_service || = ci_services . select ( & :activated? ) . first
2014-05-28 08:35:43 +00:00
end
2012-11-23 19:31:09 +00:00
# For compatibility with old code
def code
path
2012-11-22 20:34:06 +00:00
end
2012-11-24 10:37:30 +00:00
2014-09-25 22:07:40 +00:00
def items_for ( entity )
2012-11-21 05:24:05 +00:00
case entity
when 'issue' then
issues
when 'merge_request' then
merge_requests
end
end
2012-12-20 20:16:51 +00:00
def send_move_instructions
2014-01-15 12:03:52 +00:00
NotificationService . new . project_was_moved ( self )
2012-12-20 20:16:51 +00:00
end
2013-01-02 17:00:00 +00:00
def owner
2013-09-26 11:49:22 +00:00
if group
group
2013-01-02 17:00:00 +00:00
else
2013-09-26 11:49:22 +00:00
namespace . try ( :owner )
2013-01-02 17:00:00 +00:00
end
end
2013-01-02 21:35:11 +00:00
def team_member_by_name_or_email ( name = nil , email = nil )
user = users . where ( " name like ? or email like ? " , name , email ) . first
2014-09-14 16:51:54 +00:00
project_members . where ( user : user ) if user
2013-01-02 21:35:11 +00:00
end
# Get Team Member record by user id
def team_member_by_id ( user_id )
2014-09-14 16:51:54 +00:00
project_members . find_by ( user_id : user_id )
2013-01-02 21:35:11 +00:00
end
def name_with_namespace
@name_with_namespace || = begin
if namespace
namespace . human_name + " / " + name
else
name
end
end
end
def path_with_namespace
if namespace
namespace . path + '/' + path
else
path
end
end
2013-12-03 09:31:56 +00:00
def execute_hooks ( data , hooks_scope = :push_hooks )
hooks . send ( hooks_scope ) . each do | hook |
hook . async_execute ( data )
end
2013-01-02 21:35:11 +00:00
end
def execute_services ( data )
2014-12-07 10:29:37 +00:00
services . select ( & :active ) . each do | service |
service . async_execute ( data )
2013-01-02 21:35:11 +00:00
end
end
def update_merge_requests ( oldrev , newrev , ref , user )
2014-11-11 14:49:26 +00:00
MergeRequests :: RefreshService . new ( self , user ) .
execute ( oldrev , newrev , ref )
2013-01-02 21:35:11 +00:00
end
def valid_repo?
2013-04-01 13:56:25 +00:00
repository . exists?
2013-01-02 21:35:11 +00:00
rescue
errors . add ( :path , " Invalid repository path " )
false
end
def empty_repo?
2013-04-01 13:56:25 +00:00
! repository . exists? || repository . empty?
2013-01-02 21:35:11 +00:00
end
2013-02-25 19:21:38 +00:00
def ensure_satellite_exists
self . satellite . create unless self . satellite . exists?
end
2013-01-02 21:35:11 +00:00
def satellite
@satellite || = Gitlab :: Satellite :: Satellite . new ( self )
end
def repo
2013-01-03 19:09:18 +00:00
repository . raw
2013-01-02 21:35:11 +00:00
end
def url_to_repo
2013-02-11 17:16:59 +00:00
gitlab_shell . url_to_repo ( path_with_namespace )
2013-01-02 21:35:11 +00:00
end
def namespace_dir
namespace . try ( :path ) || ''
end
def repo_exists?
2013-04-01 13:56:25 +00:00
@repo_exists || = repository . exists?
2013-01-02 21:35:11 +00:00
rescue
@repo_exists = false
end
def open_branches
2013-03-31 14:08:10 +00:00
all_branches = repository . branches
if protected_branches . present?
all_branches . reject! do | branch |
protected_branches_names . include? ( branch . name )
end
end
all_branches
end
def protected_branches_names
@protected_branches_names || = protected_branches . map ( & :name )
2013-01-02 21:35:11 +00:00
end
def root_ref? ( branch )
2013-01-03 19:09:18 +00:00
repository . root_ref == branch
2013-01-02 21:35:11 +00:00
end
def ssh_url_to_repo
url_to_repo
end
def http_url_to_repo
2014-06-26 20:24:17 +00:00
[ gitlab_config . url , " / " , path_with_namespace , " .git " ] . join ( '' )
2013-01-02 21:35:11 +00:00
end
# Check if current branch name is marked as protected in the system
2014-09-25 22:07:40 +00:00
def protected_branch? ( branch_name )
2013-03-31 14:08:10 +00:00
protected_branches_names . include? ( branch_name )
2013-01-02 21:35:11 +00:00
end
2013-03-19 15:37:50 +00:00
2014-12-26 08:35:49 +00:00
def developers_can_push_to_protected_branch? ( branch_name )
protected_branches . map { | pb | pb . developers_can_push if pb . name == branch_name } . compact . first
end
2013-03-19 15:37:50 +00:00
def forked?
! ( forked_project_link . nil? || forked_project_link . forked_from_project . nil? )
end
2013-05-24 21:07:19 +00:00
2013-06-19 18:58:52 +00:00
def personal?
! group
end
2013-05-24 21:07:19 +00:00
def rename_repo
2014-07-31 12:39:28 +00:00
path_was = previous_changes [ 'path' ] . first
2013-05-24 21:07:19 +00:00
old_path_with_namespace = File . join ( namespace_dir , path_was )
new_path_with_namespace = File . join ( namespace_dir , path )
if gitlab_shell . mv_repository ( old_path_with_namespace , new_path_with_namespace )
# If repository moved successfully we need to remove old satellite
# and send update instructions to users.
# However we cannot allow rollback since we moved repository
# So we basically we mute exceptions in next actions
begin
2013-08-20 14:44:15 +00:00
gitlab_shell . mv_repository ( " #{ old_path_with_namespace } .wiki " , " #{ new_path_with_namespace } .wiki " )
2013-05-24 21:07:19 +00:00
gitlab_shell . rm_satellites ( old_path_with_namespace )
2013-08-22 11:49:57 +00:00
ensure_satellite_exists
2013-05-24 21:07:19 +00:00
send_move_instructions
2013-08-29 16:12:22 +00:00
reset_events_cache
2013-05-24 21:07:19 +00:00
rescue
2013-07-29 10:46:00 +00:00
# Returning false does not rollback after_* transaction but gives
2013-05-24 21:07:19 +00:00
# us information about failing some of tasks
false
end
else
# if we cannot move namespace directory we should rollback
# db changes in order to prevent out of sync between db and fs
raise Exception . new ( 'repository cannot be renamed' )
end
end
2013-08-29 16:12:22 +00:00
2014-09-15 07:10:35 +00:00
def hook_attrs
{
name : name ,
ssh_url : ssh_url_to_repo ,
http_url : http_url_to_repo ,
namespace : namespace . name ,
visibility_level : visibility_level
}
end
2013-08-29 16:12:22 +00:00
# Reset events cache related to this project
#
# Since we do cache @event we need to reset cache in special cases:
# * when project was moved
# * when project was renamed
# Events cache stored like events/23-20130109142513.
# The cache key includes updated_at timestamp.
# Thus it will automatically generate a new fragment
# when the event is updated because the key changes.
def reset_events_cache
Event . where ( project_id : self . id ) .
order ( 'id DESC' ) . limit ( 100 ) .
update_all ( updated_at : Time . now )
end
2013-11-05 14:41:29 +00:00
def project_member ( user )
2014-09-14 16:51:54 +00:00
project_members . where ( user_id : user ) . first
2013-11-05 14:41:29 +00:00
end
2013-11-06 16:45:39 +00:00
def default_branch
@default_branch || = repository . root_ref if repository . exists?
end
2013-11-27 08:49:59 +00:00
def reload_default_branch
@default_branch = nil
default_branch
end
2013-11-27 09:51:46 +00:00
2013-11-06 15:13:21 +00:00
def visibility_level_field
visibility_level
end
2013-11-29 16:10:59 +00:00
def archive!
update_attribute ( :archived , true )
end
def unarchive!
update_attribute ( :archived , false )
end
2013-12-16 19:30:24 +00:00
2013-12-16 17:34:56 +00:00
def change_head ( branch )
gitlab_shell . update_repository_head ( self . path_with_namespace , branch )
reload_default_branch
end
2014-04-02 18:51:53 +00:00
def forked_from? ( project )
forked? && project == forked_from_project
end
2014-05-02 13:05:08 +00:00
def update_repository_size
update_attribute ( :repository_size , repository . size )
end
2014-07-24 19:14:12 +00:00
def forks_count
ForkedProjectLink . where ( forked_from_project_id : self . id ) . count
end
2014-08-12 12:16:25 +00:00
def find_label ( name )
labels . find_by ( name : name )
end
2014-09-23 11:20:21 +00:00
def origin_merge_requests
merge_requests . where ( source_project_id : self . id )
end
2014-11-29 19:34:18 +00:00
def create_repository
if gitlab_shell . add_repository ( path_with_namespace )
true
else
errors . add ( :base , " Failed to create repository " )
false
end
end
def repository_exists?
! ! repository . exists?
end
def create_wiki
ProjectWiki . new ( self , self . owner ) . wiki
true
rescue ProjectWiki :: CouldNotCreateWikiError = > ex
errors . add ( :base , " Failed create wiki " )
false
end
2011-10-08 21:36:38 +00:00
end