biran 0.1.13.1 → 0.1.15

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ec150cd74d08598ecb7d3bfb1324bf57c15e20806c0143b042b257569f430bf6
4
- data.tar.gz: 7863cf3face519ede43bb1ca24f569112ad83fe8e686c467141c81a13a0b981d
3
+ metadata.gz: 1175961da6d05c7c7b23697b7522f2eebfbcee12fdf62cee19cee89dc1cd9ff0
4
+ data.tar.gz: e1b32e766224708ef485e81cf535ab0011e78dd97382f655fb358174ffd6e7f2
5
5
  SHA512:
6
- metadata.gz: 5464720ba0f9989e9941b77ca1fd54a17388eedd3d044e180689ce58fb7a1da87252e0ccfa09fab514410077ffe18b0a7fbbb52a56a35fce0ebc8ed6b5fb4964
7
- data.tar.gz: 1edb42ac1ebc49f45d6c60e312a4bd089495fdc11c2c96be0f1f2328f4a8d6bbdb5d14b11dbfe16fae34b8c1ab086b6ee48c82bfe4d0c3d0e8a0400e73a4b907
6
+ metadata.gz: 6ba45896793d88333fcc70fd22e5886293c46beb8e7eca1ae7ab250ccab510af4014e7dbe42a67453a7f009de0e1b01826f9d152b1a628bbce958eb961785fec
7
+ data.tar.gz: 6b3676949fec3f902e8cbb5fd3fd8cae359cd3b88bf3026b71a1c97a300b4ff2d101c1de44c615089aab7383d6c21afbce30d290fdf9011d4ab1603154428bea
data/README.md CHANGED
@@ -40,7 +40,8 @@ Dir.glob('lib/tasks/*.rake').each {|r| import r}
40
40
  # Configuration
41
41
 
42
42
  You can set where your config files are, rails end and other stuff in a file like `config/initializers/biran.rb`
43
- You can also set options in `config/app_config.yml` in the `app` block. This list will be loaded last and override anything set in the initializer.
43
+ You can also set options in `config/app_config.yml` in the `app` block. This list will be loaded last and override anything set in the initializer. All string
44
+ input is sanitized to remove special characters that don't play well with file system paths. Any special haracters found are replaced with a '-'.
44
45
 
45
46
  Config file example:
46
47
  ```
@@ -92,6 +93,7 @@ the list of things you can configure are:
92
93
  :local_config_filename,
93
94
  :db_config_file_name,
94
95
  :secrets_filename,
96
+ :extra_config_suffix,
95
97
  :config_dirname,
96
98
  :base_path,
97
99
  :shared_dir,
@@ -145,6 +147,16 @@ Available in: config file, initializer**
145
147
 
146
148
  Generally no need to change, but here in case you want to. Default is `secrets.yml`
147
149
 
150
+ ### extra_config_suffix
151
+ **Type: string
152
+ Default: extras
153
+ Available in: environment variable, config_file, initializer**
154
+
155
+ Sets the suffix to be applied to an extra config file you may want to load. The suffix is appended to the value of the config_filename. The default value will be `app_config_extras.yml`.
156
+ This file gets loaded just before the local config file and can be used to provide additional configuration based stored in a second file. There are times when you may want to organize the
157
+ configuration based on sub grouping that the yaml just doesn't allow easily.
158
+ Use cases might include grouping config based on a location, type of host, or even for testing purposes.
159
+
148
160
  ### config_dirname
149
161
  **Type: string
150
162
  Default: config
data/Rakefile CHANGED
@@ -22,10 +22,10 @@ begin
22
22
  task("spec").clear
23
23
 
24
24
  RSpec::Core::RakeTask.new(:spec) do |t|
25
- t.rspec_opts = "--format RSpec::TapY | tapout runtime"
25
+ t.rspec_opts = "--format documentation"
26
26
  end
27
27
 
28
- task :default => :spec
28
+ task default: :spec
29
29
  rescue LoadError
30
30
  raise 'No rspec available'
31
31
  end
@@ -5,9 +5,24 @@ defaults: &defaults
5
5
  files_to_generate:
6
6
  my_config:
7
7
  extension: '.yml'
8
+ my_first_value: 1
9
+ my_second_value: 2
10
+ my_fifth_value: 5
11
+ nested_values: &nested_defaults
12
+ my_third_value: 3
13
+ my_fourth_value: 4
14
+ my_sixth_value: 6
8
15
 
9
16
  test:
10
17
  <<: *defaults
18
+ my_first_value: 11
19
+ nested_values:
20
+ <<: *nested_defaults
21
+ my_third_value: 13
11
22
 
12
23
  development:
13
24
  <<: *defaults
25
+ my_first_value: 11
26
+ nested_values:
27
+ <<: *nested_defaults
28
+ my_third_value: 13
@@ -0,0 +1,10 @@
1
+ defaults: &defaults
2
+ my_fifth_value: 55
3
+ nested_values:
4
+ my_sixth_value: 66
5
+
6
+ development:
7
+ <<: *defaults
8
+
9
+ test:
10
+ <<: *defaults
data/lib/biran/config.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'singleton'
2
3
 
3
4
  module Biran
@@ -6,14 +7,15 @@ module Biran
6
7
 
7
8
  attr_writer :config_filename, :local_config_filename, :db_config_filename,
8
9
  :secrets_filename, :config_dirname, :use_capistrano, :db_config,
9
- :secrets, :base_path, :app_env, :base_dir, :bindings, :app_setup_blocks
10
+ :secrets, :base_path, :app_env, :base_dir, :bindings, :app_setup_blocks,
11
+ :extra_config_suffix
10
12
 
11
13
  attr_accessor :shared_dir
12
14
 
13
15
  def app_env
14
16
  return @app_env if @app_env
15
17
  @app_env = Rails.env if defined? Rails
16
- @app_env ||= 'development'.freeze
18
+ @app_env ||= 'development'
17
19
  end
18
20
 
19
21
  def base_dir
@@ -21,27 +23,27 @@ module Biran
21
23
  end
22
24
 
23
25
  def config_filename
24
- @config_filename ||= 'app_config.yml'.freeze
26
+ @config_filename ||= 'app_config.yml'
25
27
  end
26
28
 
27
29
  def local_config_filename
28
- @local_config_filename ||= 'local_config.yml'.freeze
30
+ @local_config_filename ||= 'local_config.yml'
29
31
  end
30
32
 
31
33
  def db_config_filename
32
- @db_config_filename ||= 'db_config.yml'.freeze
34
+ @db_config_filename ||= 'db_config.yml'
33
35
  end
34
36
 
35
37
  def secrets_filename
36
- @secrets_filename ||= 'secrets.yml'.freeze
38
+ @secrets_filename ||= 'secrets.yml'
37
39
  end
38
40
 
39
41
  def config_dirname
40
- @config_dirname ||= 'config'.freeze
42
+ @config_dirname ||= 'config'
41
43
  end
42
44
 
43
45
  def vhost_public_dirname
44
- @vhost_public_dirname ||= 'public'.freeze
46
+ @vhost_public_dirname ||= 'public'
45
47
  end
46
48
 
47
49
  def use_capistrano
@@ -63,13 +65,17 @@ module Biran
63
65
  end
64
66
 
65
67
  def app_setup_blocks
66
- @app_setup_blocks ||= %i[app].freeze
68
+ @app_setup_blocks ||= %i[app]
67
69
  end
68
70
 
69
71
  def bindings
70
72
  @bindings ||= %i[db_config]
71
73
  end
72
74
 
75
+ def extra_config_suffix
76
+ @extra_config_suffix ||= 'extras'
77
+ end
78
+
73
79
  def base_path
74
80
  return @base_path if @base_path
75
81
  @base_path = Rails.root if defined? Rails
@@ -20,7 +20,8 @@ module Biran
20
20
  end
21
21
 
22
22
  def app_env
23
- ENV['BIRAN_APP_ENV'] || ENV['RAILS_ENV'] || ENV['RACK_ENV'] || configuration.app_env
23
+ app_env = ENV['BIRAN_APP_ENV'] || ENV['RAILS_ENV'] || ENV['RACK_ENV'] || configuration.app_env
24
+ sanitize_input(app_env)
24
25
  end
25
26
 
26
27
  def app_base
@@ -41,37 +42,62 @@ module Biran
41
42
  app_config_defaults[:app][:bindings]
42
43
  end
43
44
 
45
+ def config_dirname
46
+ sanitize_input(configuration.config_dirname)
47
+ end
48
+
44
49
  def config_dir
45
- File.join configuration.base_path, configuration.config_dirname
50
+ File.join(configuration.base_path, config_dirname)
46
51
  end
47
52
 
48
53
  def local_config_file
49
54
  ENV['BIRAN_LOCAL_CONFIG_FILE'] ||
50
- File.join(app_shared_dir, configuration.config_dirname, local_config_filename)
55
+ File.join(app_shared_dir, config_dirname, local_config_filename)
51
56
  end
52
57
 
53
58
  def local_config_filename
54
- ENV['BIRAN_LOCAL_CONFIG_FILENAME'] || app_config_defaults[:app][:local_config_filename] || configuration.local_config_filename
59
+ filename= ENV['BIRAN_LOCAL_CONFIG_FILENAME'] || app_config_defaults[:app][:local_config_filename] || configuration.local_config_filename
60
+ sanitize_input( filename )
61
+ end
62
+
63
+ def extra_config_suffix
64
+ suffix = ENV['BIRAN_EXTRA_CONFIG_SUFFIX'] || app_config_defaults[:app][:extra_config_suffix] || configuration.extra_config_suffix
65
+ sanitize_input( suffix )
66
+ end
67
+
68
+ def extra_config_file
69
+ File.join(config_dirname, app_config_filename.gsub(/\.yml$/, "_#{extra_config_suffix}.yml"))
70
+ end
71
+
72
+ def app_config_filename
73
+ sanitize_input(configuration.config_filename)
74
+ end
75
+
76
+ def app_config_file
77
+ File.join(config_dirname, app_config_filename)
55
78
  end
56
79
 
57
80
  def vhost_public_dirname
58
- ENV['BIRAN_VHOST_PUBLIC_DIRNAME'] || app_config_defaults[:app][:vhost_public_dirname]
81
+ pub_dir_name = ENV['BIRAN_VHOST_PUBLIC_DIRNAME'] || app_config_defaults[:app][:vhost_public_dirname]
82
+ sanitize_input(pub_dir_name)
59
83
  end
60
84
 
61
85
  def db_config_override_file
62
- File.join(app_shared_dir, configuration.config_dirname, db_config_filename)
86
+ File.join(app_shared_dir, config_dirname, db_config_filename)
63
87
  end
64
88
 
65
89
  def db_config_filename
66
- app_config_defaults[:app][:db_config_filename] || configuration.db_config_filename
90
+ filename = app_config_defaults[:app][:db_config_filename] || configuration.db_config_filename
91
+ sanitize_input(filename)
67
92
  end
68
93
 
69
94
  def secrets_file
70
- File.join(configuration.base_path, configuration.config_dirname, secrets_filename)
95
+ File.join(configuration.base_path, config_dirname, secrets_filename)
71
96
  end
72
97
 
73
98
  def secrets_filename
74
- app_config_defaults[:app][:secrets_filename] || configuration.secrets_filename
99
+ filename = app_config_defaults[:app][:secrets_filename] || configuration.secrets_filename
100
+ sanitize_input(filename)
75
101
  end
76
102
 
77
103
  def default_db_config_file
@@ -81,5 +107,10 @@ module Biran
81
107
  def use_capistrano?
82
108
  # Implement in consumer class
83
109
  end
110
+
111
+ def sanitize_input string
112
+ # Borrowed from ActiveStorage
113
+ string.encode(Encoding::UTF_8, invalid: :replace, undef: :replace, replace: "�").strip.tr("\u{202E}%$|:;/\t\r\n\\", "-")
114
+ end
84
115
  end
85
116
  end
@@ -61,6 +61,7 @@ module Biran
61
61
  app_config[:secrets].deep_merge! get_secrets_content(app_config[:secrets_file_path])
62
62
  app_config[:db_config].deep_merge! build_db_config
63
63
 
64
+ app_config.deep_merge! extra_config_file_contents
64
65
  app_config.deep_merge! local_config_file_contents
65
66
  end
66
67
 
@@ -78,7 +79,6 @@ module Biran
78
79
 
79
80
  def app_config_defaults
80
81
  return @app_config_defaults if @app_config_defaults
81
- app_config_file = File.join(configuration.config_dirname, configuration.config_filename)
82
82
  app_defaults = app_defaults_init.dup
83
83
  config_properties = process_config_file(app_config_file)
84
84
  @app_config_defaults = app_defaults.deep_merge! config_properties
@@ -87,7 +87,7 @@ module Biran
87
87
  def process_config_file(config_file)
88
88
  config_file_contents = File.read(config_file)
89
89
  config_file_contents = ERB.new(config_file_contents).result
90
- config_file_contents = YAML.safe_load(config_file_contents, [], [], true)
90
+ config_file_contents = yaml_load(config_file_contents)
91
91
  config_file_contents[env].deep_symbolize_keys!
92
92
  rescue Errno::ENOENT
93
93
  raise "Missing config file: #{config_file}"
@@ -113,6 +113,12 @@ module Biran
113
113
  process_config_file secrets_file
114
114
  end
115
115
 
116
+ def extra_config_file_contents
117
+ return @extra_config_contents if @extra_config_contents
118
+ return @extra_config_contents = {} unless File.exists? extra_config_file
119
+ @extra_config_contents = process_config_file(extra_config_file)
120
+ end
121
+
116
122
  def sanitize_config_files files_list
117
123
  lambda do |(file, _)|
118
124
  files_list[file] ||= {extension: ''}
@@ -122,6 +128,11 @@ module Biran
122
128
  end
123
129
  end
124
130
 
131
+ def yaml_load data_content
132
+ # Ruby 3.1 with Psych 4 allows yaml-aliases only in direct manner
133
+ YAML.safe_load(data_content, aliases: true)
134
+ end
135
+
125
136
  def filtered_config
126
137
  @filtered_config ||= config.except(*configuration.app_setup_blocks)
127
138
  end
@@ -0,0 +1,155 @@
1
+ require 'biran/hash_refinement'
2
+
3
+ module Biran
4
+ class Configurinator
5
+ include ConfigDefaults
6
+ using HashRefinement
7
+
8
+ DEFAULT_ENV = 'development'
9
+
10
+ attr_reader :config, :db_config, :env
11
+
12
+ class << self
13
+ attr_accessor :config
14
+
15
+ def configure
16
+ self.config ||= Config.instance
17
+ yield config
18
+ end
19
+ end
20
+
21
+ def initialize(env: nil)
22
+ @env = env || app_env
23
+ @config = build_app_config
24
+ end
25
+
26
+ def file_tasks
27
+ files_to_generate.keys
28
+ end
29
+
30
+ def files_to_generate
31
+ @files_to_generate ||= config.fetch(:app, {})
32
+ .fetch(:files_to_generate, configuration.files_to_generate)
33
+ .tap { |files_list| files_list.each(&sanitize_config_files(files_list)) }
34
+ end
35
+
36
+ def create(name:, extension:, output_dir: nil, output_name: nil)
37
+ output_dir ||= config_dir
38
+ output_name ||= name
39
+ generated_file = ERBConfig.new(filtered_config, name, extension, config_dir, output_dir, output_name)
40
+ generated_file.bindings = bindings
41
+ generated_file.save!
42
+ end
43
+
44
+ private
45
+
46
+ def build_app_config
47
+ raise 'Environment not set to build the application config' unless @env
48
+ app_config = {
49
+ app_root_dir: app_root,
50
+ app_shared_dir: app_shared_dir,
51
+ app_base_dir: app_base,
52
+ env: env,
53
+ local_config_file: local_config_file,
54
+ secrets_file_path: secrets_file,
55
+ vhost: config_vhost_dirs
56
+ }
57
+
58
+ app_config.deep_merge! app_config_defaults
59
+ app_config[:secrets].deep_merge! get_secret_contents(app_config)
60
+ app_config[:db_config] = build_db_config
61
+
62
+ app_config.deep_merge! local_config_file_contents
63
+
64
+ puts "app config final is #{app_config.inspect}"
65
+ app_config
66
+ end
67
+
68
+ def build_db_config
69
+ default_db_config = base_db_config
70
+ return default_db_config unless File.exist? db_config_override_file
71
+ default_db_config.deep_merge! process_config_file(db_config_override_file)
72
+ end
73
+
74
+ def base_db_config
75
+ return @base_db_config if @base_db_config
76
+ return @base_db_config = {} unless File.exists? default_db_config_file
77
+ @base_db_config ||= process_config_file(default_db_config_file)
78
+ end
79
+
80
+ def app_config_defaults
81
+ return @app_config_defaults if @app_config_defaults
82
+ app_config_file = File.join(configuration.config_dirname, configuration.config_filename)
83
+ app_defaults = app_defaults_init.dup
84
+ config_properties = process_config_file(app_config_file)
85
+ @app_config_defaults = app_defaults.deep_merge! config_properties
86
+ end
87
+
88
+ def process_config_file(config_file)
89
+ config_file_contents = File.read(config_file)
90
+ config_file_contents = ERB.new(config_file_contents).result
91
+ config_file_contents = YAML.safe_load(config_file_contents, [], [], true)
92
+ #puts "Config file contents after yaml load before env grab #{config_file_contents.inspect}"
93
+ config_file_contents_for_test = config_file_contents['test']
94
+ config_file_contents_for_env = config_file_contents[env]
95
+ puts "Config file contents for test:"
96
+ puts config_file_contents_for_test.to_yaml
97
+ puts
98
+ puts "Config file contents for #{env}:"
99
+ puts config_file_contents_for_env.to_yaml
100
+ puts
101
+ config_file_diff = config_file_contents_for_test.deep_diff(config_file_contents_for_env)
102
+ puts "diff hash is:"
103
+ puts config_file_diff.to_yaml
104
+ puts
105
+ config_file_diff_r = config_file_contents_for_env.deep_diff(config_file_contents_for_test)
106
+ puts "diff hash reversed is:"
107
+ puts config_file_diff_r.to_yaml
108
+ puts
109
+
110
+ config_file_contents_for_env.deep_symbolize_keys!
111
+ rescue Errno::ENOENT
112
+ raise "Missing config file: #{config_file}"
113
+ end
114
+
115
+ def config_vhost_dirs
116
+ {
117
+ public_dir: File.join(app_root, vhost_public_dirname),
118
+ shared_dir: app_shared_dir.to_s,
119
+ log_dir: File.join(app_root, 'log'),
120
+ pids_dir: File.join(app_root, 'tmp', 'pids')
121
+ }
122
+ end
123
+
124
+ def local_config_file_contents
125
+ return @local_config_contents if @local_config_contents
126
+ return @local_config_conents = {} unless File.exists? local_config_file
127
+ @local_config_contents = process_config_file(local_config_file)
128
+ end
129
+
130
+ def get_secret_contents(app_config)
131
+ secrets_file_contents = {}
132
+ if File.exist? app_config[:secrets_file_path]
133
+ secrets_file_contents = process_config_file app_config[:secrets_file_path]
134
+ end
135
+ secrets_file_contents
136
+ end
137
+
138
+ def sanitize_config_files files_list
139
+ lambda do |file, _|
140
+ files_list[file] ||= {extension: ''}
141
+ ext = files_list[file].fetch(:extension, '').strip
142
+ ext.prepend('.') unless ext.start_with?('.') || ext.empty?
143
+ files_list[file][:extension] = ext
144
+ end
145
+ end
146
+
147
+ def filtered_config
148
+ @filtered_config ||= config.except(*configuration.app_setup_blocks)
149
+ end
150
+
151
+ def use_capistrano?
152
+ app_config_defaults[:app][:use_capistrano]
153
+ end
154
+ end
155
+ end
@@ -41,7 +41,7 @@ module Biran
41
41
 
42
42
  def process_erb
43
43
  config_erb_file = File.join(source_dir, "_#{name}#{extension}.erb")
44
- ERB.new(File.read(config_erb_file), nil, '-')
44
+ ERB.new(File.read(config_erb_file), trim_mode: '-')
45
45
  rescue Errno::ENOENT
46
46
  raise Biran::ConfigSyntaxError, "Missing template file for #{name}: #{config_erb_file}"
47
47
  end
@@ -0,0 +1,19 @@
1
+ module HashRefinement
2
+
3
+ refine Hash do
4
+ def deep_diff(b)
5
+ a = self
6
+ (a.keys | b.keys).inject({}) do |diff, k|
7
+ if a[k] != b[k]
8
+ if a[k].respond_to?(:deep_diff) && b[k].respond_to?(:deep_diff)
9
+ diff[k] = a[k].deep_diff(b[k])
10
+ else
11
+ #diff[k] = b[k] || a[k]
12
+ diff[k] = b.keys.exclude?(k) ? a[k] : b[k]
13
+ end
14
+ end
15
+ diff
16
+ end
17
+ end
18
+ end
19
+ end
data/lib/biran/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Biran
2
- VERSION = '0.1.13.1'
2
+ VERSION = '0.1.15'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: biran
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.13.1
4
+ version: 0.1.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - javierg
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2021-03-18 00:00:00.000000000 Z
13
+ date: 2023-04-27 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: railties
@@ -88,34 +88,6 @@ dependencies:
88
88
  - - "~>"
89
89
  - !ruby/object:Gem::Version
90
90
  version: '3.7'
91
- - !ruby/object:Gem::Dependency
92
- name: tapout
93
- requirement: !ruby/object:Gem::Requirement
94
- requirements:
95
- - - "~>"
96
- - !ruby/object:Gem::Version
97
- version: '0.4'
98
- type: :development
99
- prerelease: false
100
- version_requirements: !ruby/object:Gem::Requirement
101
- requirements:
102
- - - "~>"
103
- - !ruby/object:Gem::Version
104
- version: '0.4'
105
- - !ruby/object:Gem::Dependency
106
- name: rspec-ontap
107
- requirement: !ruby/object:Gem::Requirement
108
- requirements:
109
- - - "~>"
110
- - !ruby/object:Gem::Version
111
- version: '0.3'
112
- type: :development
113
- prerelease: false
114
- version_requirements: !ruby/object:Gem::Requirement
115
- requirements:
116
- - - "~>"
117
- - !ruby/object:Gem::Version
118
- version: '0.3'
119
91
  description: Biran is the guy that will help you generate config files for your rail
120
92
  app.
121
93
  email:
@@ -129,19 +101,23 @@ files:
129
101
  - Rakefile
130
102
  - config/_my_config.yml.erb
131
103
  - config/app_config.yml
104
+ - config/app_config_test.yml
132
105
  - lib/biran.rb
133
106
  - lib/biran/config.rb
134
107
  - lib/biran/config_defaults.rb
135
108
  - lib/biran/configurinator.rb
109
+ - lib/biran/configurinator.rb.test_changes
136
110
  - lib/biran/erb_config.rb
137
111
  - lib/biran/exceptions.rb
112
+ - lib/biran/hash_refinement.rb
138
113
  - lib/biran/railtie.rb
139
114
  - lib/biran/version.rb
140
115
  - lib/tasks/biran_tasks.rake
141
116
  homepage: https://github.com/amco/biran
142
117
  licenses:
143
118
  - MIT
144
- metadata: {}
119
+ metadata:
120
+ rubygems_mfa_required: 'true'
145
121
  post_install_message:
146
122
  rdoc_options: []
147
123
  require_paths:
@@ -150,7 +126,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
150
126
  requirements:
151
127
  - - ">="
152
128
  - !ruby/object:Gem::Version
153
- version: '0'
129
+ version: 2.6.0
154
130
  required_rubygems_version: !ruby/object:Gem::Requirement
155
131
  requirements:
156
132
  - - ">="