Module: AbstractFeatureBranch

Defined in:
lib/abstract_feature_branch.rb,
lib/generators/abstract_feature_branch/context_generator.rb,
lib/generators/abstract_feature_branch/install_generator.rb

Defined Under Namespace

Modules: FileBeautifier, Generators

Constant Summary collapse

ENV_FEATURE_PREFIX =
"abstract_feature_branch_"

Class Method Summary collapse

Class Method Details

.application_environmentObject



28
29
30
# File 'lib/abstract_feature_branch.rb', line 28

def application_environment
  @application_environment ||= initialize_application_environment
end

.application_environment=(environment) ⇒ Object



31
32
33
# File 'lib/abstract_feature_branch.rb', line 31

def application_environment=(environment)
  @application_environment = environment
end

.application_featuresObject



111
112
113
114
# File 'lib/abstract_feature_branch.rb', line 111

def application_features
  unload_application_features unless cacheable?
  environment_features(application_environment)
end

.application_rootObject



19
20
21
# File 'lib/abstract_feature_branch.rb', line 19

def application_root
  @application_root ||= initialize_application_root
end

.application_root=(path) ⇒ Object



22
23
24
# File 'lib/abstract_feature_branch.rb', line 22

def application_root=(path)
  @application_root = path
end

.cacheableObject



46
47
48
# File 'lib/abstract_feature_branch.rb', line 46

def cacheable
  @cacheable ||= initialize_cacheable
end

.cacheable=(cacheable) ⇒ Object



49
50
51
# File 'lib/abstract_feature_branch.rb', line 49

def cacheable=(cacheable)
  @cacheable = cacheable
end

.cacheable?Boolean

Returns:

  • (Boolean)


127
128
129
130
131
# File 'lib/abstract_feature_branch.rb', line 127

def cacheable?
  value = downcase_keys(cacheable)[application_environment]
  value = (application_environment != 'development') if value.nil?
  value
end

.environment_features(environment) ⇒ Object

performance optimization via caching of feature values resolved through environment variable overrides and local features



101
102
103
104
# File 'lib/abstract_feature_branch.rb', line 101

def environment_features(environment)
  @environment_features ||= {}
  @environment_features[environment] ||= load_environment_features(environment)
end

.environment_variable_overridesObject



70
71
72
# File 'lib/abstract_feature_branch.rb', line 70

def environment_variable_overrides
  @environment_variable_overrides ||= load_environment_variable_overrides
end

.featuresObject



88
89
90
# File 'lib/abstract_feature_branch.rb', line 88

def features
  @features ||= load_features
end

.initialize_application_environmentObject



34
35
36
# File 'lib/abstract_feature_branch.rb', line 34

def initialize_application_environment
  self.application_environment = defined?(Rails) ? Rails.env.to_s : ENV['APP_ENV'] || 'development'
end

.initialize_application_rootObject



25
26
27
# File 'lib/abstract_feature_branch.rb', line 25

def initialize_application_root
  self.application_root = defined?(Rails) ? Rails.root : '.'
end

.initialize_cacheableObject



52
53
54
55
56
57
58
59
# File 'lib/abstract_feature_branch.rb', line 52

def initialize_cacheable
  self.cacheable = {
    :development => false,
    :test => true,
    :staging => true,
    :production => true
  }
end

.initialize_loggerObject



43
44
45
# File 'lib/abstract_feature_branch.rb', line 43

def initialize_logger
  self.logger = defined?(Rails) && Rails.logger ? Rails.logger : Logger.new(STDOUT)
end

.initialize_user_features_storageObject



66
67
68
69
# File 'lib/abstract_feature_branch.rb', line 66

def initialize_user_features_storage
  require 'redis'
  self.user_features_storage = Redis.new
end

.load_application_featuresObject



115
116
117
118
119
120
# File 'lib/abstract_feature_branch.rb', line 115

def load_application_features
  AbstractFeatureBranch.load_environment_variable_overrides
  AbstractFeatureBranch.load_features
  AbstractFeatureBranch.load_local_features
  AbstractFeatureBranch.load_environment_features(application_environment)
end

.load_environment_features(environment) ⇒ Object



105
106
107
108
109
110
# File 'lib/abstract_feature_branch.rb', line 105

def load_environment_features(environment)
  @environment_features ||= {}
  features[environment] ||= {}
  local_features[environment] ||= {}
  @environment_features[environment] = features[environment].merge(local_features[environment]).merge(environment_variable_overrides)
end

.load_environment_variable_overridesObject



73
74
75
# File 'lib/abstract_feature_branch.rb', line 73

def load_environment_variable_overrides
  @environment_variable_overrides = featureize_keys(select_feature_keys(booleanize_values(downcase_keys(ENV))))
end

.load_featuresObject



91
92
93
94
95
96
97
98
99
# File 'lib/abstract_feature_branch.rb', line 91

def load_features
  @features = {}
  Dir.glob(File.join(application_root, 'config', 'features', '**', '*.yml')).each do |feature_configuration_file|
    @features.deep_merge!(downcase_feature_hash_keys(YAML.load_file(feature_configuration_file)))
  end
  main_features_file = File.join(application_root, 'config', 'features.yml')
  @features.deep_merge!(downcase_feature_hash_keys(YAML.load_file(main_features_file))) if File.exists?(main_features_file)
  @features
end

.load_local_featuresObject



79
80
81
82
83
84
85
86
87
# File 'lib/abstract_feature_branch.rb', line 79

def load_local_features
  @local_features = {}
  Dir.glob(File.join(application_root, 'config', 'features', '**', '*.local.yml')).each do |feature_configuration_file|
    @local_features.deep_merge!(downcase_feature_hash_keys(YAML.load_file(feature_configuration_file)))
  end
  main_local_features_file = File.join(application_root, 'config', 'features.local.yml')
  @local_features.deep_merge!(downcase_feature_hash_keys(YAML.load_file(main_local_features_file))) if File.exists?(main_local_features_file)
  @local_features
end

.local_featuresObject



76
77
78
# File 'lib/abstract_feature_branch.rb', line 76

def local_features
  @local_features ||= load_local_features
end

.loggerObject



37
38
39
# File 'lib/abstract_feature_branch.rb', line 37

def logger
  @logger ||= initialize_logger
end

.logger=(logger) ⇒ Object



40
41
42
# File 'lib/abstract_feature_branch.rb', line 40

def logger=(logger)
  @logger = logger
end

.toggle_features_for_user(user_id, features) ⇒ Object



132
133
134
135
136
137
138
139
140
# File 'lib/abstract_feature_branch.rb', line 132

def toggle_features_for_user(user_id, features)
  features.each do |name, value|
    if value
      user_features_storage.sadd("#{ENV_FEATURE_PREFIX}#{name.to_s.downcase}", user_id)
    else
      user_features_storage.srem("#{ENV_FEATURE_PREFIX}#{name.to_s.downcase}", user_id)
    end
  end
end

.unload_application_featuresObject



121
122
123
124
125
126
# File 'lib/abstract_feature_branch.rb', line 121

def unload_application_features
  @environment_variable_overrides = nil
  @features = nil
  @local_features = nil
  @environment_features = nil
end

.user_features_storageObject



60
61
62
# File 'lib/abstract_feature_branch.rb', line 60

def user_features_storage
  @user_features_storage ||= initialize_user_features_storage
end

.user_features_storage=(user_features_storage) ⇒ Object



63
64
65
# File 'lib/abstract_feature_branch.rb', line 63

def user_features_storage=(user_features_storage)
  @user_features_storage = user_features_storage
end