configature 0.1.0 → 0.3.3
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 +4 -4
- data/.gitignore +2 -0
- data/.travis.yml +7 -2
- data/Gemfile +6 -0
- data/Gemfile.lock +14 -14
- data/LICENSE.txt +1 -1
- data/README.md +87 -9
- data/VERSION +1 -1
- data/configature.gemspec +0 -4
- data/exe/config +13 -21
- data/lib/configature.rb +12 -37
- data/lib/configature/config.rb +93 -0
- data/lib/configature/data.rb +26 -0
- data/lib/configature/directory.rb +23 -0
- data/lib/configature/namespace.rb +163 -0
- data/lib/configature/stamper.rb +53 -0
- data/lib/configature/support.rb +45 -0
- metadata +10 -46
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 61bfe9a27a2905f469bfd446a01e8291a33a5e66ac87761d18f83f2959a8237e
|
4
|
+
data.tar.gz: 4812cfcdb1573f15a2e97ce4a23a204a28f2b76f6ef448b06f37dcadbf07c99d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c5c230c614c28c9e423fa38bd2798e7730e450c19ee9c59702a8ca993103b10bb8f6559b6128d5fc233ea25aa13b857eed9e8954b078976ea16f2c3ff718d1a8
|
7
|
+
data.tar.gz: 2b9136bcbde3a3fc9b9c1724d072353b4f0c39587c33671dbad76c8b56673082f6ef90b34b64cf1e0654e53c2ab201dbdd97ad54c004c2a62398e23f2b4f6f3b
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,26 +1,26 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
configature (0.
|
4
|
+
configature (0.3.3)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
8
8
|
specs:
|
9
9
|
diff-lcs (1.3)
|
10
|
-
rake (
|
11
|
-
rspec (3.
|
12
|
-
rspec-core (~> 3.
|
13
|
-
rspec-expectations (~> 3.
|
14
|
-
rspec-mocks (~> 3.
|
15
|
-
rspec-core (3.
|
16
|
-
rspec-support (~> 3.
|
17
|
-
rspec-expectations (3.
|
10
|
+
rake (13.0.1)
|
11
|
+
rspec (3.9.0)
|
12
|
+
rspec-core (~> 3.9.0)
|
13
|
+
rspec-expectations (~> 3.9.0)
|
14
|
+
rspec-mocks (~> 3.9.0)
|
15
|
+
rspec-core (3.9.1)
|
16
|
+
rspec-support (~> 3.9.1)
|
17
|
+
rspec-expectations (3.9.0)
|
18
18
|
diff-lcs (>= 1.2.0, < 2.0)
|
19
|
-
rspec-support (~> 3.
|
20
|
-
rspec-mocks (3.
|
19
|
+
rspec-support (~> 3.9.0)
|
20
|
+
rspec-mocks (3.9.1)
|
21
21
|
diff-lcs (>= 1.2.0, < 2.0)
|
22
|
-
rspec-support (~> 3.
|
23
|
-
rspec-support (3.
|
22
|
+
rspec-support (~> 3.9.0)
|
23
|
+
rspec-support (3.9.2)
|
24
24
|
|
25
25
|
PLATFORMS
|
26
26
|
ruby
|
@@ -32,4 +32,4 @@ DEPENDENCIES
|
|
32
32
|
rspec
|
33
33
|
|
34
34
|
BUNDLED WITH
|
35
|
-
2.
|
35
|
+
2.1.4
|
data/LICENSE.txt
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
The MIT License (MIT)
|
2
2
|
|
3
|
-
Copyright (c) 2019 Scott Tadman, PostageApp Ltd.
|
3
|
+
Copyright (c) 2019-2020 Scott Tadman, PostageApp Ltd.
|
4
4
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
data/README.md
CHANGED
@@ -12,32 +12,110 @@ gem 'configature'
|
|
12
12
|
|
13
13
|
And then execute:
|
14
14
|
|
15
|
-
|
16
|
-
|
15
|
+
```shell
|
16
|
+
bundle
|
17
|
+
bundle binstubs configature
|
18
|
+
```
|
17
19
|
|
18
20
|
Or install it yourself as:
|
19
21
|
|
20
|
-
|
22
|
+
```shell
|
23
|
+
gem install configature
|
24
|
+
```
|
21
25
|
|
22
26
|
## Usage
|
23
27
|
|
24
|
-
|
28
|
+
Configuature expects a `config/` directory that contains one or more files
|
29
|
+
with the file extension `.example`, as in `database.yml.example`. Any files
|
30
|
+
of that form found will be copied to their corresponding name minus the
|
31
|
+
`.example` extension *if* no such file exists.
|
32
|
+
|
33
|
+
This is done with the command:
|
34
|
+
|
35
|
+
```shell
|
36
|
+
bin/config
|
37
|
+
```
|
38
|
+
|
39
|
+
Where files already exist these are not touched, but are noted in the output
|
40
|
+
as being "present".
|
41
|
+
|
42
|
+
The opposite step is to remove these files:
|
43
|
+
|
44
|
+
```shell
|
45
|
+
bin/config clean
|
46
|
+
```
|
47
|
+
|
48
|
+
<blockquote>
|
49
|
+
Keep in mind this may remove important credentials so this should be done
|
50
|
+
carefully if and only if necessary.
|
51
|
+
</blockquote>
|
52
|
+
|
53
|
+
### Definining Configuration
|
54
|
+
|
55
|
+
Most applications should have a configuration definition like this where
|
56
|
+
one or more *namespace* is defined where configuration information is stored:
|
57
|
+
|
58
|
+
```ruby
|
59
|
+
class MyConfig < Configature::Config
|
60
|
+
namespace :example do
|
61
|
+
argument default: 'value'
|
62
|
+
end
|
63
|
+
end
|
64
|
+
```
|
65
|
+
|
66
|
+
In this case a single namespace is defined. When instantiated the configuration
|
67
|
+
values can be read:
|
68
|
+
|
69
|
+
```ruby
|
70
|
+
config = MyConfig.new
|
71
|
+
config.example.argument
|
72
|
+
# => 'value'
|
73
|
+
```
|
74
|
+
|
75
|
+
This can also be accessed through a factory method that provides convenient
|
76
|
+
defaults:
|
77
|
+
|
78
|
+
```ruby
|
79
|
+
Config.example.argument
|
80
|
+
# => 'value'
|
81
|
+
```
|
82
|
+
|
83
|
+
In most cases this can be adequate. The `MyConfig.new` approach allows
|
84
|
+
specifying which config file to load and which environment to read from,
|
85
|
+
something that may be important in some situations.
|
86
|
+
|
87
|
+
The default is to load from `ENV`, the main environment, and `config/`
|
88
|
+
relative to `Rails.root` if `Rails` is defined.
|
25
89
|
|
90
|
+
This value can be overridden with the environment variable `EXAMPLE_ARGUMENT`
|
91
|
+
or in a config file `config/example.yml` under the `argument:` key.
|
26
92
|
|
27
93
|
## Development
|
28
94
|
|
29
|
-
After checking out the repo, run `bin/setup` to install dependencies. Then,
|
95
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then,
|
96
|
+
run `rake spec` to run the tests. You can also run `bin/console` for an
|
97
|
+
interactive prompt that will allow you to experiment.
|
30
98
|
|
31
|
-
To install this gem onto your local machine, run `bundle exec rake install`.
|
99
|
+
To install this gem onto your local machine, run `bundle exec rake install`.
|
100
|
+
To release a new version, update the version number in `version.rb`, and
|
101
|
+
then run `bundle exec rake release`, which will create a git tag for the
|
102
|
+
version, push git commits and tags, and push the `.gem` file to
|
103
|
+
[rubygems.org](https://rubygems.org).
|
32
104
|
|
33
105
|
## Contributing
|
34
106
|
|
35
|
-
Bug reports and pull requests are welcome on GitHub
|
107
|
+
Bug reports and pull requests are welcome on [GitHub](https://github.com/postageapp/configature).
|
108
|
+
This project is intended to be a safe, welcoming space for collaboration, and
|
109
|
+
contributors are expected to adhere to the
|
110
|
+
[Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
36
111
|
|
37
112
|
## License
|
38
113
|
|
39
|
-
The gem is available as open source under the terms of the
|
114
|
+
The gem is available as open source under the terms of the
|
115
|
+
[MIT License](https://opensource.org/licenses/MIT).
|
40
116
|
|
41
117
|
## Code of Conduct
|
42
118
|
|
43
|
-
Everyone interacting in the Configature project’s codebases, issue trackers,
|
119
|
+
Everyone interacting in the Configature project’s codebases, issue trackers,
|
120
|
+
chat rooms and mailing lists is expected to follow the
|
121
|
+
[code of conduct](https://github.com/tadman/configature/blob/master/CODE_OF_CONDUCT.md).
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.3.3
|
data/configature.gemspec
CHANGED
@@ -35,8 +35,4 @@ Gem::Specification.new do |spec|
|
|
35
35
|
spec.bindir = 'exe'
|
36
36
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
37
37
|
spec.require_paths = %w[ lib ]
|
38
|
-
|
39
|
-
spec.add_development_dependency 'bundler'
|
40
|
-
spec.add_development_dependency 'rake'
|
41
|
-
spec.add_development_dependency 'rspec'
|
42
38
|
end
|
data/exe/config
CHANGED
@@ -12,7 +12,7 @@ require_relative '../lib/configature'
|
|
12
12
|
options = {
|
13
13
|
verbose: false,
|
14
14
|
quiet: false,
|
15
|
-
config_dir: Configature.
|
15
|
+
config_dir: Configature::Directory.find('config')
|
16
16
|
}
|
17
17
|
|
18
18
|
program = OptionParser.new do |opts|
|
@@ -42,30 +42,22 @@ end
|
|
42
42
|
|
43
43
|
case (arg = args.first)
|
44
44
|
when 'clean'
|
45
|
-
Configature.
|
46
|
-
|
47
|
-
print "* %s: " % File.basename(target)
|
48
|
-
File.unlink(target)
|
49
|
-
puts "removed"
|
50
|
-
end
|
45
|
+
Configature::Stamper.new(options[:config_dir]).clean! do |target|
|
46
|
+
puts "* %s: removed" % File.basename(target)
|
51
47
|
end
|
52
48
|
when nil
|
53
|
-
Configature.
|
54
|
-
if (
|
55
|
-
|
56
|
-
puts "* %s: present (requires configuration)" % File.basename(target)
|
57
|
-
else
|
58
|
-
puts "* %s: present" % File.basename(target)
|
59
|
-
end
|
49
|
+
Configature::Stamper.new(options[:config_dir]).apply! do |source, target, created:, existing:, config_required:|
|
50
|
+
if (created)
|
51
|
+
print "* %s: created" % File.basename(target)
|
60
52
|
else
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
puts "* %s: created" % File.basename(target)
|
67
|
-
end
|
53
|
+
print "* %s: present" % File.basename(target)
|
54
|
+
end
|
55
|
+
|
56
|
+
if (config_required)
|
57
|
+
print ' (requires configuration)'
|
68
58
|
end
|
59
|
+
|
60
|
+
puts
|
69
61
|
end
|
70
62
|
else
|
71
63
|
$stderr.puts("Unknown command #{arg.inspect}")
|
data/lib/configature.rb
CHANGED
@@ -1,46 +1,21 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
1
3
|
module Configature
|
2
|
-
VERSION = File.readlines(
|
4
|
+
VERSION = File.readlines(
|
5
|
+
File.expand_path('../VERSION', __dir__)
|
6
|
+
).first.chomp.freeze
|
3
7
|
|
4
8
|
class Error < StandardError; end
|
5
|
-
# Your code goes here...
|
6
9
|
|
7
10
|
def self.version
|
8
11
|
VERSION
|
9
12
|
end
|
13
|
+
end
|
10
14
|
|
11
|
-
|
12
|
-
Enumerator.new do |y|
|
13
|
-
y << dir
|
14
|
-
|
15
|
-
loop do
|
16
|
-
last, dir = dir, File.expand_path('../', dir)
|
17
|
-
|
18
|
-
break if (last == dir)
|
19
|
-
|
20
|
-
y << dir
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
def self.config_dir
|
26
|
-
dir_plus_parents(Dir.pwd).lazy.map do |dir|
|
27
|
-
File.expand_path('config', dir)
|
28
|
-
end.find do |dir|
|
29
|
-
File.directory?(dir)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def self.configable_examples(dir)
|
34
|
-
map = Dir.glob(File.expand_path('*.example', dir)).map do |source|
|
35
|
-
[ source, source.delete_suffix('.example') ]
|
36
|
-
end.to_h
|
37
|
-
|
38
|
-
if (block_given?)
|
39
|
-
map.each do |k,v|
|
40
|
-
yield(k, v)
|
41
|
-
end
|
42
|
-
end
|
15
|
+
require_relative './configature/support'
|
43
16
|
|
44
|
-
|
45
|
-
|
46
|
-
|
17
|
+
require_relative './configature/config'
|
18
|
+
require_relative './configature/data'
|
19
|
+
require_relative './configature/directory'
|
20
|
+
require_relative './configature/namespace'
|
21
|
+
require_relative './configature/stamper'
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'date'
|
2
|
+
|
3
|
+
require_relative './data'
|
4
|
+
require_relative './support'
|
5
|
+
|
6
|
+
require_relative './namespace'
|
7
|
+
|
8
|
+
class Configature::Config < Configature::Data
|
9
|
+
# == Constants ============================================================
|
10
|
+
|
11
|
+
# == Properties ===========================================================
|
12
|
+
|
13
|
+
# == Class Methods ========================================================
|
14
|
+
|
15
|
+
def self.config_dir
|
16
|
+
@config_dir ||= defined?(Rails) && Rails.root.join('config/')
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.config_dir=(dir)
|
20
|
+
@config_dir = dir
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.namespace(name, file: nil, env_suffix: '', extends: nil, &block)
|
24
|
+
namespace = self.namespaces[name] = Configature::Namespace.new(name, env_suffix: env_suffix, extends: extends && self.namespaces[extends]).tap do |n|
|
25
|
+
case (block&.arity)
|
26
|
+
when nil
|
27
|
+
nil
|
28
|
+
when 1
|
29
|
+
block[n]
|
30
|
+
else
|
31
|
+
n.instance_eval(&block)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
file = file&.to_s || name.to_s
|
36
|
+
|
37
|
+
if (file and !file.include?('.'))
|
38
|
+
file += '.yml'
|
39
|
+
end
|
40
|
+
|
41
|
+
unless (self.respond_to?(name))
|
42
|
+
iv = :"@#{name}"
|
43
|
+
|
44
|
+
singleton_class.send(:define_method, name) do
|
45
|
+
config_path = File.expand_path(file, self.config_dir)
|
46
|
+
|
47
|
+
config = Configature::Support.yaml_if_exist(config_path)
|
48
|
+
|
49
|
+
instance_variable_get(iv) or instance_variable_set(iv, namespace.__instantiate(source: config))
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.namespaces
|
55
|
+
@namespaces ||= { }
|
56
|
+
end
|
57
|
+
|
58
|
+
# == Instance Methods =====================================================
|
59
|
+
|
60
|
+
def initialize(config_dir: nil, env: ENV)
|
61
|
+
super(
|
62
|
+
self.class.namespaces.map do |name, namespace|
|
63
|
+
config_path = File.expand_path('%s.yml' % name, config_dir || self.class.config_dir)
|
64
|
+
|
65
|
+
config = Configature::Support.yaml_if_exist(config_path)
|
66
|
+
|
67
|
+
[
|
68
|
+
name,
|
69
|
+
Configature::Support.convert_hashes(
|
70
|
+
Configature::Data,
|
71
|
+
namespace.__instantiate(source: config, env: env)
|
72
|
+
)
|
73
|
+
]
|
74
|
+
end.to_h
|
75
|
+
)
|
76
|
+
end
|
77
|
+
|
78
|
+
def to_h
|
79
|
+
super.map do |k, v|
|
80
|
+
[
|
81
|
+
k,
|
82
|
+
case (v)
|
83
|
+
when Array
|
84
|
+
v.map do |e|
|
85
|
+
e.respond_to?(:to_h) ? e.to_h : e
|
86
|
+
end
|
87
|
+
else
|
88
|
+
v.respond_to?(:to_h) ? v.to_h : v
|
89
|
+
end
|
90
|
+
]
|
91
|
+
end.to_h
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
|
3
|
+
class Configature::Data < OpenStruct
|
4
|
+
# == Class Methods ========================================================
|
5
|
+
|
6
|
+
def self.hashify(data)
|
7
|
+
case (data)
|
8
|
+
when Configature::Data
|
9
|
+
data.to_h
|
10
|
+
when Array
|
11
|
+
data.map do |v|
|
12
|
+
hashify(v)
|
13
|
+
end
|
14
|
+
else
|
15
|
+
data
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# == Instance Methods =====================================================
|
20
|
+
|
21
|
+
def to_h
|
22
|
+
super.transform_values do |v|
|
23
|
+
self.class.hashify(v)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Configature::Directory
|
2
|
+
def self.parents(dir)
|
3
|
+
Enumerator.new do |y|
|
4
|
+
y << dir
|
5
|
+
|
6
|
+
loop do
|
7
|
+
last, dir = dir, File.expand_path('../', dir)
|
8
|
+
|
9
|
+
break if (last == dir)
|
10
|
+
|
11
|
+
y << dir
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.find(name)
|
17
|
+
parents(Dir.pwd).lazy.map do |dir|
|
18
|
+
File.expand_path(name, dir)
|
19
|
+
end.find do |dir|
|
20
|
+
File.directory?(dir)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,163 @@
|
|
1
|
+
require 'date'
|
2
|
+
|
3
|
+
require_relative './support'
|
4
|
+
|
5
|
+
class Configature::Namespace
|
6
|
+
# == Constants ============================================================
|
7
|
+
|
8
|
+
BOOLEAN_EQUIVALENT = begin
|
9
|
+
h = {
|
10
|
+
true => %w[ on yes 1 ],
|
11
|
+
false => %w[ off no 0 ]
|
12
|
+
}.flat_map do |k, a|
|
13
|
+
a.map do |v|
|
14
|
+
[ v, k ]
|
15
|
+
end
|
16
|
+
end.to_h
|
17
|
+
|
18
|
+
-> (v) do
|
19
|
+
b = h[v]
|
20
|
+
|
21
|
+
b.nil? ? !!v : b
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
RECAST_AS = {
|
26
|
+
[ :string, String ] => :to_s.to_proc,
|
27
|
+
[ :integer, Integer ] => :to_i.to_proc,
|
28
|
+
[ :float, Float ] => :to_f.to_proc,
|
29
|
+
[ :boolean ] => -> (v) { BOOLEAN_EQUIVALENT[v] },
|
30
|
+
[ :date, Date ] => -> (v) { Date.parse(v) },
|
31
|
+
[ :datetime, DateTime ] => -> (v) { DateTime.parse(v) },
|
32
|
+
[ :time, Time ] => -> (v) { v.match?(/\A\d+\z/) ? Time.at(v.to_i) : Time.parse(v) }
|
33
|
+
}.flat_map do |a, v|
|
34
|
+
a.map do |k|
|
35
|
+
[ k, v ]
|
36
|
+
end
|
37
|
+
end.to_h.freeze
|
38
|
+
|
39
|
+
# == Properties ===========================================================
|
40
|
+
|
41
|
+
attr_reader :name
|
42
|
+
attr_reader :env_name_prefix
|
43
|
+
attr_reader :namespaces
|
44
|
+
attr_reader :parameters
|
45
|
+
|
46
|
+
# == Class Methods ========================================================
|
47
|
+
|
48
|
+
# == Instance Methods =====================================================
|
49
|
+
|
50
|
+
def initialize(name = nil, env_name_prefix: '', env_suffix: '', extends: nil)
|
51
|
+
@name = name&.to_sym
|
52
|
+
@extends = extends
|
53
|
+
@env = extends&.instance_variable_get(:@env)
|
54
|
+
@env_default = extends&.instance_variable_get(:@env_default)
|
55
|
+
@namespaces = extends ? extends.namespaces.dup : { }
|
56
|
+
@parameters = extends ? extends.parameters.dup : { }
|
57
|
+
@env_suffix = env_suffix
|
58
|
+
@env_name_prefix = name ? Configature::Support.extend_env_prefix(env_name_prefix, name) : ''
|
59
|
+
|
60
|
+
yield(self) if (block_given?)
|
61
|
+
end
|
62
|
+
|
63
|
+
def namespace(name, env_suffix: '', extends: nil, &block)
|
64
|
+
name = name.to_sym
|
65
|
+
|
66
|
+
@namespaces[name] = self.class.new(name, env_suffix: env_suffix, extends: extends && self.namespaces[extends], env_name_prefix: @env_name_prefix).tap do |n|
|
67
|
+
case (block&.arity)
|
68
|
+
when nil
|
69
|
+
nil
|
70
|
+
when 1
|
71
|
+
block[n]
|
72
|
+
else
|
73
|
+
n.instance_eval(&block)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def env(*names, default: 'development')
|
79
|
+
@env = names.map(&:to_s).freeze
|
80
|
+
@env_default = default
|
81
|
+
end
|
82
|
+
|
83
|
+
def parameter(parameter_name, default: nil, as: :string, name: nil, env: nil, remap: nil)
|
84
|
+
name ||= parameter_name
|
85
|
+
|
86
|
+
case (as)
|
87
|
+
when Class, Symbol
|
88
|
+
as = RECAST_AS[as]
|
89
|
+
end
|
90
|
+
|
91
|
+
@parameters[name] = {
|
92
|
+
name: name,
|
93
|
+
default: default.is_a?(Proc) ? default : -> { default },
|
94
|
+
as: as,
|
95
|
+
remap: remap,
|
96
|
+
env:
|
97
|
+
case (env)
|
98
|
+
when false
|
99
|
+
false
|
100
|
+
when nil
|
101
|
+
Configature::Support.extend_env_prefix(@env_name_prefix, name)
|
102
|
+
else
|
103
|
+
env
|
104
|
+
end
|
105
|
+
}
|
106
|
+
end
|
107
|
+
|
108
|
+
def [](name)
|
109
|
+
@parameters[name] or @namespaces[name]
|
110
|
+
end
|
111
|
+
|
112
|
+
def method_missing(name, **options)
|
113
|
+
parameter(name, **options)
|
114
|
+
end
|
115
|
+
|
116
|
+
def __instantiate(source: nil, env: ENV)
|
117
|
+
if (@env and source)
|
118
|
+
env_key = @env.map { |e| env[e] }.first || @env_default
|
119
|
+
|
120
|
+
if (@env_suffix)
|
121
|
+
env_key += @env_suffix
|
122
|
+
end
|
123
|
+
|
124
|
+
source = source[env_key] || source[env_key.to_sym]
|
125
|
+
end
|
126
|
+
|
127
|
+
self.__instantiate_branch(source: source, env: env)
|
128
|
+
end
|
129
|
+
|
130
|
+
def __instantiate_branch(source: nil, env: nil)
|
131
|
+
Configature::Data.new(
|
132
|
+
@parameters.values.map do |param|
|
133
|
+
name = param[:name]
|
134
|
+
name_s = name.to_s
|
135
|
+
name_sym = name_s.to_sym
|
136
|
+
|
137
|
+
value = (param[:env] && env && env[param[:env]]) ||
|
138
|
+
source && (source[name_s] || source[name_sym])
|
139
|
+
|
140
|
+
case (remap = param[:remap])
|
141
|
+
when Hash, Proc
|
142
|
+
value = remap[value] || value
|
143
|
+
end
|
144
|
+
|
145
|
+
if (!value.nil? and as = param[:as])
|
146
|
+
value = as[value]
|
147
|
+
end
|
148
|
+
|
149
|
+
[ param[:name], value.nil? ? param[:default].call : value ]
|
150
|
+
end.to_h.merge(
|
151
|
+
@namespaces.map do |name, namespace|
|
152
|
+
[
|
153
|
+
name,
|
154
|
+
namespace.__instantiate_branch(
|
155
|
+
source: source && (source[name] || source[name.to_s]),
|
156
|
+
env: env
|
157
|
+
)
|
158
|
+
]
|
159
|
+
end.to_h
|
160
|
+
)
|
161
|
+
)
|
162
|
+
end
|
163
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
class Configature::Stamper
|
2
|
+
def initialize(dir)
|
3
|
+
@dir = dir
|
4
|
+
end
|
5
|
+
|
6
|
+
def examples
|
7
|
+
map = Dir.glob(File.expand_path('*.example', @dir)).map do |source|
|
8
|
+
[ source, source.delete_suffix('.example') ]
|
9
|
+
end.to_h
|
10
|
+
|
11
|
+
if (block_given?)
|
12
|
+
map.each do |k,v|
|
13
|
+
yield(k, v)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
map
|
18
|
+
end
|
19
|
+
|
20
|
+
def clean!
|
21
|
+
self.examples.each do |_source, target|
|
22
|
+
if (File.exist?(target))
|
23
|
+
File.unlink(target)
|
24
|
+
|
25
|
+
yield(target) if (block_given?)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def apply!(force: false)
|
31
|
+
self.examples.each do |source, target|
|
32
|
+
if (!force and File.exist?(target))
|
33
|
+
yield(
|
34
|
+
source,
|
35
|
+
target,
|
36
|
+
created: false,
|
37
|
+
existing: true,
|
38
|
+
config_required: !!File.read(target).match(/__[A-Z\-\_]+__/)
|
39
|
+
) if (block_given?)
|
40
|
+
else
|
41
|
+
FileUtils.copy(source, target)
|
42
|
+
|
43
|
+
yield(
|
44
|
+
source,
|
45
|
+
target,
|
46
|
+
created: true,
|
47
|
+
existing: false,
|
48
|
+
config_required: !!File.read(target).match(/__[A-Z\-\_]+__/)
|
49
|
+
) if (block_given?)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module Configature::Support
|
4
|
+
# == Module and Mixin Methods =============================================
|
5
|
+
|
6
|
+
def yaml_if_exist(path)
|
7
|
+
return unless (File.exist?(path))
|
8
|
+
|
9
|
+
# FIX: Use safe_load if safe_load supports aliases
|
10
|
+
File.open(path) do |f|
|
11
|
+
YAML.load(f)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def extend_env_prefix(base, with)
|
16
|
+
return base unless (base)
|
17
|
+
return with unless (with)
|
18
|
+
|
19
|
+
case (base)
|
20
|
+
when ''
|
21
|
+
with.to_s.upcase
|
22
|
+
else
|
23
|
+
base.upcase + '_' + with.to_s.upcase
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def convert_hashes(to_class, obj)
|
28
|
+
case (obj)
|
29
|
+
when Hash, OpenStruct, Configature::Data
|
30
|
+
to_class.new(
|
31
|
+
obj.to_h.map do |k, v|
|
32
|
+
[ k, convert_hashes(to_class, v) ]
|
33
|
+
end.to_h
|
34
|
+
)
|
35
|
+
when Array
|
36
|
+
obj.map do |v|
|
37
|
+
convert_hashes(to_class, v)
|
38
|
+
end
|
39
|
+
else
|
40
|
+
obj
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
extend self
|
45
|
+
end
|
metadata
CHANGED
@@ -1,57 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: configature
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Scott Tadman
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
12
|
-
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: bundler
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - ">="
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '0'
|
20
|
-
type: :development
|
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: rake
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ">="
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
34
|
-
type: :development
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - ">="
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '0'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: rspec
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - ">="
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '0'
|
48
|
-
type: :development
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - ">="
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '0'
|
11
|
+
date: 2020-04-21 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
55
13
|
description: Assists in the creation of config files from example templates and can
|
56
14
|
identify when some customization is necessary.
|
57
15
|
email:
|
@@ -76,6 +34,12 @@ files:
|
|
76
34
|
- configature.gemspec
|
77
35
|
- exe/config
|
78
36
|
- lib/configature.rb
|
37
|
+
- lib/configature/config.rb
|
38
|
+
- lib/configature/data.rb
|
39
|
+
- lib/configature/directory.rb
|
40
|
+
- lib/configature/namespace.rb
|
41
|
+
- lib/configature/stamper.rb
|
42
|
+
- lib/configature/support.rb
|
79
43
|
homepage: https://postageapp.com/
|
80
44
|
licenses:
|
81
45
|
- MIT
|
@@ -99,7 +63,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
99
63
|
- !ruby/object:Gem::Version
|
100
64
|
version: '0'
|
101
65
|
requirements: []
|
102
|
-
rubygems_version: 3.
|
66
|
+
rubygems_version: 3.1.2
|
103
67
|
signing_key:
|
104
68
|
specification_version: 4
|
105
69
|
summary: Configuration file auto-generator
|