OSDN Git Service

Get rid of roles
authorDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
Wed, 2 Jan 2013 21:35:11 +0000 (23:35 +0200)
committerDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
Wed, 2 Jan 2013 21:35:11 +0000 (23:35 +0200)
20 files changed:
app/models/event.rb
app/models/project.rb
app/models/user.rb
app/roles/account.rb [deleted file]
app/roles/authority.rb [deleted file]
app/roles/namespaced_project.rb [deleted file]
app/roles/note_event.rb [deleted file]
app/roles/push_event.rb [deleted file]
app/roles/push_observer.rb [deleted file]
app/roles/repository.rb [deleted file]
app/roles/team.rb [deleted file]
lib/git_host.rb [moved from app/roles/git_host.rb with 100% similarity]
lib/issue_commonality.rb [moved from app/roles/issue_commonality.rb with 99% similarity]
lib/static_model.rb [moved from app/roles/static_model.rb with 100% similarity]
lib/votes.rb [moved from app/roles/votes.rb with 100% similarity]
spec/lib/issue_commonality_spec.rb [moved from spec/roles/issue_commonality_spec.rb with 100% similarity]
spec/lib/votes_spec.rb [moved from spec/roles/votes_spec.rb with 100% similarity]
spec/models/project_repository_spec.rb [moved from spec/roles/repository_spec.rb with 100% similarity]
spec/models/user_spec.rb
spec/roles/account_role_spec.rb [deleted file]

index 90376e7..eb88a4e 100644 (file)
@@ -170,4 +170,139 @@ class Event < ActiveRecord::Base
       "opened"
     end
   end
+
+  def valid_push?
+    data[:ref]
+  rescue => ex
+    false
+  end
+
+  def tag?
+    data[:ref]["refs/tags"]
+  end
+
+  def branch?
+    data[:ref]["refs/heads"]
+  end
+
+  def new_branch?
+    commit_from =~ /^00000/
+  end
+
+  def new_ref?
+    commit_from =~ /^00000/
+  end
+
+  def rm_ref?
+    commit_to =~ /^00000/
+  end
+
+  def md_ref?
+    !(rm_ref? || new_ref?)
+  end
+
+  def commit_from
+    data[:before]
+  end
+
+  def commit_to
+    data[:after]
+  end
+
+  def ref_name
+    if tag?
+      tag_name
+    else
+      branch_name
+    end
+  end
+
+  def branch_name
+    @branch_name ||= data[:ref].gsub("refs/heads/", "")
+  end
+
+  def tag_name
+    @tag_name ||= data[:ref].gsub("refs/tags/", "")
+  end
+
+  # Max 20 commits from push DESC
+  def commits
+    @commits ||= data[:commits].map { |commit| project.commit(commit[:id]) }.reverse
+  end
+
+  def commits_count
+    data[:total_commits_count] || commits.count || 0
+  end
+
+  def ref_type
+    tag? ? "tag" : "branch"
+  end
+
+  def push_action_name
+    if new_ref?
+      "pushed new"
+    elsif rm_ref?
+      "deleted"
+    else
+      "pushed to"
+    end
+  end
+
+  def parent_commit
+    project.commit(commit_from)
+  rescue => ex
+    nil
+  end
+
+  def last_commit
+    project.commit(commit_to)
+  rescue => ex
+    nil
+  end
+
+  def push_with_commits?
+    md_ref? && commits.any? && parent_commit && last_commit
+  rescue Grit::NoSuchPathError
+    false
+  end
+
+  def last_push_to_non_root?
+    branch? && project.default_branch != branch_name
+  end
+
+  def note_commit_id
+    target.commit_id
+  end
+
+  def note_short_commit_id
+    note_commit_id[0..8]
+  end
+
+  def note_commit?
+    target.noteable_type == "Commit"
+  end
+
+  def note_target
+    target.noteable
+  end
+
+  def note_target_id
+    if note_commit?
+      target.commit_id
+    else
+      target.noteable_id.to_s
+    end
+  end
+
+  def wall_note?
+    target.noteable_type.blank?
+  end
+
+  def note_target_type
+    if target.noteable_type.present?
+      target.noteable_type.titleize
+    else
+      "Wall"
+    end.downcase
+  end
 end
index a697ccf..a5ef65c 100644 (file)
 require "grit"
 
 class Project < ActiveRecord::Base
-  include Repository
-  include PushObserver
-  include Authority
-  include Team
-  include NamespacedProject
+  include GitHost
 
   class TransferError < StandardError; end
 
@@ -277,4 +273,514 @@ class Project < ActiveRecord::Base
       creator
     end
   end
+
+  def team_member_by_name_or_email(name = nil, email = nil)
+    user = users.where("name like ? or email like ?", name, email).first
+    users_projects.where(user: user) if user
+  end
+
+  # Get Team Member record by user id
+  def team_member_by_id(user_id)
+    users_projects.find_by_user_id(user_id)
+  end
+
+  # Add user to project
+  # with passed access role
+  def add_user_to_team(user, access_role)
+    add_user_id_to_team(user.id, access_role)
+  end
+
+  # Add multiple users to project
+  # with same access role
+  def add_users_to_team(users, access_role)
+    add_users_ids_to_team(users.map(&:id), access_role)
+  end
+
+  # Add user to project
+  # with passed access role by user id
+  def add_user_id_to_team(user_id, access_role)
+    users_projects.create(
+      user_id: user_id,
+      project_access: access_role
+    )
+  end
+
+  # Add multiple users to project
+  # with same access role by user ids
+  def add_users_ids_to_team(users_ids, access_role)
+    UsersProject.bulk_import(self, users_ids, access_role)
+  end
+
+  # Update multiple project users
+  # to same access role by user ids
+  def update_users_ids_to_role(users_ids, access_role)
+    UsersProject.bulk_update(self, users_ids, access_role)
+  end
+
+  # Delete multiple users from project by user ids
+  def delete_users_ids_from_team(users_ids)
+    UsersProject.bulk_delete(self, users_ids)
+  end
+
+  # Remove all users from project team
+  def truncate_team
+    UsersProject.truncate_team(self)
+  end
+
+  # Compatible with all access rights
+  # Should be rewrited for new access rights
+  def add_access(user, *access)
+    access = if access.include?(:admin)
+               { project_access: UsersProject::MASTER }
+             elsif access.include?(:write)
+               { project_access: UsersProject::DEVELOPER }
+             else
+               { project_access: UsersProject::REPORTER }
+             end
+    opts = { user: user }
+    opts.merge!(access)
+    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 repository_readers
+    repository_members[UsersProject::REPORTER]
+  end
+
+  def repository_writers
+    repository_members[UsersProject::DEVELOPER]
+  end
+
+  def repository_masters
+    repository_members[UsersProject::MASTER]
+  end
+
+  def repository_members
+    keys = Hash.new {|h,k| h[k] = [] }
+    UsersProject.select("keys.identifier, project_access").
+        joins(user: :keys).where(project_id: id).
+        each {|row| keys[row.project_access] << [row.identifier] }
+
+    keys[UsersProject::REPORTER] += deploy_keys.pluck(:identifier)
+    keys
+  end
+
+  def allow_read_for?(user)
+    !users_projects.where(user_id: user.id).empty?
+  end
+
+  def guest_access_for?(user)
+    !users_projects.where(user_id: user.id).empty?
+  end
+
+  def report_access_for?(user)
+    !users_projects.where(user_id: user.id, project_access: [UsersProject::REPORTER, UsersProject::DEVELOPER, UsersProject::MASTER]).empty?
+  end
+
+  def dev_access_for?(user)
+    !users_projects.where(user_id: user.id, project_access: [UsersProject::DEVELOPER, UsersProject::MASTER]).empty?
+  end
+
+  def master_access_for?(user)
+    !users_projects.where(user_id: user.id, project_access: [UsersProject::MASTER]).empty?
+  end
+
+  def transfer(new_namespace)
+    Project.transaction do
+      old_namespace = namespace
+      self.namespace = new_namespace
+
+      old_dir = old_namespace.try(:path) || ''
+      new_dir = new_namespace.try(:path) || ''
+
+      old_repo = if old_dir.present?
+                   File.join(old_dir, self.path)
+                 else
+                   self.path
+                 end
+
+      if Project.where(path: self.path, namespace_id: new_namespace.try(:id)).present?
+        raise TransferError.new("Project with same path in target namespace already exists")
+      end
+
+      Gitlab::ProjectMover.new(self, old_dir, new_dir).execute
+
+      git_host.move_repository(old_repo, self)
+
+      save!
+    end
+  rescue Gitlab::ProjectMover::ProjectMoveError => ex
+    raise Project::TransferError.new(ex.message)
+  end
+
+  def name_with_namespace
+    @name_with_namespace ||= begin
+                               if namespace
+                                 namespace.human_name + " / " + name
+                               else
+                                 name
+                               end
+                             end
+  end
+
+  def namespace_owner
+    namespace.try(:owner)
+  end
+
+  def path_with_namespace
+    if namespace
+      namespace.path + '/' + path
+    else
+      path
+    end
+  end
+
+  # This method will be called after each post receive and only if the provided
+  # user is present in GitLab.
+  #
+  # All callbacks for post receive should be placed here.
+  def trigger_post_receive(oldrev, newrev, ref, user)
+    data = post_receive_data(oldrev, newrev, ref, user)
+
+    # Create push event
+    self.observe_push(data)
+
+    if push_to_branch? ref, oldrev
+      # Close merged MR
+      self.update_merge_requests(oldrev, newrev, ref, user)
+
+      # Execute web hooks
+      self.execute_hooks(data.dup)
+
+      # Execute project services
+      self.execute_services(data.dup)
+    end
+
+    # Create satellite
+    self.satellite.create unless self.satellite.exists?
+
+    # Discover the default branch, but only if it hasn't already been set to
+    # something else
+    if default_branch.nil?
+      update_attributes(default_branch: discover_default_branch)
+    end
+  end
+
+  def push_to_branch? ref, oldrev
+    ref_parts = ref.split('/')
+
+    # Return if this is not a push to a branch (e.g. new commits)
+    !(ref_parts[1] !~ /heads/ || oldrev == "00000000000000000000000000000000")
+  end
+
+  def observe_push(data)
+    Event.create(
+      project: self,
+      action: Event::Pushed,
+      data: data,
+      author_id: data[:user_id]
+    )
+  end
+
+  def execute_hooks(data)
+    hooks.each { |hook| hook.execute(data) }
+  end
+
+  def execute_services(data)
+    services.each do |service|
+
+      # Call service hook only if it is active
+      service.execute(data) if service.active
+    end
+  end
+
+  # Produce a hash of post-receive data
+  #
+  # data = {
+  #   before: String,
+  #   after: String,
+  #   ref: String,
+  #   user_id: String,
+  #   user_name: String,
+  #   repository: {
+  #     name: String,
+  #     url: String,
+  #     description: String,
+  #     homepage: String,
+  #   },
+  #   commits: Array,
+  #   total_commits_count: Fixnum
+  # }
+  #
+  def post_receive_data(oldrev, newrev, ref, user)
+
+    push_commits = commits_between(oldrev, newrev)
+
+    # Total commits count
+    push_commits_count = push_commits.size
+
+    # Get latest 20 commits ASC
+    push_commits_limited = push_commits.last(20)
+
+    # Hash to be passed as post_receive_data
+    data = {
+      before: oldrev,
+      after: newrev,
+      ref: ref,
+      user_id: user.id,
+      user_name: user.name,
+      repository: {
+        name: name,
+        url: url_to_repo,
+        description: description,
+        homepage: web_url,
+      },
+      commits: [],
+      total_commits_count: push_commits_count
+    }
+
+    # For perfomance purposes maximum 20 latest commits
+    # will be passed as post receive hook data.
+    #
+    push_commits_limited.each do |commit|
+      data[:commits] << {
+        id: commit.id,
+        message: commit.safe_message,
+        timestamp: commit.date.xmlschema,
+        url: "#{Gitlab.config.gitlab.url}/#{path_with_namespace}/commit/#{commit.id}",
+        author: {
+          name: commit.author_name,
+          email: commit.author_email
+        }
+      }
+    end
+
+    data
+  end
+
+  def update_merge_requests(oldrev, newrev, ref, user)
+    return true unless ref =~ /heads/
+    branch_name = ref.gsub("refs/heads/", "")
+    c_ids = self.commits_between(oldrev, newrev).map(&:id)
+
+    # Update code for merge requests
+    mrs = self.merge_requests.opened.find_all_by_branch(branch_name).all
+    mrs.each { |merge_request| merge_request.reload_code; merge_request.mark_as_unchecked }
+
+    # Close merge requests
+    mrs = self.merge_requests.opened.where(target_branch: branch_name).all
+    mrs = mrs.select(&:last_commit).select { |mr| c_ids.include?(mr.last_commit.id) }
+    mrs.each { |merge_request| merge_request.merge!(user.id) }
+
+    true
+  end
+
+  def valid_repo?
+    repo
+  rescue
+    errors.add(:path, "Invalid repository path")
+    false
+  end
+
+  def empty_repo?
+    !repo_exists? || !has_commits?
+  end
+
+  def commit(commit_id = nil)
+    Commit.find_or_first(repo, commit_id, root_ref)
+  end
+
+  def fresh_commits(n = 10)
+    Commit.fresh_commits(repo, n)
+  end
+
+  def commits_with_refs(n = 20)
+    Commit.commits_with_refs(repo, n)
+  end
+
+  def commits_since(date)
+    Commit.commits_since(repo, date)
+  end
+
+  def commits(ref, path = nil, limit = nil, offset = nil)
+    Commit.commits(repo, ref, path, limit, offset)
+  end
+
+  def last_commit_for(ref, path = nil)
+    commits(ref, path, 1).first
+  end
+
+  def commits_between(from, to)
+    Commit.commits_between(repo, from, to)
+  end
+
+  def satellite
+    @satellite ||= Gitlab::Satellite::Satellite.new(self)
+  end
+
+  def has_post_receive_file?
+    !!hook_file
+  end
+
+  def valid_post_receive_file?
+    valid_hook_file == hook_file
+  end
+
+  def valid_hook_file
+    @valid_hook_file ||= File.read(Rails.root.join('lib', 'hooks', 'post-receive'))
+  end
+
+  def hook_file
+    @hook_file ||= begin
+                     hook_path = File.join(path_to_repo, 'hooks', 'post-receive')
+                     File.read(hook_path) if File.exists?(hook_path)
+                   end
+  end
+
+  # Returns an Array of branch names
+  def branch_names
+    repo.branches.collect(&:name).sort
+  end
+
+  # Returns an Array of Branches
+  def branches
+    repo.branches.sort_by(&:name)
+  end
+
+  # Returns an Array of tag names
+  def tag_names
+    repo.tags.collect(&:name).sort.reverse
+  end
+
+  # Returns an Array of Tags
+  def tags
+    repo.tags.sort_by(&:name).reverse
+  end
+
+  # Returns an Array of branch and tag names
+  def ref_names
+    [branch_names + tag_names].flatten
+  end
+
+  def repo
+    @repo ||= Grit::Repo.new(path_to_repo)
+  end
+
+  def url_to_repo
+    git_host.url_to_repo(path_with_namespace)
+  end
+
+  def path_to_repo
+    File.join(Gitlab.config.gitolite.repos_path, "#{path_with_namespace}.git")
+  end
+
+  def namespace_dir
+    namespace.try(:path) || ''
+  end
+
+  def update_repository
+    git_host.update_repository(self)
+  end
+
+  def destroy_repository
+    git_host.remove_repository(self)
+  end
+
+  def repo_exists?
+    @repo_exists ||= (repo && !repo.branches.empty?)
+  rescue
+    @repo_exists = false
+  end
+
+  def heads
+    @heads ||= repo.heads
+  end
+
+  def tree(fcommit, path = nil)
+    fcommit = commit if fcommit == :head
+    tree = fcommit.tree
+    path ? (tree / path) : tree
+  end
+
+  def open_branches
+    if protected_branches.empty?
+      self.repo.heads
+    else
+      pnames = protected_branches.map(&:name)
+      self.repo.heads.reject { |h| pnames.include?(h.name) }
+    end.sort_by(&:name)
+  end
+
+  # Discovers the default branch based on the repository's available branches
+  #
+  # - If no branches are present, returns nil
+  # - If one branch is present, returns its name
+  # - If two or more branches are present, returns the one that has a name
+  #   matching root_ref (default_branch or 'master' if default_branch is nil)
+  def discover_default_branch
+    if branch_names.length == 0
+      nil
+    elsif branch_names.length == 1
+      branch_names.first
+    else
+      branch_names.select { |v| v == root_ref }.first
+    end
+  end
+
+  def has_commits?
+    !!commit
+  rescue Grit::NoSuchPathError
+    false
+  end
+
+  def root_ref
+    default_branch || "master"
+  end
+
+  def root_ref?(branch)
+    root_ref == branch
+  end
+
+  # Archive Project to .tar.gz
+  #
+  # Already packed repo archives stored at
+  # app_root/tmp/repositories/project_name/project_name-commit-id.tag.gz
+  #
+  def archive_repo(ref)
+    ref = ref || self.root_ref
+    commit = self.commit(ref)
+    return nil unless commit
+
+    # Build file path
+    file_name = self.path + "-" + commit.id.to_s + ".tar.gz"
+    storage_path = Rails.root.join("tmp", "repositories", self.path_with_namespace)
+    file_path = File.join(storage_path, file_name)
+
+    # Put files into a directory before archiving
+    prefix = self.path + "/"
+
+    # Create file if not exists
+    unless File.exists?(file_path)
+      FileUtils.mkdir_p storage_path
+      file = self.repo.archive_to_file(ref, prefix,  file_path)
+    end
+
+    file_path
+  end
+
+  def ssh_url_to_repo
+    url_to_repo
+  end
+
+  def http_url_to_repo
+    http_url = [Gitlab.config.gitlab.url, "/", path_with_namespace, ".git"].join('')
+  end
+
+  # Check if current branch name is marked as protected in the system
+  def protected_branch? branch_name
+    protected_branches.map(&:name).include?(branch_name)
+  end
 end
index 582eee6..d166ae4 100644 (file)
@@ -34,8 +34,6 @@
 #
 
 class User < ActiveRecord::Base
-  include Account
-
   devise :database_authenticatable, :token_authenticatable, :lockable,
          :recoverable, :rememberable, :trackable, :validatable, :omniauthable
 
@@ -192,4 +190,92 @@ class User < ActiveRecord::Base
   def tm_in_personal_projects
     personal_projects.users_projects.where(user_id: self.id)
   end
+
+  # Returns a string for use as a Gitolite user identifier
+  #
+  # Note that Gitolite 2.x requires the following pattern for users:
+  #
+  #   ^@?[0-9a-zA-Z][0-9a-zA-Z._\@+-]*$
+  def identifier
+    # Replace non-word chars with underscores, then make sure it starts with
+    # valid chars
+    email.gsub(/\W/, '_').gsub(/\A([\W\_])+/, '')
+  end
+
+  def is_admin?
+    admin
+  end
+
+  def require_ssh_key?
+    keys.count == 0
+  end
+
+  def can_create_project?
+    projects_limit > personal_projects.count
+  end
+
+  def can_create_group?
+    is_admin?
+  end
+
+  def abilities
+    @abilities ||= begin
+                     abilities = Six.new
+                     abilities << Ability
+                     abilities
+                   end
+  end
+
+  def can? action, subject
+    abilities.allowed?(self, action, subject)
+  end
+
+  def last_activity_project
+    projects.first
+  end
+
+  def first_name
+    name.split.first unless name.blank?
+  end
+
+  def cared_merge_requests
+    MergeRequest.where("author_id = :id or assignee_id = :id", id: self.id)
+  end
+
+  # Remove user from all projects and
+  # set blocked attribute to true
+  def block
+    users_projects.find_each do |membership|
+      return false unless membership.destroy
+    end
+
+    self.blocked = true
+    save
+  end
+
+  def projects_limit_percent
+    return 100 if projects_limit.zero?
+    (personal_projects.count.to_f / projects_limit) * 100
+  end
+
+  def recent_push project_id = nil
+    # Get push events not earlier than 2 hours ago
+    events = recent_events.code_push.where("created_at > ?", Time.now - 2.hours)
+    events = events.where(project_id: project_id) if project_id
+
+    # Take only latest one
+    events = events.recent.limit(1).first
+  end
+
+  def projects_sorted_by_activity
+    authorized_projects.sorted_by_activity
+  end
+
+  def several_namespaces?
+    namespaces.size > 1
+  end
+
+  def namespace_id
+    namespace.try :id
+  end
 end
diff --git a/app/roles/account.rb b/app/roles/account.rb
deleted file mode 100644 (file)
index 7e6d149..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-# == Account role
-#
-# Describe behaviour of User in application
-#
-# Used by User
-#
-module Account
-  # Returns a string for use as a Gitolite user identifier
-  #
-  # Note that Gitolite 2.x requires the following pattern for users:
-  #
-  #   ^@?[0-9a-zA-Z][0-9a-zA-Z._\@+-]*$
-  def identifier
-    # Replace non-word chars with underscores, then make sure it starts with
-    # valid chars
-    email.gsub(/\W/, '_').gsub(/\A([\W\_])+/, '')
-  end
-
-  def is_admin?
-    admin
-  end
-
-  def require_ssh_key?
-    keys.count == 0
-  end
-
-  def can_create_project?
-    projects_limit > personal_projects.count
-  end
-
-  def can_create_group?
-    is_admin?
-  end
-
-  def abilities
-    @abilities ||= begin
-                     abilities = Six.new
-                     abilities << Ability
-                     abilities
-                   end
-  end
-
-  def can? action, subject
-    abilities.allowed?(self, action, subject)
-  end
-
-  def last_activity_project
-    projects.first
-  end
-
-  def first_name
-    name.split.first unless name.blank?
-  end
-
-  def cared_merge_requests
-    MergeRequest.where("author_id = :id or assignee_id = :id", id: self.id)
-  end
-
-  # Remove user from all projects and
-  # set blocked attribute to true
-  def block
-    users_projects.find_each do |membership|
-      return false unless membership.destroy
-    end
-
-    self.blocked = true
-    save
-  end
-
-  def projects_limit_percent
-    return 100 if projects_limit.zero?
-    (personal_projects.count.to_f / projects_limit) * 100
-  end
-
-  def recent_push project_id = nil
-    # Get push events not earlier than 2 hours ago
-    events = recent_events.code_push.where("created_at > ?", Time.now - 2.hours)
-    events = events.where(project_id: project_id) if project_id
-
-    # Take only latest one
-    events = events.recent.limit(1).first
-  end
-
-  def projects_sorted_by_activity
-    authorized_projects.sorted_by_activity
-  end
-
-  def several_namespaces?
-    namespaces.size > 1
-  end
-
-  def namespace_id
-    namespace.try :id
-  end
-end
diff --git a/app/roles/authority.rb b/app/roles/authority.rb
deleted file mode 100644 (file)
index 7727848..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-# == Authority role
-#
-# Control access to project repository based on users role in team
-#
-# Used by Project
-#
-module Authority
-  # Compatible with all access rights
-  # Should be rewrited for new access rights
-  def add_access(user, *access)
-    access = if access.include?(:admin)
-               { project_access: UsersProject::MASTER }
-             elsif access.include?(:write)
-               { project_access: UsersProject::DEVELOPER }
-             else
-               { project_access: UsersProject::REPORTER }
-             end
-    opts = { user: user }
-    opts.merge!(access)
-    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 repository_readers
-    repository_members[UsersProject::REPORTER]
-  end
-
-  def repository_writers
-    repository_members[UsersProject::DEVELOPER]
-  end
-
-  def repository_masters
-    repository_members[UsersProject::MASTER]
-  end
-
-  def repository_members
-    keys = Hash.new {|h,k| h[k] = [] }
-    UsersProject.select("keys.identifier, project_access").
-        joins(user: :keys).where(project_id: id).
-        each {|row| keys[row.project_access] << [row.identifier] }
-
-    keys[UsersProject::REPORTER] += deploy_keys.pluck(:identifier)
-    keys
-  end
-
-  def allow_read_for?(user)
-    !users_projects.where(user_id: user.id).empty?
-  end
-
-  def guest_access_for?(user)
-    !users_projects.where(user_id: user.id).empty?
-  end
-
-  def report_access_for?(user)
-    !users_projects.where(user_id: user.id, project_access: [UsersProject::REPORTER, UsersProject::DEVELOPER, UsersProject::MASTER]).empty?
-  end
-
-  def dev_access_for?(user)
-    !users_projects.where(user_id: user.id, project_access: [UsersProject::DEVELOPER, UsersProject::MASTER]).empty?
-  end
-
-  def master_access_for?(user)
-    !users_projects.where(user_id: user.id, project_access: [UsersProject::MASTER]).empty?
-  end
-end
diff --git a/app/roles/namespaced_project.rb b/app/roles/namespaced_project.rb
deleted file mode 100644 (file)
index 0f9fb05..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-# == NamespacedProject role
-#
-# Provides extra functionality for Project related to namespaces like:
-#  - transfer project between namespaces
-#  - name, path including namespece
-#  - project owner based on namespace
-#
-# Used by Project
-#
-module NamespacedProject
-  def transfer(new_namespace)
-    Project.transaction do
-      old_namespace = namespace
-      self.namespace = new_namespace
-
-      old_dir = old_namespace.try(:path) || ''
-      new_dir = new_namespace.try(:path) || ''
-
-      old_repo = if old_dir.present?
-                   File.join(old_dir, self.path)
-                 else
-                   self.path
-                 end
-
-      if Project.where(path: self.path, namespace_id: new_namespace.try(:id)).present?
-        raise TransferError.new("Project with same path in target namespace already exists")
-      end
-
-      Gitlab::ProjectMover.new(self, old_dir, new_dir).execute
-
-      git_host.move_repository(old_repo, self)
-
-      save!
-    end
-  rescue Gitlab::ProjectMover::ProjectMoveError => ex
-    raise Project::TransferError.new(ex.message)
-  end
-
-  def name_with_namespace
-    @name_with_namespace ||= begin
-                               if namespace
-                                 namespace.human_name + " / " + name
-                               else
-                                 name
-                               end
-                             end
-  end
-
-  def namespace_owner
-    namespace.try(:owner)
-  end
-
-  def path_with_namespace
-    if namespace
-      namespace.path + '/' + path
-    else
-      path
-    end
-  end
-end
diff --git a/app/roles/note_event.rb b/app/roles/note_event.rb
deleted file mode 100644 (file)
index 8e311ea..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-# == NoteEvent role
-#
-# Extends Event model functionality by providing extra methods related to comment events
-#
-# Used by Event
-#
-module NoteEvent
-  def note_commit_id
-    target.commit_id
-  end
-
-  def note_short_commit_id
-    note_commit_id[0..8]
-  end
-
-  def note_commit?
-    target.noteable_type == "Commit"
-  end
-
-  def note_target
-    target.noteable
-  end
-
-  def note_target_id
-    if note_commit?
-      target.commit_id
-    else
-      target.noteable_id.to_s
-    end
-  end
-
-  def wall_note?
-    target.noteable_type.blank?
-  end
-
-  def note_target_type
-    if target.noteable_type.present?
-      target.noteable_type.titleize
-    else
-      "Wall"
-    end.downcase
-  end
-end
diff --git a/app/roles/push_event.rb b/app/roles/push_event.rb
deleted file mode 100644 (file)
index ac9c38c..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-# == PushEvent role
-#
-# Extends Event model functionality by providing extra methods related to push events
-#
-# Used by Event
-#
-module PushEvent
-  def valid_push?
-    data[:ref]
-  rescue => ex
-    false
-  end
-
-  def tag?
-    data[:ref]["refs/tags"]
-  end
-
-  def branch?
-    data[:ref]["refs/heads"]
-  end
-
-  def new_branch?
-    commit_from =~ /^00000/
-  end
-
-  def new_ref?
-    commit_from =~ /^00000/
-  end
-
-  def rm_ref?
-    commit_to =~ /^00000/
-  end
-
-  def md_ref?
-    !(rm_ref? || new_ref?)
-  end
-
-  def commit_from
-    data[:before]
-  end
-
-  def commit_to
-    data[:after]
-  end
-
-  def ref_name
-    if tag?
-      tag_name
-    else
-      branch_name
-    end
-  end
-
-  def branch_name
-    @branch_name ||= data[:ref].gsub("refs/heads/", "")
-  end
-
-  def tag_name
-    @tag_name ||= data[:ref].gsub("refs/tags/", "")
-  end
-
-  # Max 20 commits from push DESC
-  def commits
-    @commits ||= data[:commits].map { |commit| project.commit(commit[:id]) }.reverse
-  end
-
-  def commits_count
-    data[:total_commits_count] || commits.count || 0
-  end
-
-  def ref_type
-    tag? ? "tag" : "branch"
-  end
-
-  def push_action_name
-    if new_ref?
-      "pushed new"
-    elsif rm_ref?
-      "deleted"
-    else
-      "pushed to"
-    end
-  end
-
-  def parent_commit
-    project.commit(commit_from)
-  rescue => ex
-    nil
-  end
-
-  def last_commit
-    project.commit(commit_to)
-  rescue => ex
-    nil
-  end
-
-  def push_with_commits?
-    md_ref? && commits.any? && parent_commit && last_commit
-  rescue Grit::NoSuchPathError
-    false
-  end
-
-  def last_push_to_non_root?
-    branch? && project.default_branch != branch_name
-  end
-end
diff --git a/app/roles/push_observer.rb b/app/roles/push_observer.rb
deleted file mode 100644 (file)
index 42979f4..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-# == PushObserver role
-#
-# Includes methods to be triggered on push to project repository.
-#
-#
-# Used by Project
-# Triggered by PostReceive job
-#
-module PushObserver
-  # This method will be called after each post receive and only if the provided
-  # user is present in GitLab.
-  #
-  # All callbacks for post receive should be placed here.
-  def trigger_post_receive(oldrev, newrev, ref, user)
-    data = post_receive_data(oldrev, newrev, ref, user)
-
-    # Create push event
-    self.observe_push(data)
-
-    if push_to_branch? ref, oldrev
-      # Close merged MR
-      self.update_merge_requests(oldrev, newrev, ref, user)
-
-      # Execute web hooks
-      self.execute_hooks(data.dup)
-
-      # Execute project services
-      self.execute_services(data.dup)
-    end
-
-    # Create satellite
-    self.satellite.create unless self.satellite.exists?
-
-    # Discover the default branch, but only if it hasn't already been set to
-    # something else
-    if default_branch.nil?
-      update_attributes(default_branch: discover_default_branch)
-    end
-  end
-
-  def push_to_branch? ref, oldrev
-    ref_parts = ref.split('/')
-
-    # Return if this is not a push to a branch (e.g. new commits)
-    !(ref_parts[1] !~ /heads/ || oldrev == "00000000000000000000000000000000")
-  end
-
-  def observe_push(data)
-    Event.create(
-      project: self,
-      action: Event::Pushed,
-      data: data,
-      author_id: data[:user_id]
-    )
-  end
-
-  def execute_hooks(data)
-    hooks.each { |hook| hook.execute(data) }
-  end
-
-  def execute_services(data)
-    services.each do |service|
-
-      # Call service hook only if it is active
-      service.execute(data) if service.active
-    end
-  end
-
-  # Produce a hash of post-receive data
-  #
-  # data = {
-  #   before: String,
-  #   after: String,
-  #   ref: String,
-  #   user_id: String,
-  #   user_name: String,
-  #   repository: {
-  #     name: String,
-  #     url: String,
-  #     description: String,
-  #     homepage: String,
-  #   },
-  #   commits: Array,
-  #   total_commits_count: Fixnum
-  # }
-  #
-  def post_receive_data(oldrev, newrev, ref, user)
-
-    push_commits = commits_between(oldrev, newrev)
-
-    # Total commits count
-    push_commits_count = push_commits.size
-
-    # Get latest 20 commits ASC
-    push_commits_limited = push_commits.last(20)
-
-    # Hash to be passed as post_receive_data
-    data = {
-      before: oldrev,
-      after: newrev,
-      ref: ref,
-      user_id: user.id,
-      user_name: user.name,
-      repository: {
-        name: name,
-        url: url_to_repo,
-        description: description,
-        homepage: web_url,
-      },
-      commits: [],
-      total_commits_count: push_commits_count
-    }
-
-    # For perfomance purposes maximum 20 latest commits
-    # will be passed as post receive hook data.
-    #
-    push_commits_limited.each do |commit|
-      data[:commits] << {
-        id: commit.id,
-        message: commit.safe_message,
-        timestamp: commit.date.xmlschema,
-        url: "#{Gitlab.config.gitlab.url}/#{path_with_namespace}/commit/#{commit.id}",
-        author: {
-          name: commit.author_name,
-          email: commit.author_email
-        }
-      }
-    end
-
-    data
-  end
-
-  def update_merge_requests(oldrev, newrev, ref, user)
-    return true unless ref =~ /heads/
-    branch_name = ref.gsub("refs/heads/", "")
-    c_ids = self.commits_between(oldrev, newrev).map(&:id)
-
-    # Update code for merge requests
-    mrs = self.merge_requests.opened.find_all_by_branch(branch_name).all
-    mrs.each { |merge_request| merge_request.reload_code; merge_request.mark_as_unchecked }
-
-    # Close merge requests
-    mrs = self.merge_requests.opened.where(target_branch: branch_name).all
-    mrs = mrs.select(&:last_commit).select { |mr| c_ids.include?(mr.last_commit.id) }
-    mrs.each { |merge_request| merge_request.merge!(user.id) }
-
-    true
-  end
-end
diff --git a/app/roles/repository.rb b/app/roles/repository.rb
deleted file mode 100644 (file)
index 8896569..0000000
+++ /dev/null
@@ -1,216 +0,0 @@
-# == Repository role
-#
-# Provides access to git repository resources like commits, branches etc..
-# Allows you to manage repository via gitolite interface(git_host)
-#
-# Used by Project
-#
-module Repository
-  include GitHost
-
-  def valid_repo?
-    repo
-  rescue
-    errors.add(:path, "Invalid repository path")
-    false
-  end
-
-  def empty_repo?
-    !repo_exists? || !has_commits?
-  end
-
-  def commit(commit_id = nil)
-    Commit.find_or_first(repo, commit_id, root_ref)
-  end
-
-  def fresh_commits(n = 10)
-    Commit.fresh_commits(repo, n)
-  end
-
-  def commits_with_refs(n = 20)
-    Commit.commits_with_refs(repo, n)
-  end
-
-  def commits_since(date)
-    Commit.commits_since(repo, date)
-  end
-
-  def commits(ref, path = nil, limit = nil, offset = nil)
-    Commit.commits(repo, ref, path, limit, offset)
-  end
-
-  def last_commit_for(ref, path = nil)
-    commits(ref, path, 1).first
-  end
-
-  def commits_between(from, to)
-    Commit.commits_between(repo, from, to)
-  end
-
-  def satellite
-    @satellite ||= Gitlab::Satellite::Satellite.new(self)
-  end
-
-  def has_post_receive_file?
-    !!hook_file
-  end
-
-  def valid_post_receive_file?
-    valid_hook_file == hook_file
-  end
-
-  def valid_hook_file
-    @valid_hook_file ||= File.read(Rails.root.join('lib', 'hooks', 'post-receive'))
-  end
-
-  def hook_file
-    @hook_file ||= begin
-                     hook_path = File.join(path_to_repo, 'hooks', 'post-receive')
-                     File.read(hook_path) if File.exists?(hook_path)
-                   end
-  end
-
-  # Returns an Array of branch names
-  def branch_names
-    repo.branches.collect(&:name).sort
-  end
-
-  # Returns an Array of Branches
-  def branches
-    repo.branches.sort_by(&:name)
-  end
-
-  # Returns an Array of tag names
-  def tag_names
-    repo.tags.collect(&:name).sort.reverse
-  end
-
-  # Returns an Array of Tags
-  def tags
-    repo.tags.sort_by(&:name).reverse
-  end
-
-  # Returns an Array of branch and tag names
-  def ref_names
-    [branch_names + tag_names].flatten
-  end
-
-  def repo
-    @repo ||= Grit::Repo.new(path_to_repo)
-  end
-
-  def url_to_repo
-    git_host.url_to_repo(path_with_namespace)
-  end
-
-  def path_to_repo
-    File.join(Gitlab.config.gitolite.repos_path, "#{path_with_namespace}.git")
-  end
-
-  def namespace_dir
-    namespace.try(:path) || ''
-  end
-
-  def update_repository
-    git_host.update_repository(self)
-  end
-
-  def destroy_repository
-    git_host.remove_repository(self)
-  end
-
-  def repo_exists?
-    @repo_exists ||= (repo && !repo.branches.empty?)
-  rescue
-    @repo_exists = false
-  end
-
-  def heads
-    @heads ||= repo.heads
-  end
-
-  def tree(fcommit, path = nil)
-    fcommit = commit if fcommit == :head
-    tree = fcommit.tree
-    path ? (tree / path) : tree
-  end
-
-  def open_branches
-    if protected_branches.empty?
-      self.repo.heads
-    else
-      pnames = protected_branches.map(&:name)
-      self.repo.heads.reject { |h| pnames.include?(h.name) }
-    end.sort_by(&:name)
-  end
-
-  # Discovers the default branch based on the repository's available branches
-  #
-  # - If no branches are present, returns nil
-  # - If one branch is present, returns its name
-  # - If two or more branches are present, returns the one that has a name
-  #   matching root_ref (default_branch or 'master' if default_branch is nil)
-  def discover_default_branch
-    if branch_names.length == 0
-      nil
-    elsif branch_names.length == 1
-      branch_names.first
-    else
-      branch_names.select { |v| v == root_ref }.first
-    end
-  end
-
-  def has_commits?
-    !!commit
-  rescue Grit::NoSuchPathError
-    false
-  end
-
-  def root_ref
-    default_branch || "master"
-  end
-
-  def root_ref?(branch)
-    root_ref == branch
-  end
-
-  # Archive Project to .tar.gz
-  #
-  # Already packed repo archives stored at
-  # app_root/tmp/repositories/project_name/project_name-commit-id.tag.gz
-  #
-  def archive_repo(ref)
-    ref = ref || self.root_ref
-    commit = self.commit(ref)
-    return nil unless commit
-
-    # Build file path
-    file_name = self.path + "-" + commit.id.to_s + ".tar.gz"
-    storage_path = Rails.root.join("tmp", "repositories", self.path_with_namespace)
-    file_path = File.join(storage_path, file_name)
-
-    # Put files into a directory before archiving
-    prefix = self.path + "/"
-
-    # Create file if not exists
-    unless File.exists?(file_path)
-      FileUtils.mkdir_p storage_path
-      file = self.repo.archive_to_file(ref, prefix,  file_path)
-    end
-
-    file_path
-  end
-
-  def ssh_url_to_repo
-    url_to_repo
-  end
-
-  def http_url_to_repo
-    http_url = [Gitlab.config.gitlab.url, "/", path_with_namespace, ".git"].join('')
-  end
-
-  # Check if current branch name is marked as protected in the system
-  def protected_branch? branch_name
-    protected_branches.map(&:name).include?(branch_name)
-  end
-end
diff --git a/app/roles/team.rb b/app/roles/team.rb
deleted file mode 100644 (file)
index 8e431fc..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-# == Team role
-#
-# Provides functionality to manage project team
-#  - add user/users to project
-#  - update existing membership
-#  - remove users from project team
-#
-# Used by Project
-#
-module Team
-  def team_member_by_name_or_email(name = nil, email = nil)
-    user = users.where("name like ? or email like ?", name, email).first
-    users_projects.where(user: user) if user
-  end
-
-  # Get Team Member record by user id
-  def team_member_by_id(user_id)
-    users_projects.find_by_user_id(user_id)
-  end
-
-  # Add user to project
-  # with passed access role
-  def add_user_to_team(user, access_role)
-    add_user_id_to_team(user.id, access_role)
-  end
-
-  # Add multiple users to project
-  # with same access role
-  def add_users_to_team(users, access_role)
-    add_users_ids_to_team(users.map(&:id), access_role)
-  end
-
-  # Add user to project
-  # with passed access role by user id
-  def add_user_id_to_team(user_id, access_role)
-    users_projects.create(
-      user_id: user_id,
-      project_access: access_role
-    )
-  end
-
-  # Add multiple users to project
-  # with same access role by user ids
-  def add_users_ids_to_team(users_ids, access_role)
-    UsersProject.bulk_import(self, users_ids, access_role)
-  end
-
-  # Update multiple project users
-  # to same access role by user ids
-  def update_users_ids_to_role(users_ids, access_role)
-    UsersProject.bulk_update(self, users_ids, access_role)
-  end
-
-  # Delete multiple users from project by user ids
-  def delete_users_ids_from_team(users_ids)
-    UsersProject.bulk_delete(self, users_ids)
-  end
-
-  # Remove all users from project team
-  def truncate_team
-    UsersProject.truncate_team(self)
-  end
-end
similarity index 100%
rename from app/roles/git_host.rb
rename to lib/git_host.rb
similarity index 99%
rename from app/roles/issue_commonality.rb
rename to lib/issue_commonality.rb
index 3948ef1..b755936 100644 (file)
@@ -68,5 +68,4 @@ module IssueCommonality
   def is_being_reopened?
     closed_changed? && !closed
   end
-
 end
similarity index 100%
rename from app/roles/votes.rb
rename to lib/votes.rb
index eb2717e..5f6244e 100644 (file)
@@ -185,4 +185,14 @@ describe User do
 
     it { User.not_in_project(@project).should == [@user, @project.owner] }
   end
+
+  describe 'normal user' do
+    let(:user) { create(:user, name: 'John Smith') }
+
+    it { user.is_admin?.should be_false }
+    it { user.require_ssh_key?.should be_true }
+    it { user.can_create_group?.should be_false }
+    it { user.can_create_project?.should be_true }
+    it { user.first_name.should == 'John' }
+  end
 end
diff --git a/spec/roles/account_role_spec.rb b/spec/roles/account_role_spec.rb
deleted file mode 100644 (file)
index f7a128d..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-require 'spec_helper'
-
-describe User, "Account" do
-  describe 'normal user' do
-    let(:user) { create(:user, name: 'John Smith') }
-
-    it { user.is_admin?.should be_false }
-    it { user.require_ssh_key?.should be_true }
-    it { user.can_create_group?.should be_false }
-    it { user.can_create_project?.should be_true }
-    it { user.first_name.should == 'John' }
-  end
-end