blueprint_config 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6cd1d77adc1c5b0c6804976f701d7169aa95dde0fbb759223bf5f866d3dcb6ce
4
- data.tar.gz: a2afa1abc74f9353444ee4a03c8afd256ba56521f5d914376f145367caa9b70b
3
+ metadata.gz: c15d3fbdfef9100c4ea913ea334e54121af90b9a3d1a8ebebadf058e3e6332cb
4
+ data.tar.gz: 58bb317972ccb61b627973e957fc03f966d233312a45572b438e37ca61925c7f
5
5
  SHA512:
6
- metadata.gz: dcc11edd92aed918514ec06d6da8b8fe98033ceed743d8bb710d8263bcb93460ee089d6299c31a969d93cfe7997aab707b5d5749a6af99e4383a0870a2d64201
7
- data.tar.gz: 3363d88bfbc0da672f308f4d528b256399a4ac0c5364e2a4c25f298e84bf951f41feab992c071d5f74f978df7695cd9fcb3c49998c83ceae705c9f7ed3e2f9f3
6
+ metadata.gz: 9fc44988632c85c5d085b86fe6409577de935c781910d754edda255948e1a340951116fd130d0313c8a2390b837e47db3def437e4210fb566c00ebde60021e86
7
+ data.tar.gz: d070bfcbe59fa94f9720721c85d76b1d9074f9e55d78b6f2e1eb8164f88921c7237ee3a3d4c49327a9e5d8b596b33811e4d4c2d1bf56d74fa99ebbbe75dbbb83
@@ -11,11 +11,22 @@ module BlueprintConfig
11
11
  =======================================================================
12
12
  Settings table not found. Please add the configuration table by running:
13
13
 
14
- rails generate blueprint_config:install
15
- rake db:migrate
14
+ bundle exec rails generate blueprint_config:install
15
+ bundle exec rake db:migrate
16
16
  =======================================================================
17
17
  WARNING
18
18
 
19
+ MISSING_ATTRIBUTES_WARNING = <<-WARNING.gsub(/^ */, '')
20
+ =======================================================================
21
+ Settings table is missing required attributes: %s
22
+
23
+ You can create a migration and adjust it to your needs by running:
24
+ bundle exec rails generate blueprint_config:install
25
+ =======================================================================
26
+ WARNING
27
+
28
+ REQUIRED_ATTRIBUTES = %w[key value type updated_at].freeze
29
+
19
30
  def initialize(options = {})
20
31
  @options = options
21
32
  @updated_at = nil
@@ -26,23 +37,64 @@ module BlueprintConfig
26
37
 
27
38
  def load_keys
28
39
  @configured = true
40
+
41
+ return {} unless table_exist?
42
+ return {} unless has_required_attributes?
43
+
29
44
  update_timestamp
30
45
 
31
46
  data = Setting.all.map { |s| { s.key => s.parsed_value } }.reduce(:merge) || {}
32
47
  return data.transform_keys(&:to_sym) unless @options[:nest]
33
48
 
34
49
  nest_hash(data, @options[:nest_separator] || '.')
35
- rescue ::ActiveRecord::NoDatabaseError => e
50
+ rescue ::ActiveRecord::NoDatabaseError, ::ActiveRecord::ConnectionNotEstablished
36
51
  # database is not created yet
37
52
  @configured = false
38
53
  {}
39
54
  rescue ::ActiveRecord::StatementInvalid => e
40
55
  @configured = false
41
- Rails.logger.warn(e.message)
42
- Rails.logger.warn(MISSING_TABLE_WARNING)
56
+ unless @options[:silence_warnings]
57
+ puts "Failed to load seetings from database: #{e.message}"
58
+ Rails.logger.warn(e.message) if defined?(Rails)
59
+ end
43
60
  {}
44
61
  end
45
62
 
63
+ def table_exist?
64
+ Setting.reset_column_information
65
+ return true if Setting.table_exists?
66
+
67
+ @configured = false
68
+
69
+ unless @options[:silence_warnings]
70
+ puts MISSING_TABLE_WARNING
71
+ if defined?(Rails)
72
+ Rails.logger.warn(e.message)
73
+ Rails.logger.warn(MISSING_TABLE_WARNING)
74
+ end
75
+ end
76
+
77
+ false
78
+ end
79
+
80
+ def has_required_attributes?
81
+ Setting.reset_column_information
82
+ return true if REQUIRED_ATTRIBUTES - Setting.attribute_names == []
83
+
84
+ @configured = false
85
+
86
+ missing = (REQUIRED_ATTRIBUTES - Setting.attribute_names).join(', ')
87
+ unless @options[:silence_warnings]
88
+ puts MISSING_ATTRIBUTES_WARNING % missing
89
+ if defined?(Rails)
90
+ Rails.logger.warn(e.message)
91
+ Rails.logger.warn(MISSING_TABLE_WARNING)
92
+ end
93
+ end
94
+
95
+ false
96
+ end
97
+
46
98
  def update_timestamp
47
99
  @mutex.synchronize do
48
100
  @updated_at = Setting.maximum(:updated_at)
@@ -16,7 +16,7 @@ module BlueprintConfig
16
16
  reload! unless backends&.fresh?
17
17
  config.#{method}(...)
18
18
  rescue KeyError => e
19
- raise KeyError, e.message, caller[1..], cause: nil
19
+ raise KeyError, e.message, caller[1..], cause: nil#{' '}
20
20
  end
21
21
  RUBY
22
22
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module BlueprintConfig
4
- VERSION = '1.2.0'
4
+ VERSION = '1.3.0'
5
5
  end
@@ -9,14 +9,18 @@ require 'blueprint_config/backend_collection'
9
9
  module BlueprintConfig
10
10
  class << self
11
11
  attr_accessor :root, :env, :before_initialize, :after_initialize
12
- attr_writer :shortcut_name, :env_options
12
+ attr_writer :shortcut_name, :env_backend_options, :active_record_backend_options
13
13
 
14
14
  def shortcut_name
15
15
  @shortcut_name || 'AppConfig'
16
16
  end
17
17
 
18
- def env_options
19
- @env_options || {}
18
+ def env_backend_options
19
+ @env_backend_options ||= {}
20
+ end
21
+
22
+ def active_record_backend_options
23
+ @active_record_backend_options ||= { nest: true }
20
24
  end
21
25
 
22
26
  def define_shortcut
@@ -46,8 +50,6 @@ module BlueprintConfig
46
50
  end
47
51
  end
48
52
 
49
- BlueprintConfig.env_options ||= {}
50
-
51
53
  BlueprintConfig.before_initialize ||= proc do
52
54
  require 'blueprint_config/backend/credentials'
53
55
  require 'blueprint_config/backend/active_record'
@@ -55,17 +57,19 @@ BlueprintConfig.before_initialize ||= proc do
55
57
  BlueprintConfig.instance.init do |backends|
56
58
  backends.use :app, BlueprintConfig::Backend::YAML.new('config/app.yml')
57
59
  backends.use :credentials, BlueprintConfig::Backend::Credentials.new
58
- backends.use :env, BlueprintConfig::Backend::ENV.new(BlueprintConfig.env_options)
60
+ backends.use :env, BlueprintConfig::Backend::ENV.new(BlueprintConfig.env_backend_options)
59
61
  backends.use :app_local, BlueprintConfig::Backend::YAML.new('config/app.local.yml')
60
62
  end
61
63
  end
62
64
 
63
65
  BlueprintConfig.after_initialize ||= proc do
64
66
  BlueprintConfig.instance.refine do |backends|
67
+ ar_backend = BlueprintConfig::Backend::ActiveRecord.new(BlueprintConfig.active_record_backend_options)
68
+
65
69
  if backends[:env]
66
- backends.insert_after :env, :db, BlueprintConfig::Backend::ActiveRecord.new
70
+ backends.insert_after :env, :db, ar_backend
67
71
  else
68
- backends.push :db, BlueprintConfig::Backend::ActiveRecord.new
72
+ backends.push :db, ar_backend
69
73
  end
70
74
  end
71
75
  end
@@ -3,39 +3,119 @@
3
3
  require 'active_record'
4
4
  require 'blueprint_config/backend/active_record'
5
5
 
6
- ActiveRecord::Base.establish_connection adapter: 'sqlite3', database: ':memory:'
7
-
8
- ActiveRecord::Base.connection.create_table :settings do |t|
9
- t.string :key, null: false, index: { unique: true }
10
- t.integer :type, null: false, default: 0
11
- t.string :value
12
- t.timestamps
13
- end
14
-
15
6
  describe BlueprintConfig::Backend::ActiveRecord do
16
7
  let(:options) { {} }
17
8
  let(:subject) { described_class.new(options).load_keys }
18
- around do |example|
19
- ActiveRecord::Base.transaction do
9
+
10
+ context 'Database is correctly setup' do
11
+ around do |example|
12
+ ActiveRecord::Base.establish_connection adapter: 'sqlite3', database: ':memory:'
13
+
14
+ ActiveRecord::Base.connection.create_table :settings do |t|
15
+ t.string :key, null: false, index: { unique: true }
16
+ t.integer :type, null: false, default: 0
17
+ t.string :value
18
+ t.timestamps
19
+ end
20
+
20
21
  BlueprintConfig::Setting.create(key: 'foo', type: :string, value: 'bar')
21
22
  BlueprintConfig::Setting.create(key: 'x', type: :integer, value: '1')
22
23
  BlueprintConfig::Setting.create(key: 'a.b', type: :string, value: '1')
23
24
 
24
25
  example.run
25
- raise ActiveRecord::Rollback
26
+ ActiveRecord::Base.remove_connection
27
+ end
28
+
29
+ context 'with default options' do
30
+ it 'loads all keys' do
31
+ expect(subject).to eq({ foo: 'bar', "a.b": '1', x: 1 })
32
+ end
33
+ end
34
+
35
+ context 'when nesting enabled' do
36
+ let(:options) { { nest: true } }
37
+ it 'loads all keys' do
38
+ expect(subject).to eq({ foo: 'bar', a: { b: '1' }, x: 1 })
39
+ end
26
40
  end
27
41
  end
28
42
 
29
- context 'with default options' do
30
- it 'loads all keys' do
31
- expect(subject).to eq({ foo: 'bar', "a.b": '1', x: 1 })
43
+ context 'Database is not configured' do
44
+ it 'returns empty hash' do
45
+ expect(subject).to eq({})
32
46
  end
33
47
  end
34
48
 
35
- context 'when nesting enabled' do
36
- let(:options) { { nest: true } }
37
- it 'loads all keys' do
38
- expect(subject).to eq({ foo: 'bar', a: { b: '1' }, x: 1 })
49
+ context 'Database does not have proper table' do
50
+ around do |example|
51
+ ActiveRecord::Base.establish_connection adapter: 'sqlite3', database: ':memory:'
52
+
53
+ example.run
54
+ ActiveRecord::Base.remove_connection
55
+ end
56
+
57
+ it 'returns empty hash' do
58
+ expect(subject).to eq({})
59
+ end
60
+ it 'prints warning in console' do
61
+ expect { subject }.to output(a_string_including('blueprint_config:install'))
62
+ .to_stdout_from_any_process
63
+ end
64
+ context 'when silencing enabled' do
65
+ let(:options) { { silence_warnings: true } }
66
+ it 'prints nothing in console' do
67
+ expect { subject }.to_not output.to_stdout_from_any_process
68
+ end
69
+ end
70
+ end
71
+
72
+ context 'Database does table does not have correct attributes' do
73
+ around do |example|
74
+ ActiveRecord::Base.establish_connection adapter: 'sqlite3', database: ':memory:'
75
+ ActiveRecord::Base.connection.create_table :settings do |t|
76
+ t.string :alias, null: false, index: { unique: true }
77
+ t.integer :type, null: false, default: 0
78
+ t.string :string
79
+ end
80
+ BlueprintConfig::Setting.reset_column_information
81
+ BlueprintConfig::Setting.create(alias: 'foo', type: :string, string: 'bar')
82
+ BlueprintConfig::Setting.create(alias: 'x', type: :integer, string: '1')
83
+ BlueprintConfig::Setting.create(alias: 'a.b', type: :integer, string: '1')
84
+
85
+ example.run
86
+ ActiveRecord::Base.remove_connection
87
+ end
88
+
89
+ it 'returns empty hash' do
90
+ expect(subject).to eq({})
91
+ end
92
+ it 'prints warning in console' do
93
+ expect { subject }.to output(a_string_including('blueprint_config:install'))
94
+ .to_stdout_from_any_process
95
+ end
96
+ context 'when silencing enabled' do
97
+ let(:options) { { silence_warnings: true } }
98
+ it 'prints nothing in console' do
99
+ expect { subject }.to_not output.to_stdout_from_any_process
100
+ end
101
+ end
102
+ end
103
+
104
+ context 'Database does not have any records' do
105
+ around do |example|
106
+ ActiveRecord::Base.establish_connection adapter: 'sqlite3', database: ':memory:'
107
+ ActiveRecord::Base.connection.create_table :settings do |t|
108
+ t.string :key, null: false, index: { unique: true }
109
+ t.integer :type, null: false, default: 0
110
+ t.string :value
111
+ t.timestamps
112
+ end
113
+ example.run
114
+ ActiveRecord::Base.remove_connection
115
+ end
116
+
117
+ it 'returns empty hash' do
118
+ expect(subject).to eq({})
39
119
  end
40
120
  end
41
121
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: blueprint_config
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vladimir Elchinov
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2024-01-08 00:00:00.000000000 Z
12
+ date: 2024-01-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord