2012-11-19 13:24:05 -05:00
# == Schema Information
#
# Table name: projects
#
# id :integer not null, primary key
# name :string(255)
# path :string(255)
# description :text
2014-04-09 08:05:03 -04:00
# created_at :datetime
# updated_at :datetime
2013-01-03 14:09:18 -05:00
# creator_id :integer
2012-11-19 13:24:05 -05: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 15:16:51 -05:00
# namespace_id :integer
2013-03-15 09:16:02 -04:00
# issues_tracker :string(255) default("gitlab"), not null
# issues_tracker_id :string(255)
2013-03-27 12:26:37 -04:00
# snippets_enabled :boolean default(TRUE), not null
2013-04-04 15:11:51 -04:00
# last_activity_at :datetime
2013-08-21 05:34:02 -04:00
# import_url :string(255)
2013-11-06 10:13:21 -05:00
# visibility_level :integer default(0), not null
2014-04-09 08:05:03 -04:00
# archived :boolean default(FALSE), not null
# import_status :string(255)
2014-08-25 05:25:02 -04:00
# repository_size :float default(0.0)
# star_count :integer default(0), not null
2012-11-19 13:24:05 -05:00
#
2011-10-08 17:36:38 -04:00
class Project < ActiveRecord :: Base
2013-03-21 15:01:14 -04:00
include Gitlab :: ShellAdapter
2013-11-06 10:13:21 -05:00
include Gitlab :: VisibilityLevel
2014-06-26 16:24:17 -04:00
include Gitlab :: ConfigHelper
extend Gitlab :: ConfigHelper
2013-01-23 09:13:28 -05:00
extend Enumerize
2013-11-27 03:49:59 -05:00
2014-02-28 02:57:19 -05:00
default_value_for :archived , false
2014-06-26 16:24:17 -04: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 02:40:24 -04:00
default_value_for :wall_enabled , false
2014-06-26 16:24:17 -04:00
default_value_for :snippets_enabled , gitlab_config_features . snippets
2014-02-27 08:55:22 -05:00
2013-10-02 09:18:28 -04:00
ActsAsTaggableOn . strict_case_match = true
2014-07-29 12:19:26 -04:00
acts_as_taggable_on :tags
2013-04-16 05:45:45 -04:00
2013-11-06 11:45:39 -05:00
attr_accessor :new_default_branch
2012-06-07 08:44:57 -04:00
# Relations
2013-01-19 12:06:50 -05:00
belongs_to :creator , foreign_key : " creator_id " , class_name : " User "
2013-12-09 13:29:39 -05:00
belongs_to :group , - > { where ( type : Group ) } , foreign_key : " namespace_id "
2012-11-22 13:34:16 -05:00
belongs_to :namespace
2012-12-05 10:06:15 -05:00
2013-12-09 13:29:39 -05:00
has_one :last_event , - > { order 'events.created_at DESC' } , class_name : 'Event' , foreign_key : 'project_id'
2014-05-28 04:35:43 -04:00
# Project services
has_many :services
2012-11-19 14:34:05 -05:00
has_one :gitlab_ci_service , dependent : :destroy
2013-05-22 10:59:59 -04:00
has_one :campfire_service , dependent : :destroy
2013-12-17 05:42:40 -05:00
has_one :emails_on_push_service , dependent : :destroy
2013-09-24 18:56:25 -04:00
has_one :pivotaltracker_service , dependent : :destroy
2013-05-23 14:10:32 -04:00
has_one :hipchat_service , dependent : :destroy
2013-08-19 05:11:36 -04:00
has_one :flowdock_service , dependent : :destroy
2013-11-21 07:18:02 -05:00
has_one :assembla_service , dependent : :destroy
2014-02-18 18:09:16 -05:00
has_one :gemnasium_service , dependent : :destroy
2014-03-18 13:27:03 -04:00
has_one :slack_service , dependent : :destroy
2013-03-19 11:37:50 -04: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 04:32:16 -05:00
# Merge Requests for target project should be removed with it
2013-04-25 10:15:33 -04:00
has_many :merge_requests , dependent : :destroy , foreign_key : " target_project_id "
2013-12-12 04:32:16 -05: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 10:17:19 -04:00
has_many :issues , - > { order 'issues.state DESC, issues.created_at DESC' } , dependent : :destroy
2014-07-29 12:19:26 -04:00
has_many :labels , dependent : :destroy
2013-12-12 04:32:16 -05:00
has_many :services , dependent : :destroy
has_many :events , dependent : :destroy
2013-01-19 12:06:50 -05:00
has_many :milestones , dependent : :destroy
has_many :notes , dependent : :destroy
2013-03-24 14:31:14 -04:00
has_many :snippets , dependent : :destroy , class_name : " ProjectSnippet "
2013-01-19 12:06:50 -05:00
has_many :hooks , dependent : :destroy , class_name : " ProjectHook "
has_many :protected_branches , dependent : :destroy
2014-09-14 12:51:54 -04:00
has_many :project_members , dependent : :destroy , as : :source , class_name : 'ProjectMember'
has_many :users , through : :project_members
2013-05-06 08:10:55 -04:00
has_many :deploy_keys_projects , dependent : :destroy
has_many :deploy_keys , through : :deploy_keys_projects
2014-06-26 03:49:14 -04:00
has_many :users_star_projects , dependent : :destroy
has_many :starrers , through : :users_star_projects , source : :user
2013-05-06 08:10:55 -04:00
2012-10-02 12:01:40 -04:00
delegate :name , to : :owner , allow_nil : true , prefix : true
2013-06-21 17:06:21 -04:00
delegate :members , to : :team , prefix : true
2012-10-02 12:01:40 -04:00
2012-10-08 20:10:04 -04:00
# Validations
2013-12-18 13:58:16 -05:00
validates :creator , presence : true , on : :create
2013-12-06 10:05:34 -05:00
validates :description , length : { maximum : 2000 } , allow_blank : true
2012-12-25 17:50:41 -05:00
validates :name , presence : true , length : { within : 0 .. 255 } ,
format : { with : Gitlab :: Regex . project_name_regex ,
2014-06-26 03:53:01 -04:00
message : Gitlab :: Regex . project_regex_message }
2012-11-23 13:11:09 -05:00
validates :path , presence : true , length : { within : 0 .. 255 } ,
2013-06-12 15:11:35 -04:00
exclusion : { in : Gitlab :: Blacklist . path } ,
2012-11-27 22:14:05 -05:00
format : { with : Gitlab :: Regex . path_regex ,
2014-06-26 03:53:01 -04:00
message : Gitlab :: Regex . path_regex_message }
2014-06-13 07:24:54 -04:00
validates :issues_enabled , :merge_requests_enabled ,
2012-10-08 20:10:04 -04:00
:wiki_enabled , inclusion : { in : [ true , false ] }
2014-06-30 09:43:32 -04:00
validates :visibility_level ,
exclusion : { in : gitlab_config . restricted_visibility_levels } ,
if : - > { gitlab_config . restricted_visibility_levels . any? }
2013-12-06 10:05:34 -05:00
validates :issues_tracker_id , length : { maximum : 255 } , allow_blank : true
2013-09-17 09:12:10 -04:00
validates :namespace , presence : true
2012-11-23 13:11:09 -05:00
validates_uniqueness_of :name , scope : :namespace_id
validates_uniqueness_of :path , scope : :namespace_id
2013-02-11 16:13:21 -05:00
validates :import_url ,
2013-06-20 04:23:40 -04:00
format : { with : URI :: regexp ( %w( git http https ) ) , message : " should be a valid url " } ,
2013-02-11 16:13:21 -05:00
if : :import?
2014-07-14 09:17:59 -04:00
validates :star_count , numericality : { greater_than_or_equal_to : 0 }
2013-08-13 05:04:11 -04:00
validate :check_limit , on : :create
2012-10-08 20:10:04 -04:00
2012-06-07 08:44:57 -04:00
# Scopes
2013-04-02 23:06:18 -04: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 05:22:12 -05:00
scope :in_namespace , - > ( namespace ) { where ( namespace_id : namespace . id ) }
2013-04-02 18:28:12 -04:00
scope :in_group_namespace , - > { joins ( :group ) }
2013-06-22 06:39:34 -04:00
scope :sorted_by_activity , - > { reorder ( " projects.last_activity_at DESC " ) }
2012-11-29 22:14:05 -05:00
scope :personal , - > ( user ) { where ( namespace_id : user . namespace_id ) }
scope :joined , - > ( user ) { where ( " namespace_id != ? " , user . namespace_id ) }
2014-02-25 07:36:36 -05: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 11:10:59 -05:00
scope :non_archived , - > { where ( archived : false ) }
2013-04-02 22:05:00 -04:00
enumerize :issues_tracker , in : ( Gitlab . config . issues_tracker . keys ) . append ( :gitlab ) , default : :gitlab
2013-01-23 09:13:28 -05:00
2014-03-12 11:15:03 -04:00
state_machine :import_status , initial : :none do
event :import_start do
transition :none = > :started
end
event :import_finish do
transition :started = > :finished
end
event :import_fail do
2014-03-12 13:26:09 -04:00
transition :started = > :failed
end
event :import_retry do
transition :failed = > :started
2014-03-12 11:15:03 -04:00
end
state :started
state :finished
2014-03-12 13:26:09 -04:00
state :failed
after_transition any = > :started , :do = > :add_import_job
2014-03-12 11:15:03 -04:00
end
2012-10-08 20:10:04 -04:00
class << self
2014-02-25 07:36:36 -05:00
def public_and_internal_levels
[ Project :: PUBLIC , Project :: INTERNAL ]
end
2013-01-14 02:37:29 -05:00
def abandoned
2013-06-11 09:57:52 -04:00
where ( 'projects.last_activity_at < ?' , 6 . months . ago )
2013-01-14 02:37:29 -05:00
end
2014-02-25 07:36:36 -05:00
2014-02-13 15:45:51 -05:00
def publicish ( user )
visibility_levels = [ Project :: PUBLIC ]
visibility_levels += [ Project :: INTERNAL ] if user
where ( visibility_level : visibility_levels )
end
2014-02-25 07:36:36 -05:00
2013-01-14 02:44:27 -05:00
def with_push
2013-02-13 06:48:16 -05:00
includes ( :events ) . where ( 'events.action = ?' , Event :: PUSHED )
2013-01-14 02:44:27 -05:00
end
2012-10-08 20:10:04 -04:00
def active
joins ( :issues , :notes , :merge_requests ) . order ( " issues.created_at, notes.created_at, merge_requests.created_at DESC " )
end
2012-06-11 01:52:44 -04:00
2014-08-27 05:47:30 -04:00
def search ( query )
2013-11-29 11:10:59 -05: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-08 20:10:04 -04:00
end
2012-06-11 01:52:44 -04:00
2014-08-27 05:47:30 -04:00
def search_by_title ( query )
2014-01-18 09:22:57 -05:00
where ( " projects.archived = ? " , false ) . where ( " LOWER(projects.name) LIKE :query " , query : " % #{ query . downcase } % " )
2014-01-18 07:16:46 -05:00
end
2012-11-24 15:00:30 -05:00
def find_with_namespace ( id )
2014-03-14 09:58:10 -04: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 15:00:30 -05:00
end
2013-11-27 04:51:46 -05:00
2013-11-06 10:13:21 -05:00
def visibility_levels
Gitlab :: VisibilityLevel . options
end
2013-12-29 05:58:00 -05: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 10:02:57 -04:00
when 'largest_repository' then reorder ( 'projects.repository_size DESC' )
2013-12-29 05:58:00 -05:00
else reorder ( " namespaces.path, projects.name ASC " )
end
end
2012-07-05 14:59:37 -04:00
end
2013-01-03 14:09:18 -05:00
def team
2013-01-19 13:52:55 -05:00
@team || = ProjectTeam . new ( self )
2013-01-03 14:09:18 -05:00
end
def repository
2013-11-06 11:45:39 -05:00
@repository || = Repository . new ( path_with_namespace )
2013-01-03 14:09:18 -05:00
end
2012-07-05 14:59:37 -04:00
def saved?
2013-02-14 06:58:33 -05:00
id && persisted?
2012-06-11 01:52:44 -04:00
end
2014-03-12 13:26:09 -04:00
def add_import_job
RepositoryImportWorker . perform_in ( 2 . seconds , id )
end
2013-02-11 16:13:21 -05:00
def import?
import_url . present?
end
2013-08-12 11:21:47 -04:00
def imported?
2014-03-12 13:26:09 -04: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 11:21:47 -04:00
end
2012-06-07 08:44:57 -04:00
def check_limit
2014-04-09 11:27:34 -04:00
unless creator . can_create_project? or namespace . kind == 'group'
2014-04-04 16:17:21 -04:00
errors [ :limit_reached ] << ( " Your project limit is #{ creator . projects_limit } projects! Please contact your administrator to increase it " )
2012-06-07 08:44:57 -04:00
end
rescue
2012-08-10 19:47:54 -04:00
errors [ :base ] << ( " Can't check your ability to create project " )
2011-10-08 17:36:38 -04:00
end
2012-06-07 08:44:57 -04:00
def to_param
2013-09-17 09:12:10 -04:00
namespace . path + " / " + path
2011-11-06 15:38:08 -05:00
end
2012-06-07 08:44:57 -04:00
def web_url
2014-06-26 16:24:17 -04:00
[ gitlab_config . url , path_with_namespace ] . join ( " / " )
2011-12-13 16:24:31 -05:00
end
2014-01-20 06:26:34 -05:00
def web_url_without_protocol
2013-12-30 17:44:11 -05:00
web_url . split ( " :// " ) [ 1 ]
2013-12-30 15:14:15 -05:00
end
2011-11-10 18:28:26 -05:00
def build_commit_note ( commit )
2012-12-18 13:02:00 -05:00
notes . new ( commit_id : commit . id , noteable_type : " Commit " )
2011-10-08 17:36:38 -04:00
end
2011-10-26 09:46:25 -04:00
2011-11-15 03:34:30 -05:00
def last_activity
2012-10-17 15:02:52 -04:00
last_event
2011-10-31 16:57:16 -04:00
end
def last_activity_date
2013-04-02 23:06:18 -04:00
last_activity_at || updated_at
2012-03-01 13:40:32 -05:00
end
2011-12-20 01:24:14 -05:00
2012-03-05 17:26:40 -05:00
def project_id
self . id
end
2012-10-09 13:39:06 -04:00
2013-02-11 06:41:12 -05:00
def issue_exists? ( issue_id )
if used_default_issues_tracker?
2013-08-20 10:31:26 -04:00
self . issues . where ( iid : issue_id ) . first . present?
2013-02-11 06:41:12 -05:00
else
true
end
end
def used_default_issues_tracker?
self . issues_tracker == Project . issues_tracker . default_value
end
2013-02-11 09:17:43 -05:00
def can_have_issues_tracker_id?
self . issues_enabled && ! self . used_default_issues_tracker?
end
2013-05-22 09:58:44 -04: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-03-18 13:27:03 -04:00
%w( gitlab_ci campfire hipchat pivotaltracker flowdock assembla emails_on_push gemnasium slack )
2012-11-20 07:22:00 -05:00
end
2012-11-20 12:34:05 -05:00
def gitlab_ci?
gitlab_ci_service && gitlab_ci_service . active
end
2012-11-22 13:34:16 -05:00
2014-05-28 04:35:43 -04:00
def ci_services
services . select { | service | service . category == :ci }
end
def ci_service
2014-06-03 11:46:47 -04:00
@ci_service || = ci_services . select ( & :activated? ) . first
2014-05-28 04:35:43 -04:00
end
2012-11-23 14:31:09 -05:00
# For compatibility with old code
def code
path
2012-11-22 15:34:06 -05:00
end
2012-11-24 05:37:30 -05:00
2012-11-21 00:24:05 -05:00
def items_for entity
case entity
when 'issue' then
issues
when 'merge_request' then
merge_requests
end
end
2012-12-20 15:16:51 -05:00
def send_move_instructions
2014-01-15 07:03:52 -05:00
NotificationService . new . project_was_moved ( self )
2012-12-20 15:16:51 -05:00
end
2013-01-02 12:00:00 -05:00
def owner
2013-09-26 07:49:22 -04:00
if group
group
2013-01-02 12:00:00 -05:00
else
2013-09-26 07:49:22 -04:00
namespace . try ( :owner )
2013-01-02 12:00:00 -05:00
end
end
2013-01-02 16:35:11 -05: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 12:51:54 -04:00
project_members . where ( user : user ) if user
2013-01-02 16:35:11 -05:00
end
# Get Team Member record by user id
def team_member_by_id ( user_id )
2014-09-14 12:51:54 -04:00
project_members . find_by ( user_id : user_id )
2013-01-02 16:35:11 -05: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 04:31:56 -05:00
def execute_hooks ( data , hooks_scope = :push_hooks )
hooks . send ( hooks_scope ) . each do | hook |
hook . async_execute ( data )
end
2013-01-02 16:35:11 -05:00
end
def execute_services ( data )
services . each do | service |
# Call service hook only if it is active
2014-06-22 08:48:31 -04:00
begin
service . execute ( data ) if service . active
rescue = > e
logger . error ( e )
end
2013-01-02 16:35:11 -05:00
end
end
def update_merge_requests ( oldrev , newrev , ref , user )
return true unless ref =~ / heads /
branch_name = ref . gsub ( " refs/heads/ " , " " )
2014-09-05 09:56:36 -04:00
commits = self . repository . commits_between ( oldrev , newrev )
c_ids = commits . map ( & :id )
2013-01-02 16:35:11 -05:00
2014-03-14 07:02:55 -04:00
# Close merge requests
mrs = self . merge_requests . opened . where ( target_branch : branch_name ) . to_a
mrs = mrs . select ( & :last_commit ) . select { | mr | c_ids . include? ( mr . last_commit . id ) }
2014-09-05 09:56:36 -04:00
mrs . uniq . each do | merge_request |
MergeRequests :: MergeService . new . execute ( merge_request , user , nil )
end
2014-03-14 07:02:55 -04:00
2013-10-08 08:45:57 -04:00
# Update code for merge requests into project between project branches
2013-12-14 08:43:48 -05:00
mrs = self . merge_requests . opened . by_branch ( branch_name ) . to_a
2013-10-08 08:45:57 -04:00
# Update code for merge requests between project and project fork
2013-12-14 08:43:48 -05:00
mrs += self . fork_merge_requests . opened . by_branch ( branch_name ) . to_a
2014-09-05 09:56:36 -04:00
mrs . uniq . each do | merge_request |
merge_request . reload_code
merge_request . mark_as_unchecked
end
# Add comment about pushing new commits to merge requests
2014-09-23 07:20:21 -04:00
comment_mr_with_commits ( branch_name , commits , user )
true
end
def comment_mr_with_commits ( branch_name , commits , user )
mrs = self . origin_merge_requests . opened . where ( source_branch : branch_name ) . to_a
2014-09-05 09:56:36 -04:00
mrs += self . fork_merge_requests . opened . where ( source_branch : branch_name ) . to_a
mrs . uniq . each do | merge_request |
Note . create_new_commits_note ( merge_request , merge_request . project ,
user , commits )
end
2013-01-02 16:35:11 -05:00
end
def valid_repo?
2013-04-01 09:56:25 -04:00
repository . exists?
2013-01-02 16:35:11 -05:00
rescue
errors . add ( :path , " Invalid repository path " )
false
end
def empty_repo?
2013-04-01 09:56:25 -04:00
! repository . exists? || repository . empty?
2013-01-02 16:35:11 -05:00
end
2013-02-25 14:21:38 -05:00
def ensure_satellite_exists
self . satellite . create unless self . satellite . exists?
end
2013-01-02 16:35:11 -05:00
def satellite
@satellite || = Gitlab :: Satellite :: Satellite . new ( self )
end
def repo
2013-01-03 14:09:18 -05:00
repository . raw
2013-01-02 16:35:11 -05:00
end
def url_to_repo
2013-02-11 12:16:59 -05:00
gitlab_shell . url_to_repo ( path_with_namespace )
2013-01-02 16:35:11 -05:00
end
def namespace_dir
namespace . try ( :path ) || ''
end
def repo_exists?
2013-04-01 09:56:25 -04:00
@repo_exists || = repository . exists?
2013-01-02 16:35:11 -05:00
rescue
@repo_exists = false
end
def open_branches
2013-03-31 10:08:10 -04: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 16:35:11 -05:00
end
def root_ref? ( branch )
2013-01-03 14:09:18 -05:00
repository . root_ref == branch
2013-01-02 16:35:11 -05:00
end
def ssh_url_to_repo
url_to_repo
end
def http_url_to_repo
2014-06-26 16:24:17 -04:00
[ gitlab_config . url , " / " , path_with_namespace , " .git " ] . join ( '' )
2013-01-02 16:35:11 -05:00
end
# Check if current branch name is marked as protected in the system
def protected_branch? branch_name
2013-03-31 10:08:10 -04:00
protected_branches_names . include? ( branch_name )
2013-01-02 16:35:11 -05:00
end
2013-03-19 11:37:50 -04:00
def forked?
! ( forked_project_link . nil? || forked_project_link . forked_from_project . nil? )
end
2013-05-24 17:07:19 -04:00
2013-06-19 14:58:52 -04:00
def personal?
! group
end
2013-05-24 17:07:19 -04:00
def rename_repo
2014-07-31 08:39:28 -04:00
path_was = previous_changes [ 'path' ] . first
2013-05-24 17:07:19 -04: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 10:44:15 -04:00
gitlab_shell . mv_repository ( " #{ old_path_with_namespace } .wiki " , " #{ new_path_with_namespace } .wiki " )
2013-05-24 17:07:19 -04:00
gitlab_shell . rm_satellites ( old_path_with_namespace )
2013-08-22 07:49:57 -04:00
ensure_satellite_exists
2013-05-24 17:07:19 -04:00
send_move_instructions
2013-08-29 12:12:22 -04:00
reset_events_cache
2013-05-24 17:07:19 -04:00
rescue
2013-07-29 06:46:00 -04:00
# Returning false does not rollback after_* transaction but gives
2013-05-24 17:07:19 -04: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 12:12:22 -04: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 09:41:29 -05:00
def project_member ( user )
2014-09-14 12:51:54 -04:00
project_members . where ( user_id : user ) . first
2013-11-05 09:41:29 -05:00
end
2013-11-06 11:45:39 -05:00
def default_branch
@default_branch || = repository . root_ref if repository . exists?
end
2013-11-27 03:49:59 -05:00
def reload_default_branch
@default_branch = nil
default_branch
end
2013-11-27 04:51:46 -05:00
2013-11-06 10:13:21 -05:00
def visibility_level_field
visibility_level
end
2013-11-29 11:10:59 -05:00
def archive!
update_attribute ( :archived , true )
end
def unarchive!
update_attribute ( :archived , false )
end
2013-12-16 14:30:24 -05:00
2013-12-16 12:34:56 -05:00
def change_head ( branch )
gitlab_shell . update_repository_head ( self . path_with_namespace , branch )
reload_default_branch
end
2014-04-02 14:51:53 -04:00
def forked_from? ( project )
forked? && project == forked_from_project
end
2014-05-02 09:05:08 -04:00
def update_repository_size
update_attribute ( :repository_size , repository . size )
end
2014-07-24 15:14:12 -04:00
def forks_count
ForkedProjectLink . where ( forked_from_project_id : self . id ) . count
end
2014-08-12 08:16:25 -04:00
def find_label ( name )
labels . find_by ( name : name )
end
2014-09-23 07:20:21 -04:00
def origin_merge_requests
merge_requests . where ( source_project_id : self . id )
end
2011-10-08 17:36:38 -04:00
end