summaryrefslogtreecommitdiff
path: root/lib/gitlab/git/hook_env.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/gitlab/git/hook_env.rb')
-rw-r--r--lib/gitlab/git/hook_env.rb51
1 files changed, 51 insertions, 0 deletions
diff --git a/lib/gitlab/git/hook_env.rb b/lib/gitlab/git/hook_env.rb
new file mode 100644
index 00000000000..455e8451c10
--- /dev/null
+++ b/lib/gitlab/git/hook_env.rb
@@ -0,0 +1,51 @@
+# Gitaly note: JV: no RPC's here.
+
+module Gitlab
+ module Git
+ # Ephemeral (per request) storage for environment variables that some Git
+ # commands need during internal API calls made from Git push hooks.
+ #
+ # For example, in pre-receive hooks, new objects are put in a temporary
+ # $GIT_OBJECT_DIRECTORY. Without it set, the new objects cannot be retrieved
+ # (this would break push rules for instance).
+ #
+ # This class is thread-safe via RequestStore.
+ class HookEnv
+ WHITELISTED_VARIABLES = %w[
+ GIT_OBJECT_DIRECTORY_RELATIVE
+ GIT_ALTERNATE_OBJECT_DIRECTORIES_RELATIVE
+ ].freeze
+
+ def self.set(gl_repository, env)
+ return unless RequestStore.active?
+
+ raise "missing gl_repository" if gl_repository.blank?
+
+ RequestStore.store[:gitlab_git_env] ||= {}
+ RequestStore.store[:gitlab_git_env][gl_repository] = whitelist_git_env(env)
+ end
+
+ def self.all(gl_repository)
+ return {} unless RequestStore.active?
+
+ h = RequestStore.fetch(:gitlab_git_env) { {} }
+ h.fetch(gl_repository, {})
+ end
+
+ def self.to_env_hash(gl_repository)
+ env = {}
+
+ all(gl_repository).compact.each do |key, value|
+ value = value.join(File::PATH_SEPARATOR) if value.is_a?(Array)
+ env[key.to_s] = value
+ end
+
+ env
+ end
+
+ def self.whitelist_git_env(env)
+ env.select { |key, _| WHITELISTED_VARIABLES.include?(key.to_s) }.with_indifferent_access
+ end
+ end
+ end
+end