Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue#1243 configurations with unimplemented environments #1244

Conversation

JonMidhir
Copy link
Contributor

Fixes unpredictable behaviour from Sinatra::ConfigFile detailed in #1243.

  • Loads settings for the current environment regardless of other environments defined in the configuration file. Previously settings failed for all environments unless all in the file were implemented in the application.

  • Removes the restriction that settings can only be inherited from other environments, so that this is possible:

default: &default
  foo: bar

development:
  <<: *default

production:
  <<: *default
  foo: baz

test:
  <<: *default
  • Amends source documentation to represent new behaviour.

  • Includes tests for the new behaviour.

  • Backwards compatible with existing settings implementations.

@zzak zzak added the feedback label Jan 30, 2017
@JonMidhir JonMidhir force-pushed the issue#1243-configurations_with_unimplemented_environments branch from 9999791 to 8894a8f Compare March 7, 2017 10:29
if hash.respond_to? :keys and hash.keys.all? { |k| environments.include? k.to_s }
hash = hash[environment.to_s] || hash[environment.to_sym]
end
# Given a +hash+ with some application configuration, returns the settings
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This word, +hash+ refers to the new-renamed parameter (now called config), so the API docs generation will miss this annotation.

end
end

# Returns true if supplied with a hash that has any recognized
# +environments+ in it's root keys.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Grammar: it's => its

@JonMidhir JonMidhir force-pushed the issue#1243-configurations_with_unimplemented_environments branch from 8894a8f to 3ba8697 Compare October 31, 2017 19:40
@JonMidhir
Copy link
Contributor Author

Issues by @olleolleolle fixed & branch rebased.

@olleolleolle
Copy link
Member

@zzak Is this ready for re-review? I believe so.


# Returns a hash that can be accessed by both strings and symbols, when
# supplied with a hash with string keys.
def with_indifferent_access(hash)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need Yet Another Indifferent Hash implementation? Can't we use the one in core?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this PR precedes the work to build out a full IndifferentHash implementation. I can definitely look at switching to that today.

@JonMidhir JonMidhir force-pushed the issue#1243-configurations_with_unimplemented_environments branch from cf36257 to d670cea Compare November 6, 2017 23:27
@JonMidhir
Copy link
Contributor Author

@zzak think this is ready for review. Refactored a good bit and it uses IndifferentHash from core.

@olleolleolle
Copy link
Member

olleolleolle commented Nov 7, 2017

@JonMidhir Could you be using YAML.safe_load(your_thing)? (This is me asking, not telling.)

That becomes a SafeYAML.load(your_thing) and constrains to the types allowed by the schemas. (That is, white-listed according to a pre-defined list of data-types.)

@JonMidhir
Copy link
Contributor Author

@olleolleolle I'd prefer .safe_load too but it seems to ignore aliased environments then. There may be a way to use it though, let me have a look.

@JonMidhir
Copy link
Contributor Author

JonMidhir commented Nov 8, 2017

OK If we use YAML.safe_load we can allow aliases but we're going to limit the number of types that can be deserialized.

That's bound to break some existing configurations for users. ERB templates that produce Dates, for example, will be cast to Strings unpredictably or error out with Psych::DisallowedClass.

I'm inclined to leave it as-is for now. What do you think @olleolleolle?

@zzak
Copy link
Member

zzak commented Nov 8, 2017

Re: safe_load, I think it's fine to leave it. It would be a potentially big behavior change and supposing that people know the contents of the config files they are loading.

@namusyaka namusyaka added this to the v2.0.2 milestone Feb 19, 2018
@JonMidhir
Copy link
Contributor Author

Looks like this is due to be merged soon. Need it rebased?

Copy link
Member

@namusyaka namusyaka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the late reply. As you said, this should be rebased. And then, I pointed a problem about this change, please take a look at it?

end
yaml = YAML.load(document)
config = config_for_env(yaml)
config.each_pair { |key, value| set(key, value) }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You shouldn't remove the conditional expressions because the following unintentional behavior will happen.

# config.yml
development:
  raise_errors: "foo"
require 'sinatra'
require 'sinatra/config_file'

config_file './config.yml'

get '/' do
  settings.raise_errors.to_s #=> expected "false", but got "foo"
end

I think that it isn't desirable to automatically overwrite settings defined by default by config file settings.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@namusyaka Running this against both master and this branch I notice the default setting being overwritten. I don't think the original conditional defends against this behaviour. I can't actually think of a condition where the original would be met at all.

However, I can add this behaviour if you'd prefer?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, makes sense.
It seems that the sample I showed was wrong.
However, we must grasp the condition that the original conditional expression was trying to protect.

Welcome if you can look it up.
Then, if the original conditional expression is meaningful, we have to add a test on that matter.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have the case where this would fail. If the value is being set to nil and it's set using this style, the conditional will be met and setting ignored:

# config.yml
raise_errors:
  development: 

# app.rb
settings.raise_errors #=> expected nil, got false

However in both other styles the conditional is not met, and the default value is overwritten:

# config.yml
raise_errors:

# app.rb
settings.raise_errors #=> expected nil, got nil



# config.yml
development:
  raise_errors:

# app.rb
settings.raise_errors #=> expected nil, got nil

If we're changing the behaviour anyway do we really want to stop people from overriding default values using the config file? It seems reasonable that it should be possible to do so.

If not we can exclude all cases or have it function exactly as it did before.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's no problem, I think.
I've reviewed this change to a certain extent, but I judged that it is almost no problem.

@JonMidhir
Copy link
Contributor Author

Sure thing, I can see the missing conditional. I'll fix it tonight.

@JonMidhir JonMidhir force-pushed the issue#1243-configurations_with_unimplemented_environments branch from d670cea to 9426aa0 Compare March 8, 2018 11:40
Copy link
Member

@namusyaka namusyaka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for clarification. lgtm.
Please squash commits.

end
yaml = YAML.load(document)
config = config_for_env(yaml)
config.each_pair { |key, value| set(key, value) }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's no problem, I think.
I've reviewed this change to a certain extent, but I judged that it is almost no problem.

@JonMidhir JonMidhir force-pushed the issue#1243-configurations_with_unimplemented_environments branch from 9426aa0 to 5043030 Compare March 20, 2018 09:48
@JonMidhir JonMidhir force-pushed the issue#1243-configurations_with_unimplemented_environments branch from 5043030 to dac5160 Compare March 20, 2018 09:53
@JonMidhir
Copy link
Contributor Author

Done 👍

@namusyaka namusyaka merged commit 44660b9 into sinatra:master Mar 22, 2018
@namusyaka
Copy link
Member

@JonMidhir Thank you

netbsd-srcmastr pushed a commit to NetBSD/pkgsrc that referenced this pull request Sep 23, 2018
## 2.0.4 / 2018-09-15

* Don't blow up when passing frozen string to `send_file` disposition [#1137](sinatra/sinatra#1137) by Andrew Selder

* Fix ubygems LoadError [#1436](sinatra/sinatra#1436) by Pavel Rosick�«ò

* Unescape regex captures [#1446](sinatra/sinatra#1446) by Jordan Owens

* Slight performance improvements for IndifferentHash [#1427](sinatra/sinatra#1427) by Mike Pastore

* Improve development support and documentation and source code by Will Yang, Jake Craige, Grey Baker and Guilherme Goettems Schneider

## 2.0.3 / 2018-06-09

* Fix the backports gem regression [#1442](sinatra/sinatra#1442) by Marc-Andr�«± Lafortune

## 2.0.2 / 2018-06-05

* Escape invalid query parameters [#1432](sinatra/sinatra#1432) by Kunpei Sakai
  * The patch fixes [CVE-2018-11627](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-11627).

* Fix undefined method error for `Sinatra::RequiredParams` with hash key [#1431](sinatra/sinatra#1431) by Arpit Chauhan

* Add xml content-types to valid html_types for Rack::Protection [#1413](sinatra/sinatra#1413) by Reenan Arbitrario

* Encode route parameters using :default_encoding setting [#1412](sinatra/sinatra#1412) by Brian m. Carlson

* Fix unpredictable behaviour from Sinatra::ConfigFile [#1244](sinatra/sinatra#1244) by John Hope

* Add Sinatra::IndifferentHash#slice [#1405](sinatra/sinatra#1405) by Shota Iguchi

* Remove status code 205 from drop body response [#1398](sinatra/sinatra#1398) by Shota Iguchi

* Ignore empty captures from params [#1390](sinatra/sinatra#1390) by Shota Iguchi

* Improve development support and documentation and source code by Zp Yuan, Andreas Finger, Olle Jonsson, Shota Iguchi, Nikita Bulai and Joshua O'Brien
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants