summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorLin Jen-Shin <godfat@godfat.org>2018-08-30 19:05:00 +0800
committerLin Jen-Shin <godfat@godfat.org>2018-09-11 18:45:49 +0800
commit71fefe147475bb85c67de95fba8211385cfb0a79 (patch)
tree12a8d1409f699ccd0832f6a26dad055c05b19898 /lib
parentc56f2b96159afaf6f1e0831d0e7a756a40568cab (diff)
downloadgitlab-ce-71fefe147475bb85c67de95fba8211385cfb0a79.tar.gz
Properly implement prepending for Concern
Diffstat (limited to 'lib')
-rw-r--r--lib/gitlab/patch/prependable.rb71
1 files changed, 71 insertions, 0 deletions
diff --git a/lib/gitlab/patch/prependable.rb b/lib/gitlab/patch/prependable.rb
new file mode 100644
index 00000000000..45fac0ed4a7
--- /dev/null
+++ b/lib/gitlab/patch/prependable.rb
@@ -0,0 +1,71 @@
+# frozen_string_literal: true
+
+# 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
+
+ module MetaConcern
+ def extended(base)
+ super
+ base.instance_variable_set(:@_prepend_dependencies, [])
+ end
+ end
+
+ def self.prepended(base)
+ super
+ base.singleton_class.prepend MetaConcern
+ end
+
+ def append_features(base)
+ super
+
+ prepend_features(base)
+ end
+
+ def prepend_features(base)
+ if base.instance_variable_defined?(:@_prepend_dependencies)
+ base.instance_variable_get(:@_prepend_dependencies) << self
+ false
+ else
+ return false if prepended?(base)
+
+ @_prepend_dependencies.each { |dep| base.prepend(dep) }
+
+ super
+
+ if const_defined?(:ClassMethods)
+ base.singleton_class.prepend const_get(:ClassMethods)
+ end
+
+ if instance_variable_defined?(:@_prepended_block)
+ base.class_eval(&@_prepended_block)
+ end
+ 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)
+
+ @_prepend_dependencies.index(self) ||
+ base.ancestors[0...index].index(self)
+ end
+ end
+ end
+end