pvincent
3 months ago
7 changed files with 104 additions and 142 deletions
-
25config/initializers/content_security_policy.rb
-
16config/initializers/inflections.rb
-
14config/initializers/monkey_patcher.rb
-
13config/initializers/permissions_policy.rb
-
3config/initializers/rails_live_reload.rb
-
155lib/hot/constants.rb
-
20lib/monkey_patches/rails_live_reload/watcher.rb
@ -1,25 +0,0 @@ |
|||
# Be sure to restart your server when you modify this file. |
|||
|
|||
# Define an application-wide content security policy. |
|||
# See the Securing Rails Applications Guide for more information: |
|||
# https://guides.rubyonrails.org/security.html#content-security-policy-header |
|||
|
|||
# Rails.application.configure do |
|||
# config.content_security_policy do |policy| |
|||
# policy.default_src :self, :https |
|||
# policy.font_src :self, :https, :data |
|||
# policy.img_src :self, :https, :data |
|||
# policy.object_src :none |
|||
# policy.script_src :self, :https |
|||
# policy.style_src :self, :https |
|||
# # Specify URI for violation reports |
|||
# # policy.report_uri "/csp-violation-report-endpoint" |
|||
# end |
|||
# |
|||
# # Generate session nonces for permitted importmap, inline scripts, and inline styles. |
|||
# config.content_security_policy_nonce_generator = ->(request) { request.session.id.to_s } |
|||
# config.content_security_policy_nonce_directives = %w(script-src style-src) |
|||
# |
|||
# # Report violations without enforcing the policy. |
|||
# # config.content_security_policy_report_only = true |
|||
# end |
@ -1,16 +0,0 @@ |
|||
# Be sure to restart your server when you modify this file. |
|||
|
|||
# Add new inflection rules using the following format. Inflections |
|||
# are locale specific, and you may define rules for as many different |
|||
# locales as you wish. All of these examples are active by default: |
|||
# ActiveSupport::Inflector.inflections(:en) do |inflect| |
|||
# inflect.plural /^(ox)$/i, "\\1en" |
|||
# inflect.singular /^(ox)en/i, "\\1" |
|||
# inflect.irregular "person", "people" |
|||
# inflect.uncountable %w( fish sheep ) |
|||
# end |
|||
|
|||
# These inflection rules are supported but not enabled by default: |
|||
# ActiveSupport::Inflector.inflections(:en) do |inflect| |
|||
# inflect.acronym "RESTful" |
|||
# end |
@ -1,14 +1,14 @@ |
|||
return unless Rails.application.server? |
|||
|
|||
puts 'MonkeyPatcher runs:' |
|||
# puts 'MonkeyPatcher runs:' |
|||
patches = Dir.glob(Rails.root.join('lib', 'monkey_patches', '**', '*.rb')) |
|||
patches.each do |file| |
|||
puts "🐵 patching... #{Pathname.new(file).relative_path_from Rails.root}" |
|||
# puts "🐵 patching... #{Pathname.new(file).relative_path_from Rails.root}" |
|||
require file |
|||
end |
|||
|
|||
puts case patches.count |
|||
when 0 then 'No patch found' |
|||
when 1 then '1 successful patch applied' |
|||
else "#{patches.count} successful patches applied" |
|||
end |
|||
# puts case patches.count |
|||
# when 0 then 'No patch found' |
|||
# when 1 then '1 successful patch applied' |
|||
# else "#{patches.count} successful patches applied" |
|||
# end |
@ -1,13 +0,0 @@ |
|||
# Be sure to restart your server when you modify this file. |
|||
|
|||
# Define an application-wide HTTP permissions policy. For further |
|||
# information see: https://developers.google.com/web/updates/2018/06/feature-policy |
|||
|
|||
# Rails.application.config.permissions_policy do |policy| |
|||
# policy.camera :none |
|||
# policy.gyroscope :none |
|||
# policy.microphone :none |
|||
# policy.usb :none |
|||
# policy.fullscreen :self |
|||
# policy.payment :self, "https://secure.example.com" |
|||
# end |
@ -1,101 +1,104 @@ |
|||
require 'dotenv' |
|||
|
|||
# Hot Live Constants |
|||
module Hot::Constants |
|||
HOTENV = {} # rubocop:disable Style/MutableConstant |
|||
LISTENERS = {} # rubocop:disable Style/MutableConstant |
|||
LOGGER = SemanticLogger[self] |
|||
TOTO = 'titi' |
|||
|
|||
class << self |
|||
def initialize |
|||
@old_definitions = {} |
|||
@hot_definitions = {} |
|||
|
|||
load_definitions |
|||
load_values |
|||
end |
|||
module Hot |
|||
# Hot Live Constants |
|||
module Constants |
|||
include SemanticLogger::Loggable |
|||
HOTENV = {} # rubocop:disable Style/MutableConstant |
|||
LISTENERS = {} # rubocop:disable Style/MutableConstant |
|||
|
|||
class << self |
|||
def initialize |
|||
@old_definitions = {} |
|||
@hot_definitions = {} |
|||
|
|||
logger.level = :fatal |
|||
load_definitions |
|||
load_values |
|||
logger.level = :info |
|||
end |
|||
|
|||
def load_definitions |
|||
LOGGER.debug('--load_definitions3') |
|||
def load_definitions |
|||
logger.debug('--load_definitions3') |
|||
|
|||
new_definitions = Dotenv.parse('.env.sample') |
|||
new_definitions = Dotenv.parse('.env.sample') |
|||
|
|||
definitions_to_actualize = {} |
|||
@old_definitions.merge(new_definitions) do |key, old_value, new_value| |
|||
definitions_to_actualize[key] = new_value if new_value != old_value |
|||
end |
|||
definitions_to_actualize.each { |key, value| define_method(:actualize, key, value) } |
|||
definitions_to_actualize = {} |
|||
@old_definitions.merge(new_definitions) do |key, old_value, new_value| |
|||
definitions_to_actualize[key] = new_value if new_value != old_value |
|||
end |
|||
definitions_to_actualize.each { |key, value| define_method(:actualize, key, value) } |
|||
|
|||
@old_definitions = new_definitions |
|||
|
|||
@old_definitions = new_definitions |
|||
definitions_to_remove = @hot_definitions.except(*new_definitions.keys) |
|||
definitions_to_remove.each_pair do |key, dkey| |
|||
logger.info("remove method <#{dkey}>") |
|||
singleton_class.undef_method(dkey) |
|||
@hot_definitions.delete(key) |
|||
end |
|||
|
|||
definitions_to_remove = @hot_definitions.except(*new_definitions.keys) |
|||
definitions_to_remove.each_pair do |key, dkey| |
|||
LOGGER.info("remove method <#{dkey}>") |
|||
singleton_class.undef_method(dkey) |
|||
@hot_definitions.delete(key) |
|||
definitions_to_add = new_definitions.except(*@hot_definitions.keys) |
|||
definitions_to_add.each { |key, value| define_method(:add, key, value) } |
|||
end |
|||
|
|||
definitions_to_add = new_definitions.except(*@hot_definitions.keys) |
|||
definitions_to_add.each { |key, value| define_method(:add, key, value) } |
|||
end |
|||
def load_values |
|||
logger.debug('--load_values') |
|||
|
|||
def load_values |
|||
LOGGER.debug('--load_values') |
|||
new_env = Dotenv.parse |
|||
constants_to_delete = HOTENV.except(*new_env.keys) |
|||
constants_to_delete.each do |name, _| |
|||
# FIXME: default should read default and type from @old_definitions |
|||
type, default = @old_definitions[name] |
|||
logger.info("constant <#{name}> reverts to default value <#{default}> of type <#{type}>") |
|||
end |
|||
|
|||
new_env = Dotenv.parse |
|||
constants_to_delete = HOTENV.except(*new_env.keys) |
|||
constants_to_delete.each do |name, _| |
|||
# FIXME: default should read default and type from @old_definitions |
|||
type, default = @old_definitions[name] |
|||
LOGGER.info("constant <#{name}> reverts to default value <#{default}> of type <#{type}>") |
|||
end |
|||
constants_to_add = new_env.except(*HOTENV.keys) |
|||
constants_to_add.each do |constant| |
|||
logger.info("constant to add <#{constant}>") |
|||
end |
|||
|
|||
constants_to_add = new_env.except(*HOTENV.keys) |
|||
constants_to_add.each do |constant| |
|||
LOGGER.info("constant to add <#{constant}>") |
|||
HOTENV.replace new_env |
|||
# LISTENERS.each_pair { |k, b| perform_change(k, b) } |
|||
end |
|||
|
|||
HOTENV.replace new_env |
|||
# LISTENERS.each_pair { |k, b| perform_change(k, b) } |
|||
end |
|||
|
|||
def on_change(key, &block) |
|||
LISTENERS[key.downcase.to_sym] = block |
|||
perform_change(key, block) |
|||
end |
|||
def on_change(key, &block) |
|||
LISTENERS[key.downcase.to_sym] = block |
|||
perform_change(key, block) |
|||
end |
|||
|
|||
private |
|||
private |
|||
|
|||
def define_method(mode, key, value) |
|||
dkey = key.downcase |
|||
method = infer_method_from_value(value) |
|||
def define_method(mode, key, value) |
|||
dkey = key.downcase |
|||
method = infer_method_from_value(value) |
|||
|
|||
inferred_type = method.name.to_s.split('_')[1] |
|||
LOGGER.info("#{mode} method <#{dkey}> of type <#{inferred_type}> with default value <#{value}> ") |
|||
inferred_type = method.name.to_s.split('_')[1] |
|||
logger.info("#{mode} method <#{dkey}> of type <#{inferred_type}> with default value <#{value}> ") |
|||
|
|||
singleton_class.define_method(dkey) { method.call(key, value) } |
|||
@hot_definitions.store(key, dkey) |
|||
end |
|||
singleton_class.define_method(dkey) { method.call(key, value) } |
|||
@hot_definitions.store(key, dkey) |
|||
end |
|||
|
|||
def perform_change(key, block) |
|||
old_value = nil # TODO: remember last previous value |
|||
new_value = method(key).call |
|||
block.call(new_value, old_value) |
|||
end |
|||
def perform_change(key, block) |
|||
old_value = nil # TODO: remember last previous value |
|||
new_value = method(key).call |
|||
block.call(new_value, old_value) |
|||
end |
|||
|
|||
def load_boolean(key, default) = HOTENV.fetch(key, default).to_s.downcase == 'true' |
|||
def load_integer(key, default) = HOTENV.fetch(key, default).to_i |
|||
def load_string(key, default) = HOTENV.fetch(key, default) |
|||
def load_boolean(key, default) = HOTENV.fetch(key, default).to_s.downcase == 'true' |
|||
def load_integer(key, default) = HOTENV.fetch(key, default).to_i |
|||
def load_string(key, default) = HOTENV.fetch(key, default) |
|||
|
|||
def infer_method_from_value(value) |
|||
case value.downcase |
|||
when /^(true|false)$/ then method(:load_boolean) |
|||
when /^\d+$/ then method(:load_integer) |
|||
else method(:load_string) |
|||
def infer_method_from_value(value) |
|||
case value.downcase |
|||
when /^(true|false)$/ then method(:load_boolean) |
|||
when /^\d+$/ then method(:load_integer) |
|||
else method(:load_string) |
|||
end |
|||
end |
|||
end |
|||
end |
|||
|
|||
initialize # done once on first require, cause this is just a module (not a class!) |
|||
initialize # done once on first require, cause this is just a module (not a class!) |
|||
end |
|||
end |
Write
Preview
Loading…
Cancel
Save
Reference in new issue