diff options
author | Robert Speicher <robert@gitlab.com> | 2018-09-14 17:38:29 +0000 |
---|---|---|
committer | Robert Speicher <robert@gitlab.com> | 2018-09-14 17:38:29 +0000 |
commit | 165e9a99c0363934e7676f3968e974af73c6cf95 (patch) | |
tree | ddeb4bbd45faaf3a8cd3efc8e28dd22c55a6f617 /lib | |
parent | 69925767b7ac49b59c0292608b6655edb117e31d (diff) | |
parent | ebe89e8bd259a848d737b33a793298220054a023 (diff) | |
download | gitlab-ce-165e9a99c0363934e7676f3968e974af73c6cf95.tar.gz |
Merge branch '50824-fix-prepend-concern' into 'master'
CE: Properly implement prepending for Concern
See merge request gitlab-org/gitlab-ce!21444
Diffstat (limited to 'lib')
-rw-r--r-- | lib/gitlab/patch/prependable.rb | 65 | ||||
-rw-r--r-- | lib/gitlab/utils/override.rb | 12 |
2 files changed, 73 insertions, 4 deletions
diff --git a/lib/gitlab/patch/prependable.rb b/lib/gitlab/patch/prependable.rb new file mode 100644 index 00000000000..a9f6cfb19cb --- /dev/null +++ b/lib/gitlab/patch/prependable.rb @@ -0,0 +1,65 @@ +# frozen_string_literal: true + +# We're patching `ActiveSupport::Concern` in +# config/initializers/0_as_concern.rb +# +# We want to patch `ActiveSupport::Concern` for two reasons: +# 1. Allow defining class methods via: `class_methods` method +# 2. Allow `prepended do; end` work like `included do; end` +# If we don't need anything above, we don't need this patch nor the concern! + +# rubocop:disable Gitlab/ModuleWithInstanceVariables +module Gitlab + module Patch + module Prependable + class MultiplePrependedBlocks < StandardError + def initialize + super "Cannot define multiple 'prepended' blocks for a Concern" + end + end + + def prepend_features(base) + return false if prepended?(base) + + super + + if const_defined?(:ClassMethods) + klass_methods = const_get(:ClassMethods) + base.singleton_class.prepend klass_methods + base.instance_variable_set(:@_prepended_class_methods, klass_methods) + end + + if instance_variable_defined?(:@_prepended_block) + base.class_eval(&@_prepended_block) + end + + true + end + + def class_methods + super + + if instance_variable_defined?(:@_prepended_class_methods) + const_get(:ClassMethods).prepend @_prepended_class_methods + end + end + + def prepended(base = nil, &block) + if base.nil? + raise MultiplePrependedBlocks if + instance_variable_defined?(:@_prepended_block) + + @_prepended_block = block + else + super + end + end + + def prepended?(base) + index = base.ancestors.index(base) + + base.ancestors[0...index].index(self) + end + end + end +end diff --git a/lib/gitlab/utils/override.rb b/lib/gitlab/utils/override.rb index 7b2a62fed48..d00921e6cdc 100644 --- a/lib/gitlab/utils/override.rb +++ b/lib/gitlab/utils/override.rb @@ -89,15 +89,19 @@ module Gitlab def included(base = nil) super - queue_verification(base) + queue_verification(base) if base end - alias_method :prepended, :included + def prepended(base = nil) + super + + queue_verification(base) if base + end - def extended(mod) + def extended(mod = nil) super - queue_verification(mod.singleton_class) + queue_verification(mod.singleton_class) if mod end def queue_verification(base) |