diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-02-04 15:08:40 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-02-04 15:08:40 +0000 |
commit | 6b833f1e0340e00fdee074da9c42c0d4e07a46d2 (patch) | |
tree | 6fc3a7a2f8a02fec8d1e7561b453d33eb4048dad /app/models | |
parent | 88a0824944720b6edaaef56376713541b9a02118 (diff) | |
download | gitlab-ce-6b833f1e0340e00fdee074da9c42c0d4e07a46d2.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/models')
-rw-r--r-- | app/models/blob.rb | 19 | ||||
-rw-r--r-- | app/models/commit.rb | 53 | ||||
-rw-r--r-- | app/models/commit_collection.rb | 21 | ||||
-rw-r--r-- | app/models/concerns/has_repository.rb | 98 | ||||
-rw-r--r-- | app/models/project.rb | 73 | ||||
-rw-r--r-- | app/models/repository.rb | 41 | ||||
-rw-r--r-- | app/models/user.rb | 7 |
7 files changed, 181 insertions, 131 deletions
diff --git a/app/models/blob.rb b/app/models/blob.rb index 258006d8d2e..d8282c918b7 100644 --- a/app/models/blob.rb +++ b/app/models/blob.rb @@ -65,7 +65,10 @@ class Blob < SimpleDelegator BlobViewer::YarnLock ].freeze - attr_reader :project + attr_reader :container + + delegate :repository, to: :container, allow_nil: true + delegate :project, to: :repository, allow_nil: true # Wrap a Gitlab::Git::Blob object, or return nil when given nil # @@ -77,22 +80,22 @@ class Blob < SimpleDelegator # # blob = Blob.decorate(nil) # puts "truthy" if blob # No output - def self.decorate(blob, project = nil) + def self.decorate(blob, container = nil) return if blob.nil? - new(blob, project) + new(blob, container) end - def self.lazy(project, commit_id, path, blob_size_limit: Gitlab::Git::Blob::MAX_DATA_DISPLAY_SIZE) - BatchLoader.for([commit_id, path]).batch(key: project.repository) do |items, loader, args| + def self.lazy(container, commit_id, path, blob_size_limit: Gitlab::Git::Blob::MAX_DATA_DISPLAY_SIZE) + BatchLoader.for([commit_id, path]).batch(key: container.repository) do |items, loader, args| args[:key].blobs_at(items, blob_size_limit: blob_size_limit).each do |blob| loader.call([blob.commit_id, blob.path], blob) if blob end end end - def initialize(blob, project = nil) - @project = project + def initialize(blob, container = nil) + @container = container super(blob) end @@ -116,7 +119,7 @@ class Blob < SimpleDelegator def load_all_data! # Endpoint needed: https://gitlab.com/gitlab-org/gitaly/issues/756 Gitlab::GitalyClient.allow_n_plus_1_calls do - super(project.repository) if project + super(repository) if container end end diff --git a/app/models/commit.rb b/app/models/commit.rb index 31a890096e9..f2a6a8b6cbb 100644 --- a/app/models/commit.rb +++ b/app/models/commit.rb @@ -21,11 +21,14 @@ class Commit participant :committer participant :notes_with_associations - attr_accessor :project, :author + attr_accessor :author attr_accessor :redacted_description_html attr_accessor :redacted_title_html attr_accessor :redacted_full_title_html - attr_reader :gpg_commit + attr_reader :gpg_commit, :container + + delegate :repository, to: :container + delegate :project, to: :repository, allow_nil: true DIFF_SAFE_LINES = Gitlab::Git::DiffCollection::DEFAULT_LIMITS[:max_lines] @@ -44,12 +47,12 @@ class Commit cache_markdown_field :description, pipeline: :commit_description class << self - def decorate(commits, project) + def decorate(commits, container) commits.map do |commit| if commit.is_a?(Commit) commit else - self.new(commit, project) + self.new(commit, container) end end end @@ -85,24 +88,24 @@ class Commit } end - def from_hash(hash, project) - raw_commit = Gitlab::Git::Commit.new(project.repository.raw, hash) - new(raw_commit, project) + def from_hash(hash, container) + raw_commit = Gitlab::Git::Commit.new(container.repository.raw, hash) + new(raw_commit, container) end def valid_hash?(key) !!(EXACT_COMMIT_SHA_PATTERN =~ key) end - def lazy(project, oid) - BatchLoader.for({ project: project, oid: oid }).batch(replace_methods: false) do |items, loader| - items_by_project = items.group_by { |i| i[:project] } + def lazy(container, oid) + BatchLoader.for({ container: container, oid: oid }).batch(replace_methods: false) do |items, loader| + items_by_container = items.group_by { |i| i[:container] } - items_by_project.each do |project, commit_ids| + items_by_container.each do |container, commit_ids| oids = commit_ids.map { |i| i[:oid] } - project.repository.commits_by(oids: oids).each do |commit| - loader.call({ project: commit.project, oid: commit.id }, commit) if commit + container.repository.commits_by(oids: oids).each do |commit| + loader.call({ container: commit.container, oid: commit.id }, commit) if commit end end end @@ -115,12 +118,12 @@ class Commit attr_accessor :raw - def initialize(raw_commit, project) + def initialize(raw_commit, container) raise "Nil as raw commit passed" unless raw_commit @raw = raw_commit - @project = project - @gpg_commit = Gitlab::Gpg::Commit.new(self) if project + @container = container + @gpg_commit = Gitlab::Gpg::Commit.new(self) if container end delegate \ @@ -141,7 +144,7 @@ class Commit end def project_id - project.id + project&.id end def ==(other) @@ -269,17 +272,17 @@ class Commit end def parents - @parents ||= parent_ids.map { |oid| Commit.lazy(project, oid) } + @parents ||= parent_ids.map { |oid| Commit.lazy(container, oid) } end def parent strong_memoize(:parent) do - project.commit_by(oid: self.parent_id) if self.parent_id + container.commit_by(oid: self.parent_id) if self.parent_id end end def notes - project.notes.for_commit_id(self.id) + container.notes.for_commit_id(self.id) end def user_mentions @@ -295,7 +298,7 @@ class Commit end def merge_requests - @merge_requests ||= project.merge_requests.by_commit_sha(sha) + @merge_requests ||= project&.merge_requests&.by_commit_sha(sha) end def method_missing(method, *args, &block) @@ -330,7 +333,7 @@ class Commit end def cherry_pick_branch_name - project.repository.next_branch("cherry-pick-#{short_id}", mild: true) + repository.next_branch("cherry-pick-#{short_id}", mild: true) end def cherry_pick_description(user) @@ -418,7 +421,7 @@ class Commit return unless entry if entry[:type] == :blob - blob = ::Blob.decorate(Gitlab::Git::Blob.new(name: entry[:name]), @project) + blob = ::Blob.decorate(Gitlab::Git::Blob.new(name: entry[:name]), container) blob.image? || blob.video? || blob.audio? ? :raw : :blob else entry[:type] @@ -484,7 +487,7 @@ class Commit end def commit_reference(from, referable_commit_id, full: false) - base = project.to_reference_base(from, full: full) + base = project&.to_reference_base(from, full: full) if base.present? "#{base}#{self.class.reference_prefix}#{referable_commit_id}" @@ -510,6 +513,6 @@ class Commit end def merged_merge_request_no_cache(user) - MergeRequestsFinder.new(user, project_id: project.id).find_by(merge_commit_sha: id) if merge_commit? + MergeRequestsFinder.new(user, project_id: project_id).find_by(merge_commit_sha: id) if merge_commit? end end diff --git a/app/models/commit_collection.rb b/app/models/commit_collection.rb index d4c29aa295b..456d32bf403 100644 --- a/app/models/commit_collection.rb +++ b/app/models/commit_collection.rb @@ -1,17 +1,20 @@ # frozen_string_literal: true -# A collection of Commit instances for a specific project and Git reference. +# A collection of Commit instances for a specific container and Git reference. class CommitCollection include Enumerable include Gitlab::Utils::StrongMemoize - attr_reader :project, :ref, :commits + attr_reader :container, :ref, :commits - # project - The project the commits belong to. + delegate :repository, to: :container, allow_nil: true + delegate :project, to: :repository, allow_nil: true + + # container - The object the commits belong to. # commits - The Commit instances to store. # ref - The name of the ref (e.g. "master"). - def initialize(project, commits, ref = nil) - @project = project + def initialize(container, commits, ref = nil) + @container = container @commits = commits @ref = ref end @@ -39,6 +42,8 @@ class CommitCollection # Setting the pipeline for each commit ahead of time removes the need for running # a query for every commit we're displaying. def with_latest_pipeline(ref = nil) + return self unless project + pipelines = project.ci_pipelines.latest_pipeline_per_commit(map(&:id), ref) each do |commit| @@ -59,16 +64,16 @@ class CommitCollection # Batch load any commits that are not backed by full gitaly data, and # replace them in the collection. def enrich! - # A project is needed in order to fetch data from gitaly. Projects + # A container is needed in order to fetch data from gitaly. Containers # can be absent from commits in certain rare situations (like when # viewing a MR of a deleted fork). In these cases, assume that the # enriched data is not needed. - return self if project.blank? || fully_enriched? + return self if container.blank? || fully_enriched? # Batch load full Commits from the repository # and map to a Hash of id => Commit replacements = Hash[unenriched.map do |c| - [c.id, Commit.lazy(project, c.id)] + [c.id, Commit.lazy(container, c.id)] end.compact] # Replace the commits, keeping the same order diff --git a/app/models/concerns/has_repository.rb b/app/models/concerns/has_repository.rb new file mode 100644 index 00000000000..66c2f57bedd --- /dev/null +++ b/app/models/concerns/has_repository.rb @@ -0,0 +1,98 @@ +# frozen_string_literal: true + +module HasRepository + extend ActiveSupport::Concern + include Gitlab::ShellAdapter + include AfterCommitQueue + include Gitlab::Utils::StrongMemoize + + delegate :base_dir, :disk_path, to: :storage + + def valid_repo? + repository.exists? + rescue + errors.add(:path, _('Invalid repository path')) + false + end + + def repo_exists? + strong_memoize(:repo_exists) do + repository.exists? + rescue + false + end + end + + def repository_exists? + !!repository.exists? + end + + def root_ref?(branch) + repository.root_ref == branch + end + + def commit(ref = 'HEAD') + repository.commit(ref) + end + + def commit_by(oid:) + repository.commit_by(oid: oid) + end + + def commits_by(oids:) + repository.commits_by(oids: oids) + end + + def repository + raise NotImplementedError + end + + def storage + raise NotImplementedError + end + + def full_path + raise NotImplementedError + end + + def empty_repo? + repository.empty? + end + + def default_branch + @default_branch ||= repository.root_ref + end + + def reload_default_branch + @default_branch = nil # rubocop:disable Gitlab/ModuleWithInstanceVariables + + default_branch + end + + def url_to_repo + gitlab_shell.url_to_repo(full_path) + end + + def ssh_url_to_repo + url_to_repo + end + + def http_url_to_repo + custom_root = Gitlab::CurrentSettings.custom_http_clone_url_root + + url = if custom_root.present? + Gitlab::Utils.append_path( + custom_root, + web_url(only_path: true) + ) + else + web_url + end + + "#{url}.git" + end + + def web_url(only_path: nil) + raise NotImplementedError + end +end diff --git a/app/models/project.rb b/app/models/project.rb index 54bed41e9e7..31aeb0146df 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -19,6 +19,7 @@ class Project < ApplicationRecord include ProjectFeaturesCompatibility include SelectForProjectAuthorization include Presentable + include HasRepository include Routable include GroupDescendant include Gitlab::SQL::Pattern @@ -326,7 +327,6 @@ class Project < ApplicationRecord to: :project_feature, allow_nil: true delegate :scheduled?, :started?, :in_progress?, :failed?, :finished?, prefix: :import, to: :import_state, allow_nil: true - delegate :base_dir, :disk_path, to: :storage delegate :no_import?, to: :import_state, allow_nil: true delegate :name, to: :owner, allow_nil: true, prefix: true delegate :members, to: :team, prefix: true @@ -767,10 +767,6 @@ class Project < ApplicationRecord Feature.enabled?(:context_commits, default_enabled: true) end - def empty_repo? - repository.empty? - end - def team @team ||= ProjectTeam.new(self) end @@ -798,18 +794,6 @@ class Project < ApplicationRecord has_root_container_repository_tags? end - def commit(ref = 'HEAD') - repository.commit(ref) - end - - def commit_by(oid:) - repository.commit_by(oid: oid) - end - - def commits_by(oids:) - repository.commits_by(oids: oids) - end - # ref can't be HEAD, can only be branch/tag name def latest_successful_build_for_ref(job_name, ref = default_branch) return unless ref @@ -1357,48 +1341,6 @@ class Project < ApplicationRecord services.public_send(hooks_scope).any? # rubocop:disable GitlabSecurity/PublicSend end - def valid_repo? - repository.exists? - rescue - errors.add(:path, _('Invalid repository path')) - false - end - - def url_to_repo - gitlab_shell.url_to_repo(full_path) - end - - def repo_exists? - strong_memoize(:repo_exists) do - repository.exists? - rescue - false - end - end - - def root_ref?(branch) - repository.root_ref == branch - end - - def ssh_url_to_repo - url_to_repo - end - - def http_url_to_repo - custom_root = Gitlab::CurrentSettings.custom_http_clone_url_root - - project_url = if custom_root.present? - Gitlab::Utils.append_path( - custom_root, - web_url(only_path: true) - ) - else - web_url - end - - "#{project_url}.git" - end - # Is overridden in EE def lfs_http_url_to_repo(_) http_url_to_repo @@ -1538,15 +1480,6 @@ class Project < ApplicationRecord end end - def default_branch - @default_branch ||= repository.root_ref - end - - def reload_default_branch - @default_branch = nil - default_branch - end - def visibility_level_field :visibility_level end @@ -1583,10 +1516,6 @@ class Project < ApplicationRecord create_repository(force: true) unless repository_exists? end - def repository_exists? - !!repository.exists? - end - def wiki_repository_exists? wiki.repository_exists? end diff --git a/app/models/repository.rb b/app/models/repository.rb index 9807aed07a9..d720980faab 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -22,7 +22,7 @@ class Repository include Gitlab::RepositoryCacheAdapter - attr_accessor :full_path, :disk_path, :project, :repo_type + attr_accessor :full_path, :disk_path, :container, :repo_type delegate :ref_name_for_sha, to: :raw_repository delegate :bundle_to_disk, to: :raw_repository @@ -67,10 +67,10 @@ class Repository MERGED_BRANCH_NAMES_CACHE_DURATION = 10.minutes - def initialize(full_path, project, disk_path: nil, repo_type: Gitlab::GlRepository::PROJECT) + def initialize(full_path, container, disk_path: nil, repo_type: Gitlab::GlRepository::PROJECT) @full_path = full_path @disk_path = disk_path || full_path - @project = project + @container = container @commit_cache = {} @repo_type = repo_type end @@ -97,7 +97,7 @@ class Repository def path_to_repo @path_to_repo ||= begin - storage = Gitlab.config.repositories.storages[project.repository_storage] + storage = Gitlab.config.repositories.storages[container.repository_storage] File.expand_path( File.join(storage.legacy_disk_path, disk_path + '.git') @@ -130,7 +130,7 @@ class Repository commits = Gitlab::Git::Commit.batch_by_oid(raw_repository, oids) if commits.present? - Commit.decorate(commits, project) + Commit.decorate(commits, container) else [] end @@ -161,14 +161,14 @@ class Repository } commits = Gitlab::Git::Commit.where(options) - commits = Commit.decorate(commits, project) if commits.present? + commits = Commit.decorate(commits, container) if commits.present? - CommitCollection.new(project, commits, ref) + CommitCollection.new(container, commits, ref) end def commits_between(from, to) commits = Gitlab::Git::Commit.between(raw_repository, from, to) - commits = Commit.decorate(commits, project) if commits.present? + commits = Commit.decorate(commits, container) if commits.present? commits end @@ -176,7 +176,7 @@ class Repository def new_commits(newrev) commits = raw.new_commits(newrev) - ::Commit.decorate(commits, project) + ::Commit.decorate(commits, container) end # Gitaly migration: https://gitlab.com/gitlab-org/gitaly/issues/384 @@ -188,7 +188,7 @@ class Repository commits = raw_repository.find_commits_by_message(query, ref, path, limit, offset).map do |c| commit(c) end - CommitCollection.new(project, commits, ref) + CommitCollection.new(container, commits, ref) end def find_branch(name) @@ -281,7 +281,7 @@ class Repository raw_repository.archive_metadata( ref, storage_path, - project.path, + project&.path, format, append_sha: append_sha, path: path @@ -499,7 +499,7 @@ class Repository end def blob_at(sha, path) - blob = Blob.decorate(raw_repository.blob_at(sha, path), project) + blob = Blob.decorate(raw_repository.blob_at(sha, path), container) # Don't attempt to return a special result if there is no blob at all return unless blob @@ -522,7 +522,7 @@ class Repository return [] unless exists? raw_repository.batch_blobs(items, blob_size_limit: blob_size_limit).map do |blob| - Blob.decorate(blob, project) + Blob.decorate(blob, container) end end @@ -701,13 +701,13 @@ class Repository commits = raw_repository.list_last_commits_for_tree(sha, path, offset: offset, limit: limit) commits.each do |path, commit| - commits[path] = ::Commit.new(commit, project) + commits[path] = ::Commit.new(commit, container) end end def last_commit_for_path(sha, path) commit = raw_repository.last_commit_for_path(sha, path) - ::Commit.new(commit, project) if commit + ::Commit.new(commit, container) if commit end def last_commit_id_for_path(sha, path) @@ -986,6 +986,7 @@ class Repository # rubocop:disable Gitlab/RailsLogger def async_remove_remote(remote_name) return unless remote_name + return unless project job_id = RepositoryRemoveRemoteWorker.perform_async(project.id, remote_name) @@ -1157,6 +1158,10 @@ class Repository Gitlab::Git::Blob.batch_metadata(raw, references).map { |raw_blob| Blob.decorate(raw_blob) } end + def project + container + end + private # TODO Genericize finder, later split this on finders by Ref or Oid @@ -1203,10 +1208,10 @@ class Repository end def initialize_raw_repository - Gitlab::Git::Repository.new(project.repository_storage, + Gitlab::Git::Repository.new(container.repository_storage, disk_path + '.git', - repo_type.identifier_for_container(project), - project.full_path) + repo_type.identifier_for_container(container), + container.full_path) end end diff --git a/app/models/user.rb b/app/models/user.rb index bc113c72762..d44e8162abe 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1527,6 +1527,13 @@ class User < ApplicationRecord end def read_only_attribute?(attribute) + if Feature.enabled?(:ldap_readonly_attributes, default_enabled: true) + enabled = Gitlab::Auth::LDAP::Config.enabled? + read_only = attribute.to_sym.in?(UserSyncedAttributesMetadata::SYNCABLE_ATTRIBUTES) + + return true if enabled && read_only + end + user_synced_attributes_metadata&.read_only?(attribute) end |