Commit 39ba934c0a65f571214998e056e925b61f389360
1 parent
e6c0673e
Exists in
master
and in
4 other branches
REpostiry, Team models
Showing
31 changed files
with
329 additions
and
315 deletions
Show diff stats
.gitignore
Gemfile
Gemfile.lock
| ... | ... | @@ -132,6 +132,8 @@ GEM |
| 132 | 132 | chosen-rails (0.9.8) |
| 133 | 133 | railties (~> 3.0) |
| 134 | 134 | thor (~> 0.14) |
| 135 | + code_analyzer (0.3.1) | |
| 136 | + sexp_processor | |
| 135 | 137 | coderay (1.0.8) |
| 136 | 138 | coffee-rails (3.2.2) |
| 137 | 139 | coffee-script (>= 2.2.0) |
| ... | ... | @@ -302,6 +304,7 @@ GEM |
| 302 | 304 | pg (0.14.1) |
| 303 | 305 | polyglot (0.3.3) |
| 304 | 306 | posix-spawn (0.3.6) |
| 307 | + progressbar (0.12.0) | |
| 305 | 308 | pry (0.9.10) |
| 306 | 309 | coderay (~> 1.0.5) |
| 307 | 310 | method_source (~> 0.8) |
| ... | ... | @@ -335,6 +338,14 @@ GEM |
| 335 | 338 | rails-dev-tweaks (0.6.1) |
| 336 | 339 | actionpack (~> 3.1) |
| 337 | 340 | railties (~> 3.1) |
| 341 | + rails_best_practices (1.13.2) | |
| 342 | + activesupport | |
| 343 | + awesome_print | |
| 344 | + code_analyzer | |
| 345 | + colored | |
| 346 | + erubis | |
| 347 | + i18n | |
| 348 | + progressbar | |
| 338 | 349 | railties (3.2.9) |
| 339 | 350 | actionpack (= 3.2.9) |
| 340 | 351 | activesupport (= 3.2.9) |
| ... | ... | @@ -393,6 +404,7 @@ GEM |
| 393 | 404 | multi_json (~> 1.0) |
| 394 | 405 | rubyzip |
| 395 | 406 | settingslogic (2.0.8) |
| 407 | + sexp_processor (4.1.3) | |
| 396 | 408 | shoulda-matchers (1.3.0) |
| 397 | 409 | activesupport (>= 3.0.0) |
| 398 | 410 | simplecov (0.7.1) |
| ... | ... | @@ -512,6 +524,7 @@ DEPENDENCIES |
| 512 | 524 | rack-mini-profiler |
| 513 | 525 | rails (= 3.2.9) |
| 514 | 526 | rails-dev-tweaks |
| 527 | + rails_best_practices | |
| 515 | 528 | raphael-rails (= 1.5.2) |
| 516 | 529 | rb-fsevent |
| 517 | 530 | rb-inotify | ... | ... |
app/contexts/commit_load_context.rb
app/contexts/notes/load_context.rb
| ... | ... | @@ -18,7 +18,7 @@ module Notes |
| 18 | 18 | project.snippets.find(target_id).notes.fresh |
| 19 | 19 | when "wall" |
| 20 | 20 | # this is the only case, where the order is DESC |
| 21 | - project.common_notes.order("created_at DESC, id DESC").limit(50) | |
| 21 | + project.notes.common.inc_author_project.order("created_at DESC, id DESC").limit(50) | |
| 22 | 22 | end |
| 23 | 23 | |
| 24 | 24 | @notes = if after_id | ... | ... |
app/controllers/application_controller.rb
app/controllers/commits_controller.rb
| ... | ... | @@ -9,10 +9,10 @@ class CommitsController < ProjectResourceController |
| 9 | 9 | before_filter :require_non_empty_project |
| 10 | 10 | |
| 11 | 11 | def show |
| 12 | - @repo = @project.repo | |
| 12 | + @repo = @project.repository | |
| 13 | 13 | @limit, @offset = (params[:limit] || 40), (params[:offset] || 0) |
| 14 | 14 | |
| 15 | - @commits = @project.commits(@ref, @path, @limit, @offset) | |
| 15 | + @commits = @repo.commits(@ref, @path, @limit, @offset) | |
| 16 | 16 | @commits = CommitDecorator.decorate(@commits) |
| 17 | 17 | |
| 18 | 18 | respond_to do |format| | ... | ... |
app/controllers/project_resource_controller.rb
app/controllers/refs_controller.rb
| ... | ... | @@ -31,7 +31,7 @@ class RefsController < ProjectResourceController |
| 31 | 31 | contents = @tree.contents |
| 32 | 32 | @logs = contents.map do |content| |
| 33 | 33 | file = params[:path] ? File.join(params[:path], content.name) : content.name |
| 34 | - last_commit = @project.commits(@commit.id, file, 1).last | |
| 34 | + last_commit = @repo.commits(@commit.id, file, 1).last | |
| 35 | 35 | last_commit = CommitDecorator.decorate(last_commit) |
| 36 | 36 | { |
| 37 | 37 | file_name: content.name, |
| ... | ... | @@ -45,10 +45,10 @@ class RefsController < ProjectResourceController |
| 45 | 45 | def define_tree_vars |
| 46 | 46 | params[:path] = nil if params[:path].blank? |
| 47 | 47 | |
| 48 | - @repo = project.repo | |
| 49 | - @commit = project.commit(@ref) | |
| 48 | + @repo = project.repository | |
| 49 | + @commit = @repo.commit(@ref) | |
| 50 | 50 | @commit = CommitDecorator.decorate(@commit) |
| 51 | - @tree = Tree.new(@commit.tree, project, @ref, params[:path]) | |
| 51 | + @tree = Tree.new(@commit.tree, @ref, params[:path]) | |
| 52 | 52 | @tree = TreeDecorator.new(@tree) |
| 53 | 53 | @hex_path = Digest::SHA1.hexdigest(params[:path] || "") |
| 54 | 54 | ... | ... |
app/controllers/repositories_controller.rb
| ... | ... | @@ -5,19 +5,19 @@ class RepositoriesController < ProjectResourceController |
| 5 | 5 | before_filter :require_non_empty_project |
| 6 | 6 | |
| 7 | 7 | def show |
| 8 | - @activities = @project.commits_with_refs(20) | |
| 8 | + @activities = @repository.commits_with_refs(20) | |
| 9 | 9 | end |
| 10 | 10 | |
| 11 | 11 | def branches |
| 12 | - @branches = @project.branches | |
| 12 | + @branches = @repository.branches | |
| 13 | 13 | end |
| 14 | 14 | |
| 15 | 15 | def tags |
| 16 | - @tags = @project.tags | |
| 16 | + @tags = @repository.tags | |
| 17 | 17 | end |
| 18 | 18 | |
| 19 | 19 | def stats |
| 20 | - @stats = Gitlab::GitStats.new(@project.repo, @project.root_ref) | |
| 20 | + @stats = Gitlab::GitStats.new(@repository.raw, @repository.root_ref) | |
| 21 | 21 | @graph = @stats.graph |
| 22 | 22 | end |
| 23 | 23 | |
| ... | ... | @@ -27,7 +27,7 @@ class RepositoriesController < ProjectResourceController |
| 27 | 27 | end |
| 28 | 28 | |
| 29 | 29 | |
| 30 | - file_path = @project.archive_repo(params[:ref]) | |
| 30 | + file_path = @repository.archive_repo(params[:ref]) | |
| 31 | 31 | |
| 32 | 32 | if file_path |
| 33 | 33 | # Send file to user | ... | ... |
app/decorators/tree_decorator.rb
| ... | ... | @@ -6,16 +6,14 @@ class TreeDecorator < ApplicationDecorator |
| 6 | 6 | part_path = "" |
| 7 | 7 | parts = path.split("\/") |
| 8 | 8 | |
| 9 | - #parts = parts[0...-1] if is_blob? | |
| 10 | - | |
| 11 | - yield(h.link_to("..", "#")) if parts.count > max_links | |
| 9 | + yield('..', nil) if parts.count > max_links | |
| 12 | 10 | |
| 13 | 11 | parts.each do |part| |
| 14 | 12 | part_path = File.join(part_path, part) unless part_path.empty? |
| 15 | 13 | part_path = part if part_path.empty? |
| 16 | 14 | |
| 17 | 15 | next unless parts.last(2).include?(part) if parts.count > max_links |
| 18 | - yield(h.link_to(h.truncate(part, length: 40), h.project_tree_path(project, h.tree_join(ref, part_path)))) | |
| 16 | + yield(part, h.tree_join(ref, part_path)) | |
| 19 | 17 | end |
| 20 | 18 | end |
| 21 | 19 | end |
| ... | ... | @@ -26,7 +24,7 @@ class TreeDecorator < ApplicationDecorator |
| 26 | 24 | |
| 27 | 25 | def up_dir_path |
| 28 | 26 | file = File.join(path, "..") |
| 29 | - h.project_tree_path(project, h.tree_join(ref, file)) | |
| 27 | + h.tree_join(ref, file) | |
| 30 | 28 | end |
| 31 | 29 | |
| 32 | 30 | def readme | ... | ... |
app/helpers/application_helper.rb
| ... | ... | @@ -62,9 +62,11 @@ module ApplicationHelper |
| 62 | 62 | end |
| 63 | 63 | |
| 64 | 64 | def grouped_options_refs(destination = :tree) |
| 65 | + repository = @project.repository | |
| 66 | + | |
| 65 | 67 | options = [ |
| 66 | - ["Branch", @project.branch_names ], | |
| 67 | - [ "Tag", @project.tag_names ] | |
| 68 | + ["Branch", repository.branch_names ], | |
| 69 | + [ "Tag", repository.tag_names ] | |
| 68 | 70 | ] |
| 69 | 71 | |
| 70 | 72 | # If reference is commit id - |
| ... | ... | @@ -103,12 +105,12 @@ module ApplicationHelper |
| 103 | 105 | if @project && !@project.new_record? |
| 104 | 106 | project_nav = [ |
| 105 | 107 | { label: "#{@project.name} Issues", url: project_issues_path(@project) }, |
| 106 | - { label: "#{@project.name} Commits", url: project_commits_path(@project, @ref || @project.root_ref) }, | |
| 108 | + { label: "#{@project.name} Commits", url: project_commits_path(@project, @ref || @project.repository.root_ref) }, | |
| 107 | 109 | { label: "#{@project.name} Merge Requests", url: project_merge_requests_path(@project) }, |
| 108 | 110 | { label: "#{@project.name} Milestones", url: project_milestones_path(@project) }, |
| 109 | 111 | { label: "#{@project.name} Snippets", url: project_snippets_path(@project) }, |
| 110 | 112 | { label: "#{@project.name} Team", url: project_team_index_path(@project) }, |
| 111 | - { label: "#{@project.name} Tree", url: project_tree_path(@project, @ref || @project.root_ref) }, | |
| 113 | + { label: "#{@project.name} Tree", url: project_tree_path(@project, @ref || @project.repository.root_ref) }, | |
| 112 | 114 | { label: "#{@project.name} Wall", url: wall_project_path(@project) }, |
| 113 | 115 | { label: "#{@project.name} Wiki", url: project_wikis_path(@project) }, |
| 114 | 116 | ] | ... | ... |
app/helpers/events_helper.rb
| ... | ... | @@ -20,20 +20,6 @@ module EventsHelper |
| 20 | 20 | [event.action_name, target].join(" ") |
| 21 | 21 | end |
| 22 | 22 | |
| 23 | - def event_image event | |
| 24 | - event_image_path = if event.push? | |
| 25 | - "event_push.png" | |
| 26 | - elsif event.merged? | |
| 27 | - "event_mr_merged.png" | |
| 28 | - end | |
| 29 | - | |
| 30 | - return nil unless event_image_path | |
| 31 | - | |
| 32 | - content_tag :div, class: 'event_icon' do | |
| 33 | - image_tag event_image_path | |
| 34 | - end | |
| 35 | - end | |
| 36 | - | |
| 37 | 23 | def event_filter_link key, tooltip |
| 38 | 24 | key = key.to_s |
| 39 | 25 | ... | ... |
app/models/ability.rb
| ... | ... | @@ -15,17 +15,19 @@ class Ability |
| 15 | 15 | def project_abilities(user, project) |
| 16 | 16 | rules = [] |
| 17 | 17 | |
| 18 | + team = project.team | |
| 19 | + | |
| 18 | 20 | # Rules based on role in project |
| 19 | - if project.master_access_for?(user) | |
| 21 | + if team.masters.include?(user) | |
| 20 | 22 | rules << project_master_rules |
| 21 | 23 | |
| 22 | - elsif project.dev_access_for?(user) | |
| 24 | + elsif team.developers.include?(user) | |
| 23 | 25 | rules << project_dev_rules |
| 24 | 26 | |
| 25 | - elsif project.report_access_for?(user) | |
| 27 | + elsif team.reporters.include?(user) | |
| 26 | 28 | rules << project_report_rules |
| 27 | 29 | |
| 28 | - elsif project.guest_access_for?(user) | |
| 30 | + elsif team.guests.include?(user) | |
| 29 | 31 | rules << project_guest_rules |
| 30 | 32 | end |
| 31 | 33 | ... | ... |
app/models/commit.rb
| ... | ... | @@ -83,8 +83,8 @@ class Commit |
| 83 | 83 | |
| 84 | 84 | return result unless from && to |
| 85 | 85 | |
| 86 | - first = project.commit(to.try(:strip)) | |
| 87 | - last = project.commit(from.try(:strip)) | |
| 86 | + first = project.repository.commit(to.try(:strip)) | |
| 87 | + last = project.repository.commit(from.try(:strip)) | |
| 88 | 88 | |
| 89 | 89 | if first && last |
| 90 | 90 | result[:same] = (first.id == last.id) | ... | ... |
app/models/event.rb
| ... | ... | @@ -110,26 +110,6 @@ class Event < ActiveRecord::Base |
| 110 | 110 | target_type == "MergeRequest" |
| 111 | 111 | end |
| 112 | 112 | |
| 113 | - def new_issue? | |
| 114 | - target_type == "Issue" && | |
| 115 | - action == Created | |
| 116 | - end | |
| 117 | - | |
| 118 | - def new_merge_request? | |
| 119 | - target_type == "MergeRequest" && | |
| 120 | - action == Created | |
| 121 | - end | |
| 122 | - | |
| 123 | - def changed_merge_request? | |
| 124 | - target_type == "MergeRequest" && | |
| 125 | - [Closed, Reopened].include?(action) | |
| 126 | - end | |
| 127 | - | |
| 128 | - def changed_issue? | |
| 129 | - target_type == "Issue" && | |
| 130 | - [Closed, Reopened].include?(action) | |
| 131 | - end | |
| 132 | - | |
| 133 | 113 | def joined? |
| 134 | 114 | action == Joined |
| 135 | 115 | end | ... | ... |
app/models/gitlab_ci_service.rb
app/models/note.rb
| ... | ... | @@ -4,7 +4,6 @@ |
| 4 | 4 | # |
| 5 | 5 | # id :integer not null, primary key |
| 6 | 6 | # note :text |
| 7 | -# noteable_id :string(255) | |
| 8 | 7 | # noteable_type :string(255) |
| 9 | 8 | # author_id :integer |
| 10 | 9 | # created_at :datetime not null |
| ... | ... | @@ -12,6 +11,8 @@ |
| 12 | 11 | # project_id :integer |
| 13 | 12 | # attachment :string(255) |
| 14 | 13 | # line_code :string(255) |
| 14 | +# commit_id :string(255) | |
| 15 | +# noteable_id :integer | |
| 15 | 16 | # |
| 16 | 17 | |
| 17 | 18 | require 'carrierwave/orm/activerecord' |
| ... | ... | @@ -42,7 +43,7 @@ class Note < ActiveRecord::Base |
| 42 | 43 | |
| 43 | 44 | # Scopes |
| 44 | 45 | scope :for_commits, ->{ where(noteable_type: "Commit") } |
| 45 | - scope :common, ->{ where(noteable_id: nil, commit_id: nil) } | |
| 46 | + scope :common, ->{ where(noteable_type: ["", nil]) } | |
| 46 | 47 | scope :today, ->{ where("created_at >= :date", date: Date.today) } |
| 47 | 48 | scope :last_week, ->{ where("created_at >= :date", date: (Date.today - 7.days)) } |
| 48 | 49 | scope :since, ->(day) { where("created_at >= :date", date: (day)) } | ... | ... |
app/models/project.rb
| ... | ... | @@ -9,7 +9,7 @@ |
| 9 | 9 | # created_at :datetime not null |
| 10 | 10 | # updated_at :datetime not null |
| 11 | 11 | # private_flag :boolean default(TRUE), not null |
| 12 | -# owner_id :integer | |
| 12 | +# creator_id :integer | |
| 13 | 13 | # default_branch :string(255) |
| 14 | 14 | # issues_enabled :boolean default(TRUE), not null |
| 15 | 15 | # wall_enabled :boolean default(TRUE), not null |
| ... | ... | @@ -75,7 +75,6 @@ class Project < ActiveRecord::Base |
| 75 | 75 | validate :check_limit, :repo_name |
| 76 | 76 | |
| 77 | 77 | # Scopes |
| 78 | - scope :public_only, where(private_flag: false) | |
| 79 | 78 | scope :without_user, ->(user) { where("id NOT IN (:ids)", ids: user.authorized_projects.map(&:id) ) } |
| 80 | 79 | scope :not_in_group, ->(group) { where("id NOT IN (:ids)", ids: group.project_ids ) } |
| 81 | 80 | scope :in_namespace, ->(namespace) { where(namespace_id: namespace.id) } |
| ... | ... | @@ -162,6 +161,14 @@ class Project < ActiveRecord::Base |
| 162 | 161 | end |
| 163 | 162 | end |
| 164 | 163 | |
| 164 | + def team | |
| 165 | + @team ||= Team.new(self) | |
| 166 | + end | |
| 167 | + | |
| 168 | + def repository | |
| 169 | + @repository ||= Repository.new(path_with_namespace, default_branch) | |
| 170 | + end | |
| 171 | + | |
| 165 | 172 | def git_error? |
| 166 | 173 | error_code == :gitolite |
| 167 | 174 | end |
| ... | ... | @@ -198,10 +205,6 @@ class Project < ActiveRecord::Base |
| 198 | 205 | [Gitlab.config.gitlab.url, path_with_namespace].join("/") |
| 199 | 206 | end |
| 200 | 207 | |
| 201 | - def common_notes | |
| 202 | - notes.where(noteable_type: ["", nil]).inc_author_project | |
| 203 | - end | |
| 204 | - | |
| 205 | 208 | def build_commit_note(commit) |
| 206 | 209 | notes.new(commit_id: commit.id, noteable_type: "Commit") |
| 207 | 210 | end |
| ... | ... | @@ -214,14 +217,6 @@ class Project < ActiveRecord::Base |
| 214 | 217 | notes.where(commit_id: commit.id, noteable_type: "Commit").where("line_code IS NOT NULL") |
| 215 | 218 | end |
| 216 | 219 | |
| 217 | - def public? | |
| 218 | - !private_flag | |
| 219 | - end | |
| 220 | - | |
| 221 | - def private? | |
| 222 | - private_flag | |
| 223 | - end | |
| 224 | - | |
| 225 | 220 | def last_activity |
| 226 | 221 | last_event |
| 227 | 222 | end |
| ... | ... | @@ -284,33 +279,6 @@ class Project < ActiveRecord::Base |
| 284 | 279 | users_projects.find_by_user_id(user_id) |
| 285 | 280 | end |
| 286 | 281 | |
| 287 | - # Add user to project | |
| 288 | - # with passed access role | |
| 289 | - def add_user_to_team(user, access_role) | |
| 290 | - add_user_id_to_team(user.id, access_role) | |
| 291 | - end | |
| 292 | - | |
| 293 | - # Add multiple users to project | |
| 294 | - # with same access role | |
| 295 | - def add_users_to_team(users, access_role) | |
| 296 | - add_users_ids_to_team(users.map(&:id), access_role) | |
| 297 | - end | |
| 298 | - | |
| 299 | - # Add user to project | |
| 300 | - # with passed access role by user id | |
| 301 | - def add_user_id_to_team(user_id, access_role) | |
| 302 | - users_projects.create( | |
| 303 | - user_id: user_id, | |
| 304 | - project_access: access_role | |
| 305 | - ) | |
| 306 | - end | |
| 307 | - | |
| 308 | - # Add multiple users to project | |
| 309 | - # with same access role by user ids | |
| 310 | - def add_users_ids_to_team(users_ids, access_role) | |
| 311 | - UsersProject.bulk_import(self, users_ids, access_role) | |
| 312 | - end | |
| 313 | - | |
| 314 | 282 | # Update multiple project users |
| 315 | 283 | # to same access role by user ids |
| 316 | 284 | def update_users_ids_to_role(users_ids, access_role) |
| ... | ... | @@ -322,30 +290,6 @@ class Project < ActiveRecord::Base |
| 322 | 290 | UsersProject.bulk_delete(self, users_ids) |
| 323 | 291 | end |
| 324 | 292 | |
| 325 | - # Remove all users from project team | |
| 326 | - def truncate_team | |
| 327 | - UsersProject.truncate_team(self) | |
| 328 | - end | |
| 329 | - | |
| 330 | - # Compatible with all access rights | |
| 331 | - # Should be rewrited for new access rights | |
| 332 | - def add_access(user, *access) | |
| 333 | - access = if access.include?(:admin) | |
| 334 | - { project_access: UsersProject::MASTER } | |
| 335 | - elsif access.include?(:write) | |
| 336 | - { project_access: UsersProject::DEVELOPER } | |
| 337 | - else | |
| 338 | - { project_access: UsersProject::REPORTER } | |
| 339 | - end | |
| 340 | - opts = { user: user } | |
| 341 | - opts.merge!(access) | |
| 342 | - users_projects.create(opts) | |
| 343 | - end | |
| 344 | - | |
| 345 | - def reset_access(user) | |
| 346 | - users_projects.where(project_id: self.id, user_id: user.id).destroy if self.id | |
| 347 | - end | |
| 348 | - | |
| 349 | 293 | def repository_readers |
| 350 | 294 | repository_members[UsersProject::REPORTER] |
| 351 | 295 | end |
| ... | ... | @@ -368,26 +312,6 @@ class Project < ActiveRecord::Base |
| 368 | 312 | keys |
| 369 | 313 | end |
| 370 | 314 | |
| 371 | - def allow_read_for?(user) | |
| 372 | - !users_projects.where(user_id: user.id).empty? | |
| 373 | - end | |
| 374 | - | |
| 375 | - def guest_access_for?(user) | |
| 376 | - !users_projects.where(user_id: user.id).empty? | |
| 377 | - end | |
| 378 | - | |
| 379 | - def report_access_for?(user) | |
| 380 | - !users_projects.where(user_id: user.id, project_access: [UsersProject::REPORTER, UsersProject::DEVELOPER, UsersProject::MASTER]).empty? | |
| 381 | - end | |
| 382 | - | |
| 383 | - def dev_access_for?(user) | |
| 384 | - !users_projects.where(user_id: user.id, project_access: [UsersProject::DEVELOPER, UsersProject::MASTER]).empty? | |
| 385 | - end | |
| 386 | - | |
| 387 | - def master_access_for?(user) | |
| 388 | - !users_projects.where(user_id: user.id, project_access: [UsersProject::MASTER]).empty? | |
| 389 | - end | |
| 390 | - | |
| 391 | 315 | def transfer(new_namespace) |
| 392 | 316 | Project.transaction do |
| 393 | 317 | old_namespace = namespace |
| ... | ... | @@ -586,97 +510,21 @@ class Project < ActiveRecord::Base |
| 586 | 510 | end |
| 587 | 511 | |
| 588 | 512 | def empty_repo? |
| 589 | - !repo_exists? || !has_commits? | |
| 590 | - end | |
| 591 | - | |
| 592 | - def commit(commit_id = nil) | |
| 593 | - Commit.find_or_first(repo, commit_id, root_ref) | |
| 594 | - end | |
| 595 | - | |
| 596 | - def fresh_commits(n = 10) | |
| 597 | - Commit.fresh_commits(repo, n) | |
| 598 | - end | |
| 599 | - | |
| 600 | - def commits_with_refs(n = 20) | |
| 601 | - Commit.commits_with_refs(repo, n) | |
| 602 | - end | |
| 603 | - | |
| 604 | - def commits_since(date) | |
| 605 | - Commit.commits_since(repo, date) | |
| 606 | - end | |
| 607 | - | |
| 608 | - def commits(ref, path = nil, limit = nil, offset = nil) | |
| 609 | - Commit.commits(repo, ref, path, limit, offset) | |
| 610 | - end | |
| 611 | - | |
| 612 | - def last_commit_for(ref, path = nil) | |
| 613 | - commits(ref, path, 1).first | |
| 614 | - end | |
| 615 | - | |
| 616 | - def commits_between(from, to) | |
| 617 | - Commit.commits_between(repo, from, to) | |
| 513 | + !repository || repository.empty_repo? | |
| 618 | 514 | end |
| 619 | 515 | |
| 620 | 516 | def satellite |
| 621 | 517 | @satellite ||= Gitlab::Satellite::Satellite.new(self) |
| 622 | 518 | end |
| 623 | 519 | |
| 624 | - def has_post_receive_file? | |
| 625 | - !!hook_file | |
| 626 | - end | |
| 627 | - | |
| 628 | - def valid_post_receive_file? | |
| 629 | - valid_hook_file == hook_file | |
| 630 | - end | |
| 631 | - | |
| 632 | - def valid_hook_file | |
| 633 | - @valid_hook_file ||= File.read(Rails.root.join('lib', 'hooks', 'post-receive')) | |
| 634 | - end | |
| 635 | - | |
| 636 | - def hook_file | |
| 637 | - @hook_file ||= begin | |
| 638 | - hook_path = File.join(path_to_repo, 'hooks', 'post-receive') | |
| 639 | - File.read(hook_path) if File.exists?(hook_path) | |
| 640 | - end | |
| 641 | - end | |
| 642 | - | |
| 643 | - # Returns an Array of branch names | |
| 644 | - def branch_names | |
| 645 | - repo.branches.collect(&:name).sort | |
| 646 | - end | |
| 647 | - | |
| 648 | - # Returns an Array of Branches | |
| 649 | - def branches | |
| 650 | - repo.branches.sort_by(&:name) | |
| 651 | - end | |
| 652 | - | |
| 653 | - # Returns an Array of tag names | |
| 654 | - def tag_names | |
| 655 | - repo.tags.collect(&:name).sort.reverse | |
| 656 | - end | |
| 657 | - | |
| 658 | - # Returns an Array of Tags | |
| 659 | - def tags | |
| 660 | - repo.tags.sort_by(&:name).reverse | |
| 661 | - end | |
| 662 | - | |
| 663 | - # Returns an Array of branch and tag names | |
| 664 | - def ref_names | |
| 665 | - [branch_names + tag_names].flatten | |
| 666 | - end | |
| 667 | - | |
| 668 | 520 | def repo |
| 669 | - @repo ||= Grit::Repo.new(path_to_repo) | |
| 521 | + repository.raw | |
| 670 | 522 | end |
| 671 | 523 | |
| 672 | 524 | def url_to_repo |
| 673 | 525 | gitolite.url_to_repo(path_with_namespace) |
| 674 | 526 | end |
| 675 | 527 | |
| 676 | - def path_to_repo | |
| 677 | - File.join(Gitlab.config.gitolite.repos_path, "#{path_with_namespace}.git") | |
| 678 | - end | |
| 679 | - | |
| 680 | 528 | def namespace_dir |
| 681 | 529 | namespace.try(:path) || '' |
| 682 | 530 | end |
| ... | ... | @@ -690,21 +538,11 @@ class Project < ActiveRecord::Base |
| 690 | 538 | end |
| 691 | 539 | |
| 692 | 540 | def repo_exists? |
| 693 | - @repo_exists ||= (repo && !repo.branches.empty?) | |
| 541 | + @repo_exists ||= (repository && repository.branches.present?) | |
| 694 | 542 | rescue |
| 695 | 543 | @repo_exists = false |
| 696 | 544 | end |
| 697 | 545 | |
| 698 | - def heads | |
| 699 | - @heads ||= repo.heads | |
| 700 | - end | |
| 701 | - | |
| 702 | - def tree(fcommit, path = nil) | |
| 703 | - fcommit = commit if fcommit == :head | |
| 704 | - tree = fcommit.tree | |
| 705 | - path ? (tree / path) : tree | |
| 706 | - end | |
| 707 | - | |
| 708 | 546 | def open_branches |
| 709 | 547 | if protected_branches.empty? |
| 710 | 548 | self.repo.heads |
| ... | ... | @@ -714,61 +552,8 @@ class Project < ActiveRecord::Base |
| 714 | 552 | end.sort_by(&:name) |
| 715 | 553 | end |
| 716 | 554 | |
| 717 | - # Discovers the default branch based on the repository's available branches | |
| 718 | - # | |
| 719 | - # - If no branches are present, returns nil | |
| 720 | - # - If one branch is present, returns its name | |
| 721 | - # - If two or more branches are present, returns the one that has a name | |
| 722 | - # matching root_ref (default_branch or 'master' if default_branch is nil) | |
| 723 | - def discover_default_branch | |
| 724 | - if branch_names.length == 0 | |
| 725 | - nil | |
| 726 | - elsif branch_names.length == 1 | |
| 727 | - branch_names.first | |
| 728 | - else | |
| 729 | - branch_names.select { |v| v == root_ref }.first | |
| 730 | - end | |
| 731 | - end | |
| 732 | - | |
| 733 | - def has_commits? | |
| 734 | - !!commit | |
| 735 | - rescue Grit::NoSuchPathError | |
| 736 | - false | |
| 737 | - end | |
| 738 | - | |
| 739 | - def root_ref | |
| 740 | - default_branch || "master" | |
| 741 | - end | |
| 742 | - | |
| 743 | 555 | def root_ref?(branch) |
| 744 | - root_ref == branch | |
| 745 | - end | |
| 746 | - | |
| 747 | - # Archive Project to .tar.gz | |
| 748 | - # | |
| 749 | - # Already packed repo archives stored at | |
| 750 | - # app_root/tmp/repositories/project_name/project_name-commit-id.tag.gz | |
| 751 | - # | |
| 752 | - def archive_repo(ref) | |
| 753 | - ref = ref || self.root_ref | |
| 754 | - commit = self.commit(ref) | |
| 755 | - return nil unless commit | |
| 756 | - | |
| 757 | - # Build file path | |
| 758 | - file_name = self.path + "-" + commit.id.to_s + ".tar.gz" | |
| 759 | - storage_path = Rails.root.join("tmp", "repositories", self.path_with_namespace) | |
| 760 | - file_path = File.join(storage_path, file_name) | |
| 761 | - | |
| 762 | - # Put files into a directory before archiving | |
| 763 | - prefix = self.path + "/" | |
| 764 | - | |
| 765 | - # Create file if not exists | |
| 766 | - unless File.exists?(file_path) | |
| 767 | - FileUtils.mkdir_p storage_path | |
| 768 | - file = self.repo.archive_to_file(ref, prefix, file_path) | |
| 769 | - end | |
| 770 | - | |
| 771 | - file_path | |
| 556 | + repository.root_ref == branch | |
| 772 | 557 | end |
| 773 | 558 | |
| 774 | 559 | def ssh_url_to_repo | ... | ... |
| ... | ... | @@ -0,0 +1,163 @@ |
| 1 | +class Repository | |
| 2 | + # Repository directory name with namespace direcotry | |
| 3 | + # Examples: | |
| 4 | + # gitlab/gitolite | |
| 5 | + # diaspora | |
| 6 | + # | |
| 7 | + attr_accessor :path_with_namespace | |
| 8 | + | |
| 9 | + # Grit repo object | |
| 10 | + attr_accessor :repo | |
| 11 | + | |
| 12 | + # Default branch in the repository | |
| 13 | + attr_accessor :root_ref | |
| 14 | + | |
| 15 | + def initialize(path_with_namespace, root_ref = 'master') | |
| 16 | + @root_ref = root_ref | |
| 17 | + @path_with_namespace = path_with_namespace | |
| 18 | + @repo = Grit::Repo.new(path_to_repo) | |
| 19 | + end | |
| 20 | + | |
| 21 | + def raw | |
| 22 | + repo | |
| 23 | + end | |
| 24 | + | |
| 25 | + def path_to_repo | |
| 26 | + @path_to_repo ||= File.join(Gitlab.config.gitolite.repos_path, "#{path_with_namespace}.git") | |
| 27 | + end | |
| 28 | + | |
| 29 | + def commit(commit_id = nil) | |
| 30 | + Commit.find_or_first(repo, commit_id, root_ref) | |
| 31 | + end | |
| 32 | + | |
| 33 | + def fresh_commits(n = 10) | |
| 34 | + Commit.fresh_commits(repo, n) | |
| 35 | + end | |
| 36 | + | |
| 37 | + def commits_with_refs(n = 20) | |
| 38 | + Commit.commits_with_refs(repo, n) | |
| 39 | + end | |
| 40 | + | |
| 41 | + def commits_since(date) | |
| 42 | + Commit.commits_since(repo, date) | |
| 43 | + end | |
| 44 | + | |
| 45 | + def commits(ref, path = nil, limit = nil, offset = nil) | |
| 46 | + Commit.commits(repo, ref, path, limit, offset) | |
| 47 | + end | |
| 48 | + | |
| 49 | + def last_commit_for(ref, path = nil) | |
| 50 | + commits(ref, path, 1).first | |
| 51 | + end | |
| 52 | + | |
| 53 | + def commits_between(from, to) | |
| 54 | + Commit.commits_between(repo, from, to) | |
| 55 | + end | |
| 56 | + | |
| 57 | + def has_post_receive_file? | |
| 58 | + !!hook_file | |
| 59 | + end | |
| 60 | + | |
| 61 | + def valid_post_receive_file? | |
| 62 | + valid_hook_file == hook_file | |
| 63 | + end | |
| 64 | + | |
| 65 | + def valid_hook_file | |
| 66 | + @valid_hook_file ||= File.read(Rails.root.join('lib', 'hooks', 'post-receive')) | |
| 67 | + end | |
| 68 | + | |
| 69 | + def hook_file | |
| 70 | + @hook_file ||= begin | |
| 71 | + hook_path = File.join(path_to_repo, 'hooks', 'post-receive') | |
| 72 | + File.read(hook_path) if File.exists?(hook_path) | |
| 73 | + end | |
| 74 | + end | |
| 75 | + | |
| 76 | + # Returns an Array of branch names | |
| 77 | + def branch_names | |
| 78 | + repo.branches.collect(&:name).sort | |
| 79 | + end | |
| 80 | + | |
| 81 | + # Returns an Array of Branches | |
| 82 | + def branches | |
| 83 | + repo.branches.sort_by(&:name) | |
| 84 | + end | |
| 85 | + | |
| 86 | + # Returns an Array of tag names | |
| 87 | + def tag_names | |
| 88 | + repo.tags.collect(&:name).sort.reverse | |
| 89 | + end | |
| 90 | + | |
| 91 | + # Returns an Array of Tags | |
| 92 | + def tags | |
| 93 | + repo.tags.sort_by(&:name).reverse | |
| 94 | + end | |
| 95 | + | |
| 96 | + # Returns an Array of branch and tag names | |
| 97 | + def ref_names | |
| 98 | + [branch_names + tag_names].flatten | |
| 99 | + end | |
| 100 | + | |
| 101 | + def heads | |
| 102 | + @heads ||= repo.heads | |
| 103 | + end | |
| 104 | + | |
| 105 | + def tree(fcommit, path = nil) | |
| 106 | + fcommit = commit if fcommit == :head | |
| 107 | + tree = fcommit.tree | |
| 108 | + path ? (tree / path) : tree | |
| 109 | + end | |
| 110 | + | |
| 111 | + def has_commits? | |
| 112 | + !!commit | |
| 113 | + rescue Grit::NoSuchPathError | |
| 114 | + false | |
| 115 | + end | |
| 116 | + | |
| 117 | + def empty_repo? | |
| 118 | + !has_commits? | |
| 119 | + end | |
| 120 | + | |
| 121 | + # Discovers the default branch based on the repository's available branches | |
| 122 | + # | |
| 123 | + # - If no branches are present, returns nil | |
| 124 | + # - If one branch is present, returns its name | |
| 125 | + # - If two or more branches are present, returns the one that has a name | |
| 126 | + # matching root_ref (default_branch or 'master' if default_branch is nil) | |
| 127 | + def discover_default_branch | |
| 128 | + if branch_names.length == 0 | |
| 129 | + nil | |
| 130 | + elsif branch_names.length == 1 | |
| 131 | + branch_names.first | |
| 132 | + else | |
| 133 | + branch_names.select { |v| v == root_ref }.first | |
| 134 | + end | |
| 135 | + end | |
| 136 | + | |
| 137 | + # Archive Project to .tar.gz | |
| 138 | + # | |
| 139 | + # Already packed repo archives stored at | |
| 140 | + # app_root/tmp/repositories/project_name/project_name-commit-id.tag.gz | |
| 141 | + # | |
| 142 | + def archive_repo(ref) | |
| 143 | + ref = ref || self.root_ref | |
| 144 | + commit = self.commit(ref) | |
| 145 | + return nil unless commit | |
| 146 | + | |
| 147 | + # Build file path | |
| 148 | + file_name = self.path + "-" + commit.id.to_s + ".tar.gz" | |
| 149 | + storage_path = Rails.root.join("tmp", "repositories", self.path_with_namespace) | |
| 150 | + file_path = File.join(storage_path, file_name) | |
| 151 | + | |
| 152 | + # Put files into a directory before archiving | |
| 153 | + prefix = self.path + "/" | |
| 154 | + | |
| 155 | + # Create file if not exists | |
| 156 | + unless File.exists?(file_path) | |
| 157 | + FileUtils.mkdir_p storage_path | |
| 158 | + file = self.repo.archive_to_file(ref, prefix, file_path) | |
| 159 | + end | |
| 160 | + | |
| 161 | + file_path | |
| 162 | + end | |
| 163 | +end | ... | ... |
| ... | ... | @@ -0,0 +1,49 @@ |
| 1 | +class Team | |
| 2 | + attr_accessor :project | |
| 3 | + | |
| 4 | + def initialize(project) | |
| 5 | + @project = project | |
| 6 | + @roles = UsersProject.roles_hash | |
| 7 | + end | |
| 8 | + | |
| 9 | + def add_user(user, access) | |
| 10 | + add_users_ids([user.id], access) | |
| 11 | + end | |
| 12 | + | |
| 13 | + def add_users(users, access) | |
| 14 | + add_users_ids(users.map(&:id), access) | |
| 15 | + end | |
| 16 | + | |
| 17 | + def add_users_ids(users_ids, access) | |
| 18 | + UsersProject.add_users_into_projects( | |
| 19 | + [project.id], | |
| 20 | + user_ids, | |
| 21 | + access | |
| 22 | + ) | |
| 23 | + end | |
| 24 | + | |
| 25 | + # Remove all users from project team | |
| 26 | + def truncate | |
| 27 | + UsersProject.truncate_team(project) | |
| 28 | + end | |
| 29 | + | |
| 30 | + def members | |
| 31 | + project.users_projects | |
| 32 | + end | |
| 33 | + | |
| 34 | + def guests | |
| 35 | + members.guests.map(&:user) | |
| 36 | + end | |
| 37 | + | |
| 38 | + def reporters | |
| 39 | + members.reporters.map(&:user) | |
| 40 | + end | |
| 41 | + | |
| 42 | + def developers | |
| 43 | + members.developers.map(&:user) | |
| 44 | + end | |
| 45 | + | |
| 46 | + def masters | |
| 47 | + members.masters.map(&:user) | |
| 48 | + end | |
| 49 | +end | ... | ... |
app/models/tree.rb
| 1 | 1 | class Tree |
| 2 | 2 | include Linguist::BlobHelper |
| 3 | - attr_accessor :path, :tree, :project, :ref | |
| 3 | + | |
| 4 | + attr_accessor :path, :tree, :ref | |
| 4 | 5 | |
| 5 | 6 | delegate :contents, :basename, :name, :data, :mime_type, |
| 6 | 7 | :mode, :size, :text?, :colorize, to: :tree |
| 7 | 8 | |
| 8 | - def initialize(raw_tree, project, ref = nil, path = nil) | |
| 9 | - @project, @ref, @path = project, ref, path | |
| 9 | + def initialize(raw_tree, ref = nil, path = nil) | |
| 10 | + @ref, @path = ref, path | |
| 10 | 11 | @tree = if path.present? |
| 11 | 12 | raw_tree / path |
| 12 | 13 | else | ... | ... |
app/models/users_project.rb
| ... | ... | @@ -42,7 +42,21 @@ class UsersProject < ActiveRecord::Base |
| 42 | 42 | scope :in_project, ->(project) { where(project_id: project.id) } |
| 43 | 43 | |
| 44 | 44 | class << self |
| 45 | - def add_users_into_projects(project_ids, user_ids, project_access) | |
| 45 | + | |
| 46 | + # Add users to project teams with passed access option | |
| 47 | + # | |
| 48 | + # access can be an integer representing a access code | |
| 49 | + # or symbol like :master representing role | |
| 50 | + # | |
| 51 | + def add_users_into_projects(project_ids, user_ids, access) | |
| 52 | + project_access = if @roles.has_key?(access) | |
| 53 | + @roles[access] | |
| 54 | + elsif @roles.values.include?(access) | |
| 55 | + access | |
| 56 | + else | |
| 57 | + raise "Non valid access" | |
| 58 | + end | |
| 59 | + | |
| 46 | 60 | UsersProject.transaction do |
| 47 | 61 | project_ids.each do |project_id| |
| 48 | 62 | user_ids.each do |user_id| |
| ... | ... | @@ -141,6 +155,15 @@ class UsersProject < ActiveRecord::Base |
| 141 | 155 | add_users_into_projects(project_ids, [user.id], project_access) |
| 142 | 156 | end |
| 143 | 157 | |
| 158 | + def roles_hash | |
| 159 | + { | |
| 160 | + guest: GUEST, | |
| 161 | + reporter: REPORTER, | |
| 162 | + developer: DEVELOPER, | |
| 163 | + master: MASTER | |
| 164 | + } | |
| 165 | + end | |
| 166 | + | |
| 144 | 167 | def access_roles |
| 145 | 168 | { |
| 146 | 169 | "Guest" => GUEST, | ... | ... |
app/views/commits/_head.html.haml
| ... | ... | @@ -2,19 +2,19 @@ |
| 2 | 2 | %li= render partial: 'shared/ref_switcher', locals: {destination: 'commits'} |
| 3 | 3 | |
| 4 | 4 | = nav_link(controller: [:commit, :commits]) do |
| 5 | - = link_to 'Commits', project_commits_path(@project, @project.root_ref) | |
| 5 | + = link_to 'Commits', project_commits_path(@project, @repository.root_ref) | |
| 6 | 6 | = nav_link(controller: :compare) do |
| 7 | 7 | = link_to 'Compare', project_compare_index_path(@project) |
| 8 | 8 | |
| 9 | 9 | = nav_link(html_options: {class: branches_tab_class}) do |
| 10 | 10 | = link_to project_repository_path(@project) do |
| 11 | 11 | Branches |
| 12 | - %span.badge= @project.branches.length | |
| 12 | + %span.badge= @repository.branches.length | |
| 13 | 13 | |
| 14 | 14 | = nav_link(controller: :repositories, action: :tags) do |
| 15 | 15 | = link_to tags_project_repository_path(@project) do |
| 16 | 16 | Tags |
| 17 | - %span.badge= @project.tags.length | |
| 17 | + %span.badge= @repository.tags.length | |
| 18 | 18 | |
| 19 | 19 | = nav_link(controller: :repositories, action: :stats) do |
| 20 | 20 | = link_to stats_project_repository_path(@project) do | ... | ... |
app/views/layouts/project_resource.html.haml
| ... | ... | @@ -14,9 +14,9 @@ |
| 14 | 14 | - if @project.repo_exists? |
| 15 | 15 | - if can? current_user, :download_code, @project |
| 16 | 16 | = nav_link(controller: %w(tree blob blame)) do |
| 17 | - = link_to 'Files', project_tree_path(@project, @ref || @project.root_ref) | |
| 17 | + = link_to 'Files', project_tree_path(@project, @ref || @repository.root_ref) | |
| 18 | 18 | = nav_link(controller: %w(commit commits compare repositories protected_branches)) do |
| 19 | - = link_to "Commits", project_commits_path(@project, @ref || @project.root_ref) | |
| 19 | + = link_to "Commits", project_commits_path(@project, @ref || @repository.root_ref) | |
| 20 | 20 | = nav_link(path: 'projects#graph') do |
| 21 | 21 | = link_to "Network", graph_project_path(@project) |
| 22 | 22 | ... | ... |
app/views/repositories/_branch.html.haml
| ... | ... | @@ -8,7 +8,7 @@ |
| 8 | 8 | - else |
| 9 | 9 | %i.icon-unlock |
| 10 | 10 | %strong= truncate(branch.name, length: 60) |
| 11 | - - if branch.name == @project.root_ref | |
| 11 | + - if branch.name == @repository.root_ref | |
| 12 | 12 | %span.label default |
| 13 | 13 | %td |
| 14 | 14 | = link_to project_commit_path(@project, commit.id), class: 'commit_short_id' do | ... | ... |
app/views/repositories/stats.html.haml
app/views/tree/_tree.html.haml
| ... | ... | @@ -3,9 +3,13 @@ |
| 3 | 3 | %span.arrow |
| 4 | 4 | = link_to project_tree_path(@project, @ref) do |
| 5 | 5 | = @project.name |
| 6 | - - tree.breadcrumbs(6) do |link| | |
| 6 | + - tree.breadcrumbs(6) do |title, path| | |
| 7 | 7 | \/ |
| 8 | - %li= link | |
| 8 | + %li | |
| 9 | + - if path | |
| 10 | + = link_to truncate(title, length: 40), project_tree_path(@project, path) | |
| 11 | + - else | |
| 12 | + = link_to title, '#' | |
| 9 | 13 | |
| 10 | 14 | .clear |
| 11 | 15 | %div.tree_progress |
| ... | ... | @@ -26,7 +30,7 @@ |
| 26 | 30 | %tr.tree-item |
| 27 | 31 | %td.tree-item-file-name |
| 28 | 32 | = image_tag "file_empty.png", size: '16x16' |
| 29 | - = link_to "..", tree.up_dir_path | |
| 33 | + = link_to "..", project_tree_path(@project, tree.up_dir_path) | |
| 30 | 34 | %td |
| 31 | 35 | %td |
| 32 | 36 | %td | ... | ... |
lib/extracts_path.rb
| ... | ... | @@ -68,7 +68,7 @@ module ExtractsPath |
| 68 | 68 | id = input |
| 69 | 69 | id += '/' unless id.ends_with?('/') |
| 70 | 70 | |
| 71 | - valid_refs = @project.ref_names | |
| 71 | + valid_refs = @project.repository.ref_names | |
| 72 | 72 | valid_refs.select! { |v| id.start_with?("#{v}/") } |
| 73 | 73 | |
| 74 | 74 | if valid_refs.length != 1 |
| ... | ... | @@ -114,9 +114,9 @@ module ExtractsPath |
| 114 | 114 | |
| 115 | 115 | @id = File.join(@ref, @path) |
| 116 | 116 | |
| 117 | - @commit = CommitDecorator.decorate(@project.commit(@ref)) | |
| 117 | + @commit = CommitDecorator.decorate(@project.repository.commit(@ref)) | |
| 118 | 118 | |
| 119 | - @tree = Tree.new(@commit.tree, @project, @ref, @path) | |
| 119 | + @tree = Tree.new(@commit.tree, @ref, @path) | |
| 120 | 120 | @tree = TreeDecorator.new(@tree) |
| 121 | 121 | |
| 122 | 122 | raise InvalidPathError if @tree.invalid? | ... | ... |
spec/models/note_spec.rb
| ... | ... | @@ -4,7 +4,6 @@ |
| 4 | 4 | # |
| 5 | 5 | # id :integer not null, primary key |
| 6 | 6 | # note :text |
| 7 | -# noteable_id :string(255) | |
| 8 | 7 | # noteable_type :string(255) |
| 9 | 8 | # author_id :integer |
| 10 | 9 | # created_at :datetime not null |
| ... | ... | @@ -12,6 +11,8 @@ |
| 12 | 11 | # project_id :integer |
| 13 | 12 | # attachment :string(255) |
| 14 | 13 | # line_code :string(255) |
| 14 | +# commit_id :string(255) | |
| 15 | +# noteable_id :integer | |
| 15 | 16 | # |
| 16 | 17 | |
| 17 | 18 | require 'spec_helper' | ... | ... |
spec/models/project_spec.rb
| ... | ... | @@ -9,7 +9,7 @@ |
| 9 | 9 | # created_at :datetime not null |
| 10 | 10 | # updated_at :datetime not null |
| 11 | 11 | # private_flag :boolean default(TRUE), not null |
| 12 | -# owner_id :integer | |
| 12 | +# creator_id :integer | |
| 13 | 13 | # default_branch :string(255) |
| 14 | 14 | # issues_enabled :boolean default(TRUE), not null |
| 15 | 15 | # wall_enabled :boolean default(TRUE), not null | ... | ... |