dry-web 0.6.0 → 0.7.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
  SHA1:
3
- metadata.gz: ebcf4adb58017f9e639efb394e9beffed9569647
4
- data.tar.gz: 04635ad8ebd204c99a9b07cd058c5153d72ac688
3
+ metadata.gz: 97793e4957eae5c7a9ef6d23940ea36b3a6c0b39
4
+ data.tar.gz: f44ea39a81319979561bbf1b36dcc954bd61aa77
5
5
  SHA512:
6
- metadata.gz: b66229021044639a2abe4d42d4f4728deed718cd774324f1b551a8ebd6ef1c533f5bd4a7720753ada38c135ade1a47aaf9fcb4814cd8a6a621d2fa8d764b31bb
7
- data.tar.gz: 2095506487f2aafa110dc75eba1dd202fd8a6ab9fadefafc5885e628dba7fb4aab8d80a3339d3080f22530d18b958d773005a5d1401d54b05f6a40857eda7149
6
+ metadata.gz: a73e673298f094cc8c6947eb328f5b6c0a86f06ff2cc73d341ce98493adde571b3fd282cfce152b6724c6cb652acce7e632a831f0ccea3a09dad816db06cbd38
7
+ data.tar.gz: 6d1b9d93e7bae26a96b043b92cc5b896876c6d250b0cf35b981e9aec945ca8d8b5bd142954705a017d63da7f8c5e71170ddecf4f2a08b95c05d6974db3b9ec91
@@ -8,11 +8,11 @@ script:
8
8
  after_script:
9
9
  - bundle exec codeclimate-test-reporter
10
10
  rvm:
11
- - 2.1
11
+ - 2.4.0
12
+ - 2.3
12
13
  - 2.2
13
- - 2.3.0
14
14
  - rbx-3
15
- - jruby-9000
15
+ - jruby-9.1.6.0
16
16
  env:
17
17
  global:
18
18
  - JRUBY_OPTS='--dev -J-Xmx1024M'
@@ -1,3 +1,10 @@
1
+ # 0.7.0 - 2017-06-16
2
+
3
+ ### Changed
4
+
5
+ - [BREAKING] `Dry::Web::Settings` now loads settings from local `.env` and `.env.<environment>` files (GustavoCaso)
6
+ - [BREAKING] Removed `Dry::Web::Umbrella` with special handling of settings. Settings should for now be provided as a bootable component within your applications (dry-web-roda will be updated to generate such) (timriley)
7
+
1
8
  # 0.6.0 - 2017-02-02
2
9
 
3
10
  ### Added
@@ -0,0 +1,29 @@
1
+ # Issue Guidelines
2
+
3
+ ## Reporting bugs
4
+
5
+ If you found a bug, report an issue and describe what's the expected behavior versus what actually happens. If the bug causes a crash, attach a full backtrace. If possible, a reproduction script showing the problem is highly appreciated.
6
+
7
+ ## Reporting feature requests
8
+
9
+ Report a feature request **only after discussing it first on [discuss.dry-rb.org](https://discuss.dry-rb.org)** where it was accepted. Please provide a concise description of the feature, don't link to a discussion thread, and instead summarize what was discussed.
10
+
11
+ ## Reporting questions, support requests, ideas, concerns etc.
12
+
13
+ **PLEASE DON'T** - use [discuss.dry-rb.org](http://discuss.dry-rb.org) instead.
14
+
15
+ # Pull Request Guidelines
16
+
17
+ A Pull Request will only be accepted if it addresses a specific issue that was reported previously, or fixes typos, mistakes in documentation etc.
18
+
19
+ Other requirements:
20
+
21
+ 1) Do not open a pull request if you can't provide tests along with it. If you have problems writing tests, ask for help in the related issue.
22
+ 2) Follow the style conventions of the surrounding code. In most cases, this is standard ruby style.
23
+ 3) Add API documentation if it's a new feature
24
+ 4) Update API documentation if it changes an existing feature
25
+ 5) Bonus points for sending a PR to [github.com/dry-rb/dry-rb.org](github.com/dry-rb/dry-rb.org) which updates user documentation and guides
26
+
27
+ # Asking for help
28
+
29
+ If these guidelines aren't helpful, and you're stuck, please post a message on [discuss.dry-rb.org](https://discuss.dry-rb.org).
@@ -1,4 +1,4 @@
1
- require "yaml"
1
+ require "dry/web/settings/file_loader"
2
2
 
3
3
  module Dry
4
4
  module Web
@@ -27,16 +27,20 @@ module Dry
27
27
  end
28
28
  private_class_method :check_schema_duplication
29
29
 
30
+ def self.load_files(root, env)
31
+ FileLoader.new.(root, env)
32
+ end
33
+ private_class_method :load_files
34
+
30
35
  def self.load(root, env)
31
- yaml_path = root.join("config/settings.yml")
32
- yaml_data = File.exist?(yaml_path) ? YAML.load_file(yaml_path)[env.to_s] : {}
36
+ env_data = load_files(root, env)
33
37
  schema = self.schema
34
38
 
35
39
  Class.new do
36
40
  extend Dry::Configurable
37
41
 
38
42
  schema.each do |key, type|
39
- value = ENV.fetch(key.to_s.upcase) { yaml_data[key.to_s.downcase] }
43
+ value = ENV.fetch(key.to_s.upcase) { env_data[key.to_s.upcase] }
40
44
 
41
45
  begin
42
46
  value = type[value] if type
@@ -0,0 +1,28 @@
1
+ require "dry/web/settings/file_parser"
2
+
3
+ module Dry
4
+ module Web
5
+ class Settings
6
+ class FileLoader
7
+ def call(root, env)
8
+ files(root, env).reduce({}) do |hash, file|
9
+ hash.merge(parser.(file))
10
+ end
11
+ end
12
+
13
+ private
14
+
15
+ def parser
16
+ @parser ||= FileParser.new
17
+ end
18
+
19
+ def files(root, env)
20
+ [
21
+ root.join(".env"),
22
+ root.join(".env.#{env}")
23
+ ].compact
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,49 @@
1
+ module Dry
2
+ module Web
3
+ class Settings
4
+ class FileParser
5
+ # Regex extracted from dotenv gem
6
+ # https://github.com/bkeepers/dotenv/blob/master/lib/dotenv/parser.rb#L14
7
+ LINE = %r(
8
+ \A
9
+ \s*
10
+ (?:export\s+)? # optional export
11
+ ([\w\.]+) # key
12
+ (?:\s*=\s*|:\s+?) # separator
13
+ ( # optional value begin
14
+ '(?:\'|[^'])*' # single quoted value
15
+ | # or
16
+ "(?:\"|[^"])*" # double quoted value
17
+ | # or
18
+ [^#\n]+ # unquoted value
19
+ )? # value end
20
+ \s*
21
+ (?:\#.*)? # optional comment
22
+ \z
23
+ )x
24
+
25
+ def call(file)
26
+ File.readlines(file).each_with_object({}) do |line, hash|
27
+ parse_line(line, hash)
28
+ end
29
+ rescue Errno::ENOENT
30
+ {}
31
+ end
32
+
33
+ private
34
+
35
+ def parse_line(line, hash)
36
+ if (match = line.match(LINE))
37
+ key, value = match.captures
38
+ hash[key] = parse_value(value || "")
39
+ end
40
+ hash
41
+ end
42
+
43
+ def parse_value(value)
44
+ value.strip.sub(/\A(['"])(.*)\1\z/, '\2')
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -1,5 +1,5 @@
1
1
  module Dry
2
2
  module Web
3
- VERSION = '0.6.0'.freeze
3
+ VERSION = '0.7.0'.freeze
4
4
  end
5
5
  end
@@ -0,0 +1,2 @@
1
+ IN_BOTH_ENVIRONMENT='.env'
2
+ ONLY_ON_ENV='will be loaded from env'
@@ -0,0 +1,2 @@
1
+ IN_BOTH_ENVIRONMENT='.env.test'
2
+ ONLY_IN_TEST='will be loaded from env.test'
@@ -0,0 +1,5 @@
1
+ API_KEY='yaml123'
2
+ IN_BOTH_ENVIRONMENT='.env.test'
3
+ PRECOMPILE_ASSETS="1"
4
+ UNDECLARED=not declared in settings
5
+ TESTING='variables with = in it'
@@ -0,0 +1,16 @@
1
+ require "dry/web/settings/file_loader"
2
+
3
+ RSpec.describe Dry::Web::Settings::FileLoader do
4
+ let(:klass) { Dry::Web::Settings::FileLoader }
5
+ let(:root) { SPEC_ROOT.join("fixtures/multiple_env_files") }
6
+ let(:env) { :test }
7
+ subject(:data) { klass.new.(root, env) }
8
+
9
+ describe "#call" do
10
+ it "will create hash with both variables from files" do
11
+ expect(subject["ONLY_ON_ENV"]).to eq ("will be loaded from env")
12
+ expect(subject["ONLY_IN_TEST"]).to eq ("will be loaded from env.test")
13
+ expect(subject["IN_BOTH_ENVIRONMENT"]).to eq (".env.test")
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,29 @@
1
+ require "dry/web/settings/file_parser"
2
+
3
+ RSpec.describe Dry::Web::Settings::FileParser do
4
+ let(:klass) { Dry::Web::Settings::FileParser }
5
+ let(:parser) { klass.new }
6
+
7
+ describe "#call" do
8
+ context "with existing file" do
9
+ let(:file) { SPEC_ROOT.join("fixtures/test/.env.test") }
10
+ subject(:settings) { parser.(file) }
11
+
12
+ it "will retrun a hash with all variables and its value" do
13
+ expect(subject["API_KEY"]).to eq ("yaml123")
14
+ expect(subject["PRECOMPILE_ASSETS"]).to eq ("1")
15
+ expect(subject["UNDECLARED"]).to eq ("not declared in settings")
16
+ expect(subject["TESTING"]).to eq ("variables with = in it")
17
+ end
18
+ end
19
+
20
+ context "without existing file" do
21
+ let(:file) { SPEC_ROOT.join("fixtures/test/.env") }
22
+ subject(:settings) { parser.(file) }
23
+
24
+ it "will retrun a empty hash" do
25
+ expect(subject).to eq ({})
26
+ end
27
+ end
28
+ end
29
+ end
@@ -26,14 +26,39 @@ RSpec.describe Dry::Web::Settings do
26
26
  expect(settings.env_only_setting).to eq "hello"
27
27
  end
28
28
 
29
- it "loads settings from a YAML file (as lower-cased keys) if unavailable from ENV" do
29
+ it "loads settings from a env file (as upper-cased keys) if unavailable from ENV" do
30
30
  expect(settings.api_key).to eq "yaml123"
31
31
  end
32
32
 
33
- it "ignores undeclared settings in the YAML file" do
33
+ it "ignores undeclared settings in the env file" do
34
34
  expect(settings).not_to respond_to(:undeclared)
35
35
  end
36
36
 
37
+ context "without file" do
38
+ subject(:settings) {
39
+ Class.new(Dry::Web::Settings) do
40
+ setting :api_key
41
+ setting :precompile_assets
42
+ end.load(SPEC_ROOT.join("fixtures/test"), :development)
43
+ }
44
+
45
+ it "will retrun an config hash " do
46
+ expect(settings.to_h).to eq ({api_key: nil, precompile_assets: nil})
47
+ end
48
+ end
49
+
50
+ context "specific env file will merge on top of `.env`" do
51
+ subject(:settings) {
52
+ Class.new(Dry::Web::Settings) do
53
+ setting :in_both_environment
54
+ end.load(SPEC_ROOT.join("fixtures/multiple_env_files"), :test)
55
+ }
56
+
57
+ it "will retrun the value set from the test env " do
58
+ expect(settings.in_both_environment).to eq ".env.test"
59
+ end
60
+ end
61
+
37
62
  context "settings with types" do
38
63
  before do
39
64
  Test::CoercingBool = Class.new do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dry-web
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Piotr Solnica
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-02-02 00:00:00.000000000 Z
11
+ date: 2017-06-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dry-system
@@ -105,6 +105,7 @@ files:
105
105
  - ".rspec"
106
106
  - ".travis.yml"
107
107
  - CHANGELOG.md
108
+ - CONTRIBUTING.md
108
109
  - Gemfile
109
110
  - LICENSE
110
111
  - README.md
@@ -114,15 +115,19 @@ files:
114
115
  - lib/dry/web/console.rb
115
116
  - lib/dry/web/container.rb
116
117
  - lib/dry/web/settings.rb
117
- - lib/dry/web/umbrella.rb
118
+ - lib/dry/web/settings/file_loader.rb
119
+ - lib/dry/web/settings/file_parser.rb
118
120
  - lib/dry/web/version.rb
119
121
  - log/.gitkeep
120
- - spec/fixtures/test/config/settings.yml
122
+ - spec/fixtures/multiple_env_files/.env
123
+ - spec/fixtures/multiple_env_files/.env.test
124
+ - spec/fixtures/test/.env.test
121
125
  - spec/fixtures/test/log/.gitkeep
122
126
  - spec/spec_helper.rb
123
127
  - spec/unit/container_spec.rb
128
+ - spec/unit/settings/file_loader_spec.rb
129
+ - spec/unit/settings/file_parser_spec.rb
124
130
  - spec/unit/settings_spec.rb
125
- - spec/unit/umbrella_spec.rb
126
131
  homepage: https://github.com/dry-rb/dry-web
127
132
  licenses:
128
133
  - MIT
@@ -143,14 +148,17 @@ required_rubygems_version: !ruby/object:Gem::Requirement
143
148
  version: '0'
144
149
  requirements: []
145
150
  rubyforge_project:
146
- rubygems_version: 2.6.9
151
+ rubygems_version: 2.6.11
147
152
  signing_key:
148
153
  specification_version: 4
149
154
  summary: Lightweight web application stack on top of dry-system
150
155
  test_files:
151
- - spec/fixtures/test/config/settings.yml
156
+ - spec/fixtures/multiple_env_files/.env
157
+ - spec/fixtures/multiple_env_files/.env.test
158
+ - spec/fixtures/test/.env.test
152
159
  - spec/fixtures/test/log/.gitkeep
153
160
  - spec/spec_helper.rb
154
161
  - spec/unit/container_spec.rb
162
+ - spec/unit/settings/file_loader_spec.rb
163
+ - spec/unit/settings/file_parser_spec.rb
155
164
  - spec/unit/settings_spec.rb
156
- - spec/unit/umbrella_spec.rb
@@ -1,33 +0,0 @@
1
- require "dry/web/container"
2
-
3
- module Dry
4
- module Web
5
- class Umbrella < Dry::Web::Container
6
- setting :settings_loader
7
- setting :settings
8
-
9
- def self.configure(env = config.env, &block)
10
- super() do |config|
11
- yield(config) if block
12
-
13
- if config.settings_loader && config.settings.nil?
14
- config.settings = load_settings(config.settings_loader, root, env)
15
- end
16
- end
17
-
18
- self
19
- end
20
-
21
- def self.load_settings(loader, root, env)
22
- begin
23
- loader.load(root, env)
24
- rescue => e
25
- puts "Could not load your settings: #{e}"
26
- puts
27
- raise e
28
- end
29
- end
30
- private_class_method :load_settings
31
- end
32
- end
33
- end
@@ -1,4 +0,0 @@
1
- test:
2
- api_key: "yaml123"
3
- precompile_assets: "1"
4
- undeclared: "not declared in settings"
@@ -1,56 +0,0 @@
1
- require "dry/web/settings"
2
- require "dry/web/umbrella"
3
-
4
- RSpec.describe Dry::Web::Umbrella do
5
- subject(:umbrella) {
6
- Class.new(Dry::Web::Umbrella) do
7
- configure do |config|
8
- config.root = SPEC_ROOT.join("fixtures/test")
9
- end
10
- end
11
- }
12
-
13
- describe "config" do
14
- describe "#settings" do
15
- subject(:settings) { umbrella.config.settings }
16
-
17
- context "no settings specified" do
18
- it "is an empty object" do
19
- expect(:settings).not_to be_nil
20
- end
21
-
22
- it "does not offer any settings" do
23
- expect(:settings).not_to respond_to(:some_setting)
24
- end
25
- end
26
-
27
- context "settings loader specified" do
28
- let(:settings_loader) { class_double("Dry::Web::Settings") }
29
-
30
- it "loads the settings using the specified settings_loader" do
31
- allow(settings_loader).to receive(:load).with(umbrella.config.root, :test) {
32
- double("settings", foo: "bar")
33
- }
34
-
35
- umbrella.configure do |config|
36
- config.settings_loader = settings_loader
37
- end
38
-
39
- expect(settings.foo).to eq "bar"
40
- end
41
- end
42
-
43
- context "settings object specified" do
44
- before do
45
- umbrella.configure do |config|
46
- config.settings = double("custom settings", bar: "baz")
47
- end
48
- end
49
-
50
- it "leaves the settings object in place" do
51
- expect(settings.bar).to eq "baz"
52
- end
53
- end
54
- end
55
- end
56
- end