2011-10-08 17:36:38 -04:00
|
|
|
require "grit"
|
|
|
|
|
|
|
|
class Project < ActiveRecord::Base
|
2011-10-09 15:36:57 -04:00
|
|
|
belongs_to :owner, :class_name => "User"
|
|
|
|
|
2011-10-15 12:56:53 -04:00
|
|
|
has_many :issues, :dependent => :destroy, :order => "position"
|
2011-10-08 17:36:38 -04:00
|
|
|
has_many :users_projects, :dependent => :destroy
|
|
|
|
has_many :users, :through => :users_projects
|
|
|
|
has_many :notes, :dependent => :destroy
|
2011-10-16 17:07:10 -04:00
|
|
|
has_many :snippets, :dependent => :destroy
|
2011-10-08 17:36:38 -04:00
|
|
|
|
2011-11-04 03:42:36 -04:00
|
|
|
acts_as_taggable
|
|
|
|
|
2011-10-08 17:36:38 -04:00
|
|
|
validates :name,
|
|
|
|
:uniqueness => true,
|
|
|
|
:presence => true,
|
|
|
|
:length => { :within => 0..255 }
|
|
|
|
|
|
|
|
validates :path,
|
|
|
|
:uniqueness => true,
|
|
|
|
:presence => true,
|
2011-10-15 12:30:56 -04:00
|
|
|
:format => { :with => /^[a-zA-Z0-9_\-]*$/,
|
|
|
|
:message => "only letters, digits & '_' '-' allowed" },
|
2011-10-08 17:36:38 -04:00
|
|
|
:length => { :within => 0..255 }
|
2011-10-26 09:46:25 -04:00
|
|
|
|
2011-10-08 17:36:38 -04:00
|
|
|
validates :description,
|
|
|
|
:length => { :within => 0..2000 }
|
|
|
|
|
|
|
|
validates :code,
|
|
|
|
:presence => true,
|
|
|
|
:uniqueness => true,
|
2011-10-15 12:30:56 -04:00
|
|
|
:format => { :with => /^[a-zA-Z0-9_\-]*$/,
|
|
|
|
:message => "only letters, digits & '_' '-' allowed" },
|
2011-10-18 04:21:44 -04:00
|
|
|
:length => { :within => 3..255 }
|
2011-10-08 17:36:38 -04:00
|
|
|
|
2011-10-09 15:36:57 -04:00
|
|
|
validates :owner,
|
|
|
|
:presence => true
|
|
|
|
|
2011-10-09 14:15:01 -04:00
|
|
|
validate :check_limit
|
2011-10-21 14:40:36 -04:00
|
|
|
validate :repo_name
|
|
|
|
|
2011-10-08 17:36:38 -04:00
|
|
|
after_destroy :destroy_gitosis_project
|
|
|
|
after_save :update_gitosis_project
|
|
|
|
|
2011-10-09 07:05:31 -04:00
|
|
|
attr_protected :private_flag, :owner_id
|
2011-10-08 17:36:38 -04:00
|
|
|
|
|
|
|
scope :public_only, where(:private_flag => false)
|
|
|
|
|
|
|
|
def to_param
|
|
|
|
code
|
|
|
|
end
|
|
|
|
|
|
|
|
def common_notes
|
|
|
|
notes.where(:noteable_type => ["", nil])
|
|
|
|
end
|
|
|
|
|
|
|
|
def update_gitosis_project
|
|
|
|
Gitosis.new.configure do |c|
|
|
|
|
c.update_project(path, gitosis_writers)
|
|
|
|
end
|
|
|
|
end
|
2011-10-26 09:46:25 -04:00
|
|
|
|
2011-10-08 17:36:38 -04:00
|
|
|
def destroy_gitosis_project
|
|
|
|
Gitosis.new.configure do |c|
|
|
|
|
c.destroy_project(self)
|
|
|
|
end
|
|
|
|
end
|
2011-10-26 09:46:25 -04:00
|
|
|
|
2011-10-08 17:36:38 -04:00
|
|
|
def add_access(user, *access)
|
|
|
|
opts = { :user => user }
|
|
|
|
access.each { |name| opts.merge!(name => true) }
|
|
|
|
users_projects.create(opts)
|
|
|
|
end
|
|
|
|
|
|
|
|
def reset_access(user)
|
|
|
|
users_projects.where(:project_id => self.id, :user_id => user.id).destroy if self.id
|
|
|
|
end
|
|
|
|
|
|
|
|
def writers
|
|
|
|
@writers ||= users_projects.includes(:user).where(:write => true).map(&:user)
|
|
|
|
end
|
|
|
|
|
|
|
|
def gitosis_writers
|
|
|
|
keys = Key.joins({:user => :users_projects}).where("users_projects.project_id = ? AND users_projects.write = ?", id, true)
|
|
|
|
keys.map(&:identifier)
|
|
|
|
end
|
|
|
|
|
|
|
|
def readers
|
|
|
|
@readers ||= users_projects.includes(:user).where(:read => true).map(&:user)
|
|
|
|
end
|
|
|
|
|
|
|
|
def admins
|
|
|
|
@admins ||=users_projects.includes(:user).where(:admin => true).map(&:user)
|
|
|
|
end
|
|
|
|
|
|
|
|
def public?
|
|
|
|
!private_flag
|
|
|
|
end
|
|
|
|
|
|
|
|
def private?
|
|
|
|
private_flag
|
|
|
|
end
|
|
|
|
|
|
|
|
def url_to_repo
|
|
|
|
"#{GITOSIS["git_user"]}@#{GITOSIS["host"]}:#{path}.git"
|
|
|
|
end
|
2011-10-26 09:46:25 -04:00
|
|
|
|
2011-10-08 17:36:38 -04:00
|
|
|
def path_to_repo
|
|
|
|
GITOSIS["base_path"] + path + ".git"
|
|
|
|
end
|
|
|
|
|
2011-10-26 09:46:25 -04:00
|
|
|
def repo
|
2011-10-08 17:36:38 -04:00
|
|
|
@repo ||= Grit::Repo.new(path_to_repo)
|
|
|
|
end
|
|
|
|
|
|
|
|
def tags
|
|
|
|
repo.tags.map(&:name).sort.reverse
|
|
|
|
end
|
|
|
|
|
|
|
|
def repo_exists?
|
|
|
|
repo rescue false
|
|
|
|
end
|
|
|
|
|
2011-10-31 16:57:16 -04:00
|
|
|
def last_activity
|
|
|
|
updates(1).first
|
|
|
|
rescue
|
|
|
|
nil
|
|
|
|
end
|
|
|
|
|
|
|
|
def last_activity_date
|
|
|
|
last_activity.try(:created_at)
|
|
|
|
end
|
|
|
|
|
|
|
|
def updates(n = 3)
|
|
|
|
[
|
|
|
|
fresh_commits(n),
|
|
|
|
issues.last(n),
|
|
|
|
notes.fresh.limit(n)
|
|
|
|
].compact.flatten.sort do |x, y|
|
|
|
|
y.created_at <=> x.created_at
|
2011-11-02 16:14:03 -04:00
|
|
|
end[0...n]
|
2011-10-31 16:57:16 -04:00
|
|
|
end
|
|
|
|
|
2011-10-08 17:36:38 -04:00
|
|
|
def commit(commit_id = nil)
|
|
|
|
if commit_id
|
|
|
|
repo.commits(commit_id).first
|
2011-10-26 09:46:25 -04:00
|
|
|
else
|
2011-10-08 17:36:38 -04:00
|
|
|
repo.commits.first
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2011-10-26 09:46:25 -04:00
|
|
|
def heads
|
2011-10-21 07:03:34 -04:00
|
|
|
@heads ||= repo.heads
|
|
|
|
end
|
|
|
|
|
2011-10-31 16:57:16 -04:00
|
|
|
def fresh_commits(n = 10)
|
2011-10-26 09:46:25 -04:00
|
|
|
commits = heads.map do |h|
|
2011-10-31 16:57:16 -04:00
|
|
|
repo.commits(h.name, n)
|
2011-10-21 07:03:34 -04:00
|
|
|
end.flatten.uniq { |c| c.id }
|
|
|
|
|
|
|
|
commits.sort! do |x, y|
|
|
|
|
y.committed_date <=> x.committed_date
|
|
|
|
end
|
|
|
|
|
2011-11-02 16:14:03 -04:00
|
|
|
commits[0...n]
|
2011-10-21 07:03:34 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def commits_since(date)
|
2011-10-26 09:46:25 -04:00
|
|
|
commits = heads.map do |h|
|
2011-10-21 07:03:34 -04:00
|
|
|
repo.log(h.name, nil, :since => date)
|
|
|
|
end.flatten.uniq { |c| c.id }
|
|
|
|
|
|
|
|
commits.sort! do |x, y|
|
|
|
|
y.committed_date <=> x.committed_date
|
|
|
|
end
|
|
|
|
|
|
|
|
commits
|
|
|
|
end
|
|
|
|
|
2011-10-08 17:36:38 -04:00
|
|
|
def tree(fcommit, path = nil)
|
|
|
|
fcommit = commit if fcommit == :head
|
|
|
|
tree = fcommit.tree
|
|
|
|
path ? (tree / path) : tree
|
|
|
|
end
|
|
|
|
|
2011-10-09 14:15:01 -04:00
|
|
|
def check_limit
|
|
|
|
unless owner.can_create_project?
|
2011-10-09 15:36:57 -04:00
|
|
|
errors[:base] << ("Your own projects limit is #{owner.projects_limit}! Please contact administrator to increase it")
|
2011-10-09 14:15:01 -04:00
|
|
|
end
|
2011-10-26 09:46:25 -04:00
|
|
|
rescue
|
2011-10-09 15:36:57 -04:00
|
|
|
errors[:base] << ("Cant check your ability to create project")
|
2011-10-09 14:15:01 -04:00
|
|
|
end
|
|
|
|
|
2011-10-21 14:40:36 -04:00
|
|
|
def repo_name
|
|
|
|
if path == "gitosis-admin"
|
2011-10-21 14:51:55 -04:00
|
|
|
errors.add(:path, " like 'gitosis-admin' is not allowed")
|
2011-10-21 14:40:36 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2011-10-08 17:36:38 -04:00
|
|
|
def valid_repo?
|
|
|
|
repo
|
|
|
|
rescue
|
|
|
|
errors.add(:path, "Invalid repository path")
|
|
|
|
false
|
|
|
|
end
|
|
|
|
end
|
|
|
|
# == Schema Information
|
|
|
|
#
|
|
|
|
# Table name: projects
|
|
|
|
#
|
|
|
|
# id :integer not null, primary key
|
|
|
|
# name :string(255)
|
|
|
|
# path :string(255)
|
|
|
|
# description :text
|
|
|
|
# created_at :datetime
|
|
|
|
# updated_at :datetime
|
|
|
|
# private_flag :boolean default(TRUE), not null
|
|
|
|
# code :string(255)
|
2011-10-09 07:05:31 -04:00
|
|
|
# owner_id :integer
|
2011-10-08 17:36:38 -04:00
|
|
|
#
|
|
|
|
|