sourced_config 0.1.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 +7 -0
- data/.standard.yml +3 -0
- data/CHANGELOG.md +5 -0
- data/Gemfile +14 -0
- data/LICENSE.txt +21 -0
- data/README.md +47 -0
- data/Rakefile +14 -0
- data/lib/sourced_config/config_contract.rb +28 -0
- data/lib/sourced_config/config_manager.rb +97 -0
- data/lib/sourced_config/locale/g_sheets_client.rb +54 -0
- data/lib/sourced_config/locale/i18n_backend.rb +22 -0
- data/lib/sourced_config/locale/loader.rb +54 -0
- data/lib/sourced_config/locale/null_client.rb +11 -0
- data/lib/sourced_config/locale/s3_config_client.rb +29 -0
- data/lib/sourced_config/railtie.rb +7 -0
- data/lib/sourced_config/s3_file.rb +11 -0
- data/lib/sourced_config/version.rb +5 -0
- data/lib/sourced_config.rb +110 -0
- data/lib/tasks/sourced_config_tasks.rake +4 -0
- data/sig/sourced_config.rbs +4 -0
- metadata +122 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 67bcae6215d95ddc63e2dd5522805c69b73c4357756160d765a9f5581404152d
|
4
|
+
data.tar.gz: e6d714e45c36234238ff22c7c1390273de3df7b4c9d6ea1f52ee9829946f8ff4
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8d786b59013736cceb1435f5e88351cff813658f88ba88a0a1a927f32c2ad5baf5668b7ed7565179b880f21de5c206cb8b89454798c6545dbc52f8c7578d74ba
|
7
|
+
data.tar.gz: 977b760623e3e29f545de365193b83c2f1555274ed53c68dcb6941b13d56beec8b3b7c976703998a57a8ad04ad1c58c198b6eab451336a37748a0804e408f92d
|
data/.standard.yml
ADDED
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2022 Stephen Ierodiaconou
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
# SourcedConfig
|
2
|
+
|
3
|
+
App configuration & Locales for Rails apps where the config is loaded from a remote or local non-repo source.
|
4
|
+
|
5
|
+
Useful in apps that are 'white-labeled' and can have different configurations for different deployments.
|
6
|
+
|
7
|
+
Config can be loaded from:
|
8
|
+
- S3
|
9
|
+
- Local files
|
10
|
+
|
11
|
+
Locale data can be loaded from:
|
12
|
+
- S3
|
13
|
+
- Local files
|
14
|
+
- Google Spreadsheets
|
15
|
+
|
16
|
+
## Installation
|
17
|
+
|
18
|
+
Install the gem and add to the application's Gemfile by executing:
|
19
|
+
|
20
|
+
$ bundle add sourced_config
|
21
|
+
|
22
|
+
If bundler is not being used to manage dependencies, install the gem by executing:
|
23
|
+
|
24
|
+
$ gem install sourced_config
|
25
|
+
|
26
|
+
## Usage
|
27
|
+
|
28
|
+
TODO: Write usage instructions here
|
29
|
+
|
30
|
+
- Add an initializer to your app to configure the gem
|
31
|
+
- Add a base config file to your app
|
32
|
+
|
33
|
+
Access config with `SourcedConfig[key]`
|
34
|
+
|
35
|
+
## Development
|
36
|
+
|
37
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
38
|
+
|
39
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
40
|
+
|
41
|
+
## Contributing
|
42
|
+
|
43
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/sourced_config.
|
44
|
+
|
45
|
+
## License
|
46
|
+
|
47
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "bundler/gem_tasks"
|
4
|
+
require "rake/testtask"
|
5
|
+
|
6
|
+
Rake::TestTask.new(:test) do |t|
|
7
|
+
t.libs << "test"
|
8
|
+
t.libs << "lib"
|
9
|
+
t.test_files = FileList["test/**/*_test.rb"]
|
10
|
+
end
|
11
|
+
|
12
|
+
require "standard/rake"
|
13
|
+
|
14
|
+
task default: %i[test standard]
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry-monads"
|
4
|
+
require "dry-validation"
|
5
|
+
|
6
|
+
module SourcedConfig
|
7
|
+
class ConfigContract < ::Dry::Validation::Contract
|
8
|
+
::Dry::Validation.load_extensions(:monads)
|
9
|
+
|
10
|
+
class LocalesConfig < ConfigContract
|
11
|
+
params do
|
12
|
+
required(:supported).filled(array[:string])
|
13
|
+
optional(:load_from_type).filled(:string)
|
14
|
+
optional(:load_from_source).maybe(:string)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
params do
|
19
|
+
required(:locales).hash(LocalesConfig.schema)
|
20
|
+
end
|
21
|
+
|
22
|
+
class << self
|
23
|
+
def key_names
|
24
|
+
schema.key_map.map(&:name)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SourcedConfig
|
4
|
+
class ConfigManager
|
5
|
+
SOURCE_TYPE_LOCAL_FILE = "local_file"
|
6
|
+
SOURCE_TYPE_S3_CONFIG_BUCKET = "s3_config_bucket"
|
7
|
+
|
8
|
+
def root(key, raises: false)
|
9
|
+
raise ConfigurationNotLoadedError, "You cannot access config nodes until you have loaded configuration!" unless loaded?
|
10
|
+
raise ConfigurationRootKeyNotFoundError, "Config key #{key} not found" if raises && !configuration.key?(key)
|
11
|
+
configuration[key]
|
12
|
+
end
|
13
|
+
|
14
|
+
def load!(external_type, external_source_path)
|
15
|
+
Rails.logger.info "Load configuration data from #{external_type} - #{external_source_path}" if external_type
|
16
|
+
if loaded?
|
17
|
+
Rails.logger.warn "An attempt to load configuration happened when it is already loaded"
|
18
|
+
return false
|
19
|
+
end
|
20
|
+
primary_config = load_yaml_and_parse_erb(SourcedConfig.configuration.base_configuration_file_path).deep_symbolize_keys
|
21
|
+
external = external_type.present? && load_external_config(external_type, external_source_path).deep_symbolize_keys
|
22
|
+
|
23
|
+
schema = SourcedConfig.configuration.config_schema_klass.new
|
24
|
+
config_contract = schema.call(external ? primary_config.deep_merge(external) : primary_config)
|
25
|
+
if config_contract.failure?
|
26
|
+
messages = config_contract.errors(full: true).to_h
|
27
|
+
Rails.logger.error "Error in configuration file! #{messages}"
|
28
|
+
raise InvalidConfigurationError, "Failed to load configuration data! #{messages}"
|
29
|
+
end
|
30
|
+
@configuration = config_contract
|
31
|
+
|
32
|
+
loaded?
|
33
|
+
end
|
34
|
+
|
35
|
+
# Reload configuration files, only in development, this is hooked up to a file watcher on the config file
|
36
|
+
# and external directory if specified.
|
37
|
+
def reload!(external_type, external_source_path, force: false)
|
38
|
+
return false if Rails.env.production? && !force
|
39
|
+
Rails.logger.warn "Something changed: Reloading application configuration!"
|
40
|
+
@configuration = nil
|
41
|
+
load!(external_type, external_source_path)
|
42
|
+
end
|
43
|
+
|
44
|
+
def loaded?
|
45
|
+
configuration.present?
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
attr_reader :configuration
|
51
|
+
|
52
|
+
def load_external_config(external_type, external_source_path)
|
53
|
+
Rails.logger.info "Load external configuration data #{external_type}: #{external_source_path}"
|
54
|
+
case external_type
|
55
|
+
when SOURCE_TYPE_LOCAL_FILE
|
56
|
+
load_yaml(external_source_path)
|
57
|
+
when SOURCE_TYPE_S3_CONFIG_BUCKET
|
58
|
+
load_s3_config_bucket_file(external_source_path)
|
59
|
+
else
|
60
|
+
Rails.logger.error "Cannot load external configuration data for unknown #{external_type}"
|
61
|
+
raise ArgumentError, "Invalid external file type"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def load_yaml_and_parse_erb(file)
|
66
|
+
parsed = ERB.new(File.read(file)).result(binding)
|
67
|
+
parse_yaml(parsed)
|
68
|
+
end
|
69
|
+
|
70
|
+
def parse_yaml(str)
|
71
|
+
YAML.safe_load(str, permitted_classes: [Symbol])
|
72
|
+
end
|
73
|
+
|
74
|
+
def load_s3_config_bucket_file(path)
|
75
|
+
file = path || s3_file_path
|
76
|
+
Rails.logger.info "Loading from S3 #{s3_bucket} - #{s3_region} - #{file}"
|
77
|
+
s = SourcedConfig::S3File.read(s3_bucket, file, s3_region)
|
78
|
+
parse_yaml(s)
|
79
|
+
end
|
80
|
+
|
81
|
+
def s3_file_path
|
82
|
+
SourcedConfig.configuration.configuration_file_path
|
83
|
+
end
|
84
|
+
|
85
|
+
def s3_bucket
|
86
|
+
SourcedConfig.configuration.configuration_bucket
|
87
|
+
end
|
88
|
+
|
89
|
+
def s3_region
|
90
|
+
SourcedConfig.configuration.configuration_bucket_region
|
91
|
+
end
|
92
|
+
|
93
|
+
def load_yaml(file)
|
94
|
+
YAML.safe_load_file(file, permitted_classes: [Symbol])
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "csv"
|
4
|
+
|
5
|
+
module SourcedConfig
|
6
|
+
module Locale
|
7
|
+
class GSheetsClient
|
8
|
+
def initialize(url)
|
9
|
+
@url = url
|
10
|
+
end
|
11
|
+
|
12
|
+
attr_reader :url
|
13
|
+
|
14
|
+
def load(locale)
|
15
|
+
Rails.logger.debug { "[locale - #{locale}] Strings read (as UTF-8) from remote URL #{url}" }
|
16
|
+
content = get_content
|
17
|
+
parse_body(content.body.force_encoding("UTF-8")).reduce({}) do |memo, row|
|
18
|
+
parse_item(row, memo)
|
19
|
+
end
|
20
|
+
rescue => e
|
21
|
+
Rails.logger.error "[locale - #{locale}] Could not fetch TSV doc directly from Google Spreadsheets: #{e.message}"
|
22
|
+
{}
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def parse_body(text)
|
28
|
+
CSV.parse(text, col_sep: "\t", quote_char: "^", skip_lines: /^\s*#.*$/, skip_blanks: true, headers: true)
|
29
|
+
end
|
30
|
+
|
31
|
+
def parse_item(item, locale_hash)
|
32
|
+
*keys, string = item.to_a.map { |x| x[1] }
|
33
|
+
keys.compact!
|
34
|
+
leaf_item = keys[..-2].reduce(locale_hash) do |h, k|
|
35
|
+
next h unless k.present?
|
36
|
+
h[k] ||= {}
|
37
|
+
end
|
38
|
+
leaf_item[keys.last] = string
|
39
|
+
locale_hash
|
40
|
+
end
|
41
|
+
|
42
|
+
def get_content
|
43
|
+
uri = URI.parse(url)
|
44
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
45
|
+
http.read_timeout = 5
|
46
|
+
http.open_timeout = 5
|
47
|
+
http.use_ssl = true
|
48
|
+
http.start do |http|
|
49
|
+
http.get(uri.request_uri)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "loader"
|
4
|
+
require_relative "null_client"
|
5
|
+
|
6
|
+
module SourcedConfig
|
7
|
+
module Locale
|
8
|
+
class I18nBackend < ::I18n::Backend::Simple
|
9
|
+
def load_translations
|
10
|
+
return unless ::SourcedConfig.loaded?
|
11
|
+
type = ::SourcedConfig[:locales][:load_from_type]
|
12
|
+
source = ::SourcedConfig[:locales][:load_from_source]
|
13
|
+
null_client = Rails.env.test? ? NullClient.new : nil
|
14
|
+
loader = Loader.new(type, source, client: null_client)
|
15
|
+
::SourcedConfig[:locales][:supported].each do |locale|
|
16
|
+
Rails.logger.info "Load I18n: for supported locale #{locale}"
|
17
|
+
store_translations(locale, loader.load(locale.to_sym)[locale])
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "./g_sheets_client"
|
4
|
+
require_relative "./s3_config_client"
|
5
|
+
|
6
|
+
module SourcedConfig
|
7
|
+
module Locale
|
8
|
+
class Loader
|
9
|
+
COPY_SOURCE_TYPE_LOCAL_DIRECTORY = "local-directory"
|
10
|
+
COPY_SOURCE_TYPE_S3_CONFIG = "s3-config"
|
11
|
+
COPY_SOURCE_TYPE_GOOGLE_SHEETS = "google-sheets"
|
12
|
+
COPY_SOURCE_TYPE_DEFAULT = "default"
|
13
|
+
|
14
|
+
def initialize(type, source, client: nil)
|
15
|
+
@type = type
|
16
|
+
@source = source
|
17
|
+
@client = client
|
18
|
+
end
|
19
|
+
|
20
|
+
attr_reader :locale, :type, :source
|
21
|
+
|
22
|
+
def load(locale)
|
23
|
+
Rails.logger.debug { "[locale - #{locale}] Load copy from #{type} #{source}" }
|
24
|
+
case type
|
25
|
+
when COPY_SOURCE_TYPE_LOCAL_DIRECTORY
|
26
|
+
HashWithIndifferentAccess.new load_from_local_dir(locale)
|
27
|
+
when COPY_SOURCE_TYPE_S3_CONFIG, COPY_SOURCE_TYPE_GOOGLE_SHEETS
|
28
|
+
HashWithIndifferentAccess.new(locale => HashWithIndifferentAccess.new(client.load(locale)))
|
29
|
+
when COPY_SOURCE_TYPE_DEFAULT
|
30
|
+
Rails.logger.warn "[locale - #{locale}] Using only default app copy"
|
31
|
+
HashWithIndifferentAccess.new(locale => {})
|
32
|
+
else
|
33
|
+
raise StandardError, "When loading the Copy and Content the type was unrecognised! #{type}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def client
|
40
|
+
return @client if @client
|
41
|
+
@client = case type
|
42
|
+
when COPY_SOURCE_TYPE_S3_CONFIG
|
43
|
+
S3ConfigClient.new
|
44
|
+
when COPY_SOURCE_TYPE_GOOGLE_SHEETS
|
45
|
+
GSheetsClient.new(source)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def load_from_local_dir(locale)
|
50
|
+
YAML.safe_load_file(Rails.root.join(source, "#{locale}.yml")) || {}
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../s3_file"
|
4
|
+
|
5
|
+
module SourcedConfig
|
6
|
+
module Locale
|
7
|
+
class S3ConfigClient
|
8
|
+
def initialize(
|
9
|
+
bucket: ::SourcedConfig.configuration.configuration_bucket,
|
10
|
+
region: ::SourcedConfig.configuration.configuration_bucket_region
|
11
|
+
)
|
12
|
+
@bucket = bucket
|
13
|
+
@region = region
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_reader :bucket, :region
|
17
|
+
|
18
|
+
def load(locale)
|
19
|
+
Rails.logger.debug "Locale read from S3 locale file"
|
20
|
+
file = "locales/#{locale}.yml" # TODO: make this configurable
|
21
|
+
str = ::SourcedConfig::S3File.read(bucket, file, region)
|
22
|
+
yaml = YAML.safe_load(str)
|
23
|
+
root_node = yaml[locale.to_s]
|
24
|
+
return {} if root_node.blank?
|
25
|
+
root_node
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SourcedConfig
|
4
|
+
class S3File
|
5
|
+
def self.read(bucket, path, region, retry_limit: 10)
|
6
|
+
s3 = Aws::S3::Client.new(retry_limit: retry_limit, region: region)
|
7
|
+
resp = s3.get_object(bucket: bucket, key: path)
|
8
|
+
resp.body
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "sourced_config/version"
|
4
|
+
require_relative "sourced_config/railtie"
|
5
|
+
require_relative "sourced_config/config_manager"
|
6
|
+
require_relative "sourced_config/config_contract"
|
7
|
+
require_relative "sourced_config/locale/i18n_backend"
|
8
|
+
|
9
|
+
module SourcedConfig
|
10
|
+
class ConfigurationNotLoadedError < StandardError; end
|
11
|
+
|
12
|
+
class InvalidConfigurationError < StandardError; end
|
13
|
+
|
14
|
+
class ConfigurationRootKeyNotFoundError < StandardError; end
|
15
|
+
|
16
|
+
class << self
|
17
|
+
def configuration
|
18
|
+
@configuration ||= Configuration.new
|
19
|
+
end
|
20
|
+
|
21
|
+
def configure
|
22
|
+
yield(configuration) if block_given?
|
23
|
+
configuration
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class Configuration
|
28
|
+
attr_accessor :config_schema_klass,
|
29
|
+
:config_type,
|
30
|
+
:base_configuration_file_path, # Can also be ERB
|
31
|
+
:configuration_bucket,
|
32
|
+
:configuration_bucket_region,
|
33
|
+
:configuration_file_path # Can not be ERB
|
34
|
+
|
35
|
+
def initialize
|
36
|
+
@config_schema_klass = ConfigContract
|
37
|
+
@base_configuration_file_path = Rails.root.join("config/config.yml.erb")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# The configuration class API
|
42
|
+
# Uses the ConfigManager to actually hold and prepare configuration data
|
43
|
+
class << self
|
44
|
+
# https://github.com/rails/rails/blob/master/activesupport/lib/active_support/i18n_railtie.rb
|
45
|
+
@inited = false
|
46
|
+
|
47
|
+
def config_type_file?
|
48
|
+
configuration.config_type == ConfigManager::SOURCE_TYPE_LOCAL_FILE
|
49
|
+
end
|
50
|
+
|
51
|
+
def setup(app)
|
52
|
+
return if @inited
|
53
|
+
|
54
|
+
I18n.backend = I18n::Backend::Chain.new(Locale::I18nBackend.new, I18n.backend)
|
55
|
+
|
56
|
+
files = [configuration.base_configuration_file_path]
|
57
|
+
|
58
|
+
files << Rails.root.join(configuration.configuration_file_path) if config_type_file?
|
59
|
+
|
60
|
+
reloader = app.config.file_watcher.new(files) do
|
61
|
+
Rails.logger.warn "*** Application configuration changed in #{Rails.env} " \
|
62
|
+
"(zeitwerk: #{Rails.autoloaders.zeitwerk_enabled?})"
|
63
|
+
SourcedConfig.load!(configuration.config_type, configuration.configuration_file_path)
|
64
|
+
end
|
65
|
+
|
66
|
+
app.reloaders << reloader
|
67
|
+
app.reloader.to_run do
|
68
|
+
# We are *not* using execute_if_updated cause if anything causes Classes to be reloaded it will kill the config
|
69
|
+
# persisted in the class variable in the Config singleton. So we want to always execute a reload (eg when
|
70
|
+
# I18n content changes)
|
71
|
+
reloader.execute { require_unload_lock! }
|
72
|
+
end
|
73
|
+
|
74
|
+
# Load now
|
75
|
+
reloader.execute
|
76
|
+
|
77
|
+
@started_up ||= Time.zone.now
|
78
|
+
@inited = true
|
79
|
+
end
|
80
|
+
|
81
|
+
def load!(type = SourcedConfig.configuration.config_type, source_path = SourcedConfig.configuration.configuration_file_path, force: false)
|
82
|
+
loaded? ? manager.reload!(type, source_path, force: force) : manager.load!(type, source_path)
|
83
|
+
end
|
84
|
+
|
85
|
+
def startup_time
|
86
|
+
@started_up
|
87
|
+
end
|
88
|
+
|
89
|
+
# Get a key from the configuration
|
90
|
+
def [](key)
|
91
|
+
manager.root(key)
|
92
|
+
end
|
93
|
+
|
94
|
+
# Dig lets you reach in and extract deeply nested keys from an array of keys. Note will NOT raise if the key
|
95
|
+
# doesnt exist, like Hash#dig etc
|
96
|
+
def dig(root, *keys)
|
97
|
+
manager.root(root).dig(*keys)
|
98
|
+
end
|
99
|
+
|
100
|
+
def loaded?
|
101
|
+
manager&.loaded?
|
102
|
+
end
|
103
|
+
|
104
|
+
private
|
105
|
+
|
106
|
+
def manager
|
107
|
+
@manager ||= ConfigManager.new
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
metadata
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sourced_config
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Stephen Ierodiaconou
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2022-11-22 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: aws-sdk-s3
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rails
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '6'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '6'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: dry-monads
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: dry-validation
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: Load configuration & locales for Rails apps from a remote or local non-repo
|
70
|
+
source.
|
71
|
+
email:
|
72
|
+
- stevegeek@gmail.com
|
73
|
+
executables: []
|
74
|
+
extensions: []
|
75
|
+
extra_rdoc_files: []
|
76
|
+
files:
|
77
|
+
- ".standard.yml"
|
78
|
+
- CHANGELOG.md
|
79
|
+
- Gemfile
|
80
|
+
- LICENSE.txt
|
81
|
+
- README.md
|
82
|
+
- Rakefile
|
83
|
+
- lib/sourced_config.rb
|
84
|
+
- lib/sourced_config/config_contract.rb
|
85
|
+
- lib/sourced_config/config_manager.rb
|
86
|
+
- lib/sourced_config/locale/g_sheets_client.rb
|
87
|
+
- lib/sourced_config/locale/i18n_backend.rb
|
88
|
+
- lib/sourced_config/locale/loader.rb
|
89
|
+
- lib/sourced_config/locale/null_client.rb
|
90
|
+
- lib/sourced_config/locale/s3_config_client.rb
|
91
|
+
- lib/sourced_config/railtie.rb
|
92
|
+
- lib/sourced_config/s3_file.rb
|
93
|
+
- lib/sourced_config/version.rb
|
94
|
+
- lib/tasks/sourced_config_tasks.rake
|
95
|
+
- sig/sourced_config.rbs
|
96
|
+
homepage: https://github.com/stevegeek/sourced_config
|
97
|
+
licenses:
|
98
|
+
- MIT
|
99
|
+
metadata:
|
100
|
+
homepage_uri: https://github.com/stevegeek/sourced_config
|
101
|
+
source_code_uri: https://github.com/stevegeek/sourced_config
|
102
|
+
post_install_message:
|
103
|
+
rdoc_options: []
|
104
|
+
require_paths:
|
105
|
+
- lib
|
106
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 2.7.0
|
111
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
112
|
+
requirements:
|
113
|
+
- - ">="
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
version: '0'
|
116
|
+
requirements: []
|
117
|
+
rubygems_version: 3.3.7
|
118
|
+
signing_key:
|
119
|
+
specification_version: 4
|
120
|
+
summary: Load configuration & locales for Rails apps from a remote or local non-repo
|
121
|
+
source.
|
122
|
+
test_files: []
|