Code Monkey home page Code Monkey logo

configatron's People

Contributors

bdimcheff avatar bkrausz avatar chikamichi avatar cmaggard avatar gdb avatar jlecour avatar joemiller avatar josetonyp avatar juanibiapina avatar kron4eg avatar markbates avatar mattelacchiato avatar rfletcher avatar rosenfeld avatar rsanheim avatar shishi avatar sqbell avatar technicalpickles avatar timriley avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

configatron's Issues

Doesn't work

In model, in view files, it renders empty hash, but in rails console works fine

Should configatron.temp ensure that temp_end is called?

If I write an RSpec example like this:

configatron.temp do
  configatron.foo = "someval"
  expect(something).to be_falsy
end

and the expectation fails, the temp setting "leaks" and can cause other examples to fail unexpectedly. This can be handled by setting configatron.foo to a known value in a before(:example) block, but I wonder if temp should work more like the following:

begin
  configatron.temp_start
  configatron.foo = "someval"
  expect(something).to be_falsy
ensure
  configatron.temp_end
end

configure_from_yaml / hash seems broken

In a new Rails 3 project

>> configatron.configure_from_yaml("#{Rails.root}/config/s3.yml")


NoMethodError: You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.flatten
    from /Users/benjaminmoss/.rvm/gems/ruby-1.9.2-p180@rails31/gems/configatron-2.8.1/lib/configatron/store.rb:306:in `block in parse_options'
    from /Users/benjaminmoss/.rvm/gems/ruby-1.9.2-p180@rails31/gems/configatron-2.8.1/lib/configatron/store.rb:303:in `each'
    from /Users/benjaminmoss/.rvm/gems/ruby-1.9.2-p180@rails31/gems/configatron-2.8.1/lib/configatron/store.rb:303:in `parse_options'
    from /Users/benjaminmoss/.rvm/gems/ruby-1.9.2-p180@rails31/gems/configatron-2.8.1/lib/configatron/store.rb:94:in `configure_from_hash'
    from /Users/benjaminmoss/.rvm/gems/ruby-1.9.2-p180@rails31/gems/configatron-2.8.1/lib/configatron/store.rb:105:in `configure_from_yaml'
    from /Users/benjaminmoss/.rvm/gems/ruby-1.9.2-p180@rails31/gems/configatron-2.8.1/lib/configatron/configatron.rb:15:in `method_missing'
    from (irb):35
    from /Users/benjaminmoss/.rvm/gems/ruby-1.9.2-p180@rails31/gems/railties-3.1.0.rc4/lib/rails/commands/console.rb:45:in `start'
    from /Users/benjaminmoss/.rvm/gems/ruby-1.9.2-p180@rails31/gems/railties-3.1.0.rc4/lib/rails/commands/console.rb:8:in `start'
    from /Users/benjaminmoss/.rvm/gems/ruby-1.9.2-p180@rails31/gems/railties-3.1.0.rc4/lib/rails/commands.rb:40:in `<top (required)>'
    from script/rails:6:in `require'
    from script/rails:6:in `<main>'

The yml:

default: &default
  access_key_id: access_key
  secret_access_key: secret_access_key

development:
  bucket: develop
  <<: *default

production:
  bucket: production
  <<: *default

test: &test

Possible bug in store.retrieve

Hey, I was just trying to use the retrieve method and ran into a potential issue.

It first does method_missing to get a value and then checks if it is a store, if so it returns the default.

Is that intended?

For instance, I have nested fields, and some of them are supposed to be stores, and instead of getting the value, I get nil because I did not specify a default.

Should it be:

return (val.is_a?(Configatron::Store) && val.nil?) ? default_value : val

or

vreturn val.nil? ? default_value : val

instead of

return val.is_a?(Configatron::Store) ? default_value : val

Maybe I am misunderstanding the usage of that method. I worked around it by calling method_missing myself and checking for nil.

Thanks for a great library!

uninitialized constant YAML::Syck with jruby (1.6.x) and configatron 2.8

Why I can't use configatron with jruby?

trace:

$ rails s
NameError: uninitialized constant YAML::Syck
const_missing at org/jruby/RubyModule.java:2569
Store at /home/mschiller/.rvm/gems/jruby-1.6.2/gems/configatron-2.8.0/lib/configatron/store.rb:324
Configatron at /home/mschiller/.rvm/gems/jruby-1.6.2/gems/configatron-2.8.0/lib/configatron/store.rb:2
(root) at /home/mschiller/.rvm/gems/jruby-1.6.2/gems/configatron-2.8.0/lib/configatron/store.rb:1
require at org/jruby/RubyKernel.java:1038
(root) at /home/mschiller/.rvm/gems/jruby-1.6.2/gems/configatron-2.8.0/lib/configatron/store.rb:5
require at org/jruby/RubyKernel.java:1038
(root) at /home/mschiller/.rvm/gems/jruby-1.6.2/gems/configatron-2.8.0/lib/configatron.rb:2
require at org/jruby/RubyKernel.java:1038
send at org/jruby/RubyKernel.java:2063
require_all at /home/mschiller/Entwicklung/Projects/framework/lib/system/config_loader.rb:75
require_rel at /home/mschiller/.rvm/gems/jruby-1.6.2/gems/require_all-1.2.0/lib/require_all.rb:154
each at org/jruby/RubyArray.java:1602
require_rel at /home/mschiller/.rvm/gems/jruby-1.6.2/gems/require_all-1.2.0/lib/require_all.rb:153
(root) at /home/mschiller/Entwicklung/Projects/framework/config/application.rb:7
require at org/jruby/RubyKernel.java:1038
(root) at /home/mschiller/Entwicklung/Projects/framework/config/application.rb:52
tap at org/jruby/RubyKernel.java:1770
(root) at /home/mschiller/.rvm/gems/jruby-1.6.2/gems/railties-3.1.0.rc1/lib/rails/commands.rb:49
require at org/jruby/RubyKernel.java:1038
(root) at script/rails:6

has_key give an error if the value is set.

if I have a value set for a
configatron.init do |init|
init.defaults.configure_from_hash (config: {file: './config.yml'})
end
configatron.init.defaults.config.file.has_key?(:exist)

When the value exists gives an error
block in initialize': undefined method has_key?' for "./config.yml":String (NoMethodError) from gems/ruby-2.3.1/gems/configatron-4.5.1/lib/configatron/store.rb:151:in do_lookup'
from gems/ruby-2.3.1/gems/configatron-4.5.1/lib/configatron/store.rb:126:in method_missing' from gems/ruby-2.3.1/gems/configatron-4.5.1/lib/configatron/root_store.rb:54:in method_missing'

configatron leaks syck into other projects

When using cover_me on a rails 3.2, mongoid 3.0.10 project on ruby 1.9.3 we ran into random spec failures.

We eventually traced the failures back to configatron forcing the use of syck for ruby 1.9.3 with the following in store.rb:

class Configatron
  class Store
    if RUBY_VERSION.match(/^1\.9\.[^1]/)
      require 'syck'
      ::YAML::ENGINE.yamler = 'syck' unless RUBY_PLATFORM == 'java'
    end

If configatron needs to use syck as its yamler, it should do so only within the context of configatron and not leak that choice into other projects.

configatron breaks JRuby's YAML parser

I don't know if this is a JRuby (1.6.0) problem or a configatron (2.7.2) problem, but it's definitely a problem when the two of them get together:

$ cat test.yml
config:
  x: 1
  y: 2

$ irb
jruby-1.6.0 :001 > require 'yaml'
 => true 
jruby-1.6.0 :002 > yml = YAML.load_file 'test.yml'           
 => {"config"=>{"x"=>1, "y"=>2}} 
jruby-1.6.0 :003 > require 'configatron'                     
 => true 
jruby-1.6.0 :004 > yml = YAML.load_file 'test.yml'
Java::JavaLang::NullPointerException: 
    from org.yecht.ruby.RubyLoadHandler.handle(RubyLoadHandler.java:38)
    from org.yecht.Parser.addNode(Parser.java:300)
    from org.yecht.DefaultYAMLParser.yyparse(DefaultYAMLParser.java:676)
    from org.yecht.Parser.yechtparse(Parser.java:290)
    from org.yecht.Parser.parse(Parser.java:284)
    from org.yecht.ruby.YParser.load(YParser.java:152)
    from org.yecht.ruby.YParser$s$0$1$load.call(YParser$s$0$1$load.gen:65535)
    from org.jruby.internal.runtime.methods.JavaMethod$JavaMethodN.call(JavaMethod.java:630)
    from org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:205)
    from org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:282)
    from org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:139)
    from org.jruby.ast.CallOneArgNode.interpret(CallOneArgNode.java:57)
    from org.jruby.ast.LocalAsgnNode.interpret(LocalAsgnNode.java:123)
    from org.jruby.ast.NewlineNode.interpret(NewlineNode.java:103)
    from org.jruby.evaluator.ASTInterpreter.INTERPRET_METHOD(ASTInterpreter.java:74)
    from org.jruby.internal.runtime.methods.InterpretedMethod.call(InterpretedMethod.java:190)
... 153 levels...
    from org.jruby.ast.BlockNode.interpret(BlockNode.java:71)
    from org.jruby.evaluator.ASTInterpreter.INTERPRET_METHOD(ASTInterpreter.java:74)
    from org.jruby.internal.runtime.methods.InterpretedMethod.call(InterpretedMethod.java:190)
    from org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:179)
    from org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:282)
    from org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:139)
    from usr.local.rvm.rubies.jruby_minus_1_dot_6_dot_0.bin.irb.__file__(/usr/local/rvm/rubies/jruby-1.6.0/bin/irb:17)
    from usr.local.rvm.rubies.jruby_minus_1_dot_6_dot_0.bin.irb.load(/usr/local/rvm/rubies/jruby-1.6.0/bin/irb)
    from org.jruby.Ruby.runScript(Ruby.java:670)
    from org.jruby.Ruby.runNormally(Ruby.java:574)
    from org.jruby.Ruby.runFromMain(Ruby.java:423)
    from org.jruby.Main.doRunFromMain(Main.java:278)
    from org.jruby.Main.internalRun(Main.java:198)
    from org.jruby.Main.run(Main.java:164)
    from org.jruby.Main.run(Main.java:148)
    from org.jruby.Main.main(Main.java:128)jruby-1.6.0 :005 > 

I initially thought the problem was isolated to configatron.configure_from_yaml, but as the above sample shows the damage is done in require 'configatron'.

Some key don't compatible with rake

# Rakefile
gem "configatron", "~> 2.8.2"
require "configatron"

Settings = Configatron.instance
Settings.foo = "foo"
puts Settings.foo  # ok

Settings.import = "import"
puts Settings.import # nothing to print

Because rake is defined some methods in Object: import, task and etc.

uninitialized constant Configatron::Integrations (NameError)

apologies to take the groups time. i cannot find anything on net that suggests anyone has a similar problem.
not a rails / ruby wiz so i’m afraid i’m doing something stupid
using configatron within rails app. bundle install’d etc
have used rails generate configatron:install

but i keep getting : uninitialized constant Configatron::Integrations (NameError)
have tried various gem versions
all files where we’re referring to configatron items have require ''
have even tried require within actual config files.

still get uninitialized constant Configatron::Integrations (NameError)

any ideas?

thanks so much

configatron-2.8.1/lib/configatron/store.rb:308:in `block in parse_options': undefined method `configure_from_hash'

The following code runs error :

configatron.import = "base/path"

configatron.bar = {
  :import => {
    :path => Configatron::Delayed.new { File.join(configatron.import, "bar") }
  }
}

Output :

/Users/sunteya/.rvm/gems/ruby-1.9.2-p180/gems/configatron-2.8.1/lib/configatron/store.rb:308:in `block in parse_options': undefined method `configure_from_hash' for "base/path":String (NoMethodError)
    from /Users/sunteya/.rvm/gems/ruby-1.9.2-p180/gems/configatron-2.8.1/lib/configatron/store.rb:303:in `each'
    from /Users/sunteya/.rvm/gems/ruby-1.9.2-p180/gems/configatron-2.8.1/lib/configatron/store.rb:303:in `parse_options'
    from /Users/sunteya/.rvm/gems/ruby-1.9.2-p180/gems/configatron-2.8.1/lib/configatron/store.rb:148:in `method_missing'
    from /Users/sunteya/.rvm/gems/ruby-1.9.2-p180/gems/configatron-2.8.1/lib/configatron/configatron.rb:15:in `method_missing'
    from /Users/sunteya/Workspaces/bstar/pukka/home_news_client/config/application.extra.rb:7:in `block (3 levels) in <class:Application>'
    from /Users/sunteya/Workspaces/bstar/pukka/home_news_client/config/application.rb:50:in `instance_eval'
    from /Users/sunteya/Workspaces/bstar/pukka/home_news_client/config/application.rb:50:in `block (3 levels) in <class:Application>'

Looks like the "configure_from_hash" method only run on the configatron object.

What is the right / best place to store configatron configuration in a Rails app?

Hello,
I'm cross-posting this from stackoverflow as I don't seem to get any views on this question ( just 3 in over 24 hours :( ). Anyways I'm trying out configatron for my Rails 3.1 app and it's a great tool (thank you, markbates!) - but here is my question:

I'm using configatron gem for a new Rails app that is backed by ActiveRecord. Some of my configatron settings are set in a file and some are pulled from DB, as they will change from time to time, here are a couple of lines from my configatron.rb

configatron.app.uptime.start = Time.now
configatron.email.signature = Setting.where(:keyname => "email_signature").first.value.to_s unless Setting.where(:keyname => "email_signature").first.nil?

Since this app sends multuple emails from multiple mailers - that is a good way to keep this global config in one place, plus it reduces db lookups for signature. If for some reason site admin decides to change it - they can do it through web admin interface that will update my settings table ( tied to Setting model).

This is all jolly & good, however what is the best place to store configatron.rb? Right now it's sitting in my initializers folder. Which means it will load once on application startup - which is good, however if one of the settings changes - site admin decides to tweek email signature to mention a new promotional website - in order for the change to take effect - I would need to restart app ( I'm running passenger - so it trivial to do touch tmp/restart.txt from code). However that means other configatron settings that I don't wont to reset ( such as my uptime start timestamp) will be reset as well, plus if somebody is in a middle of some transaction I will most likely break it.

So what is a better place to move my configatron.rb and load from so that it would allow for
loading once on startup and then changing some configs without and app restart?

Thanks.

Type casting problem when sorting array of Configatron::Dynamic values

try this in console:

configatron.test.not_sorted = [Configatron::Dynamic.new {Time.now.to_i}, Configatron::Dynamic.new {Time.now.to_i}]
=> [1413583466, 1413583466]

configatron.test.sorted = configatron.test.not_sorted
=> [1413583479, 1413583479]

configatron.test.sorted.last.to_s
=> "#Configatron::Dynamic:0x0000000394d218"

This is wrong, it should give a string of the timestamp like this:

Time.now.to_i.to_s
=> "1413583779"

Hook for configuration factory?

I have a question. In my console application, I converted from a homebrew configuration module to Configurator. It tracks say a dozen items and I want to keep the setup logic encapsulated in a factory class. In most circumstances, I only want to setup Configurator once because it's involved. However, during unit testing, I want to generate different configurations against a blank Configurator to ensure various command-line parameters behave as expected.

Since Configurator already mostly supports this use case through 'temp', is there a way I can either:

  • reset Configurator to a blank state to eliminate the change of test run order playing a factor
  • hook in my factory class create method into Configurator, so I don't need to memoize the standard configuration?

Thanks,
Chuck

Confusing behavior when deep cloning with configatron

Hello,

I really like configatron.

Perhaps I've got the wrong idea, but I would like to be able to duplicate/clone a set of configurations. It roughly seems to work but I think there is something wrong with either deep_clone or the inspect method. After using deep_clone to copy a set of configurations, the configurations seem to be duplicated under their original names. Try running the code below to see what I mean.

Thanks,
Morri

require 'configatron'

configatron.testConfig.field = :value

configatron.duplicateConfig = configatron.testConfig.deep_clone

puts "Expecting to see .duplicateConfig, but it isn't there, only .testConfig twice"
p configatron

puts "However configatron_keys does know about .duplicateConfig"
p configatron.configatron_keys

`store': wrong number of arguments (0 for 2) (ArgumentError)

when i try to run "rake assets:precompile RAILS_ENV=test"

it's giving me following error

/var/lib/gems/1.9.1/gems/configatron-4.5.0/lib/configatron/store.rb:51:in `store': wrong number of arguments (0 for 2) (ArgumentError)

i updated configatron 4.2.1 to 4.5.0 but no use. please help

No install docs

How do I install and configure this? Is it a gem, plugin, etc?

Multiple environment configuration files

Hello,

Is there an example or a proposed way to have different files based on ENV for a ruby project?

In other words, if i have a <root>/config/development.rb and a <root>/config/production.rb, is it possible configatron to load the appropriate one based on ENV?

Thank you for any replies,

Alex

Bug Report

I have a key set up like this in my config.yml file and in production mode, it gets read just fine however in development or test mode, Configatron crashes.

site:
version: 1.6.1
url: http://something.local/
domain: something.com

The crash spits out 'domain' as the key that is giving it trouble.

best, Art

array of locked config still can be modified

require 'configatron'
 => true 
2.5.0 :002 > configatron.test = []
 => [] 
2.5.0 :003 > configatron.lock!
 => true 
2.5.0 :004 > configatron.test << 1 # should raise exception
 => [1] 
2.5.0 :005 > configatron.test
 => [1] 

I think subclassing of Array might be required to fix this.

`configatron.temp` broken for nested settings?

Hi there.

We've just upgraded from 2.13.0 to 4.2.0 and have noticed a change in the behaviour in configatron.temp when settings are nested. Here is an example in irb:

2.1.2 :001 > require "configatron"
 => true
2.1.2 :002 > configatron.foo = "foo"
 => "foo"
2.1.2 :003 > configatron.foo
 => "foo"
2.1.2 :004 > configatron.temp { configatron.foo = "bar"; puts configatron.foo }
bar
 => configatron.foo = "foo"
2.1.2 :005 > configatron.foo
 => "foo"
2.1.2 :006 > configatron.bar.baz = "baz"
 => "baz"
2.1.2 :007 > configatron.bar.baz
 => "baz"
2.1.2 :007 > configatron.temp { configatron.bar.baz = "bat"; puts configatron.bar.baz }
bat
 => configatron.bar.baz = "bat"
configatron.foo = "foo"
2.1.2 :009 > configatron.bar.baz
 => "bat"

Is this expected behaviour, or a bug in the deep cloning?

How to properly reload all settings?

Scenario

I have a Setting model where I keep some settings, that can be changed occasionally

class CreateSettings < ActiveRecord::Migration
  def change
    create_table :settings do |t|
      t.string   :keyname, limit: 50,    null: false, index: {unique: true}
      t.text     :value,   limit: 2000,  null: false
      t.string   :name,    limit: 50
      t.string   :description
      t.timestamps   null: false, index: true
    end
    add_index :settings, :updated_at
  end
end

For instance this is used to keep a list of people that should be emailed for certain things . Like accounting report.

# To avoid doing multiple calls to DB - I pull all settings and then pluck needed settings 
configatron.settings = Configatron::Delayed.new{Setting.all.to_a}

configatron.email.errors   = Configatron::Delayed.new{configatron.settings.find{|s| s.keyname == 'email_errors_to'}.value.split(', ')}
configatron.email.accounting      = Configatron::Delayed.new{configatron.settings.find{|s| s.keyname == 'email_accounting_to'}.value.split(', ')}
configatron.email.client1_reports   = Configatron::Delayed.new{configatron.settings.find{|s| s.keyname == 'email_client1_to'}.value.split(', ')}

This setup works well for me. However here every time there is a change in that record in setting ( it happens more often for several clients as people move from one department to another and don't need to be on the list anymore. ) - I need to restart the whole server - I have multiple application instances. This happens at least a couple of times a months. Often enough that's it's annoying but not often enough that I would go for

configatron.email.client1_reports = Configatron::Dynamic.new{Setting.where(keyname: 'email_client1_to').first.value.split(', ')}

@markbates - we actually covered this already in issue #24. And we came to a conclusion that there is no good way around it.

Possible solution - needs feedback

I just had an idea (based on some other config settings I was coding) and wanted to run it here for feedback.

What if I was to setup

# to be set on initially on app load 
configatron.config_last_reload_time = Time.now

configatron.config_reload = Configatron::Dynamic.new{
if configatron.config_last_reload_time > 10.minutes.ago
   configatron.config_last_reload_time = Time.now
   if st = Setting.where(keyname: 'config_reload').first.value.include?"true"
       st.value = 'false'
       st.save
       true
    else
      false
    end
else
   false
end
}

# Then
configatron.email.client1_reports = Configatron::Dynamic.new{Setting.where(keyname: 'email_client1_to').first.value.split(', ') if configatron.config_reload }

Then Setting.where(keyname: 'config_reload') can be set every time a user makes a setting change, but the the change won't apply for 10 minutes potentially. And a DB will only be querried once every 10 mins, and reload all settings if reload_config got set. This way if there is a change like this all instances of an app will get the change withing 10 minutes or less

What do you think?

Nil values?

Hi there,

Is this code doing what we expect? Is there another way to check if a config value is nil?

[6] pry(main)> configatron.foo = nil
=> nil
[7] pry(main)> configatron.foo
=> #<Configatron::Store:0x3fd12f4411b0>
[8] pry(main)> configatron.foo.nil?
=> false
[9] pry(main)> configatron.foo.inspect
=> ""

Using version 4.2.1, with ruby 2.1.3.

Thanks!

the base setting will be override by hash value

CODE:

# gem "configatron", "~> 2.8.2"

Settings = Configatron.instance

Settings.remote.ntp = "localhost"
Settings.remote.servers = {
  :ntp => "58.196.13.13"
}

puts Settings.remote.ntp  # print "58.196.13.13"

I would think Settings.remote.ntp should be print localhost
and Settings.remote.servers.ntp should be print 58.196.13.13

Non-existent options should return nil rather than Configatron::Store

The problem with returning an instance of Configatron::Store, as you probably already know, is that you can't do var = configatron.some_option || 'default', where some_option may or may not exist.

Because even if it does exist, a Configatron::Store object will be returned, which is truthy and therefore the || 'default' never has any effect.

Worse yet, when we try to use the value, we will inevitably get NoMethodErrors, because Configatron::Store does not act like a string or a Fixnum or any of the data types we are probably expecting our value to be.

I don't THINK there is any way to make objects of a certain class so they are not truthy (that would sure be handy though, but you can't override the logical operators like ||), so the only solution I can think of is to have configatron return (for options that are not found) a special nil object that had a method_missing added that proxied the message on to the Store instance but otherwise behaved like a normal nil. Do you think that could work?

NameError: uninitialized constant Configatron::Dynamic

While I was trying Configuratron under irb (Ruby 2.0.0p195) I found this:

configatron.current.time = Configatron::Dynamic.new {Time.now}
NameError: uninitialized constant Configatron::Dynamic
from (irb):35
from /usr/local/bin/irb:12:in `

'

Am I missing some package as a find reveals no Dynamic class defined?

Suggestion: Unset keys should be falsy

I love configatron, but although it solves a lot of things, it makes it rather difficult to work with unassigned keys.

In a standard hash, or an OpenStruct, non existing values are falsy:

o = OpenStruct.new({ one: '1', two: '2' })
p o.three
# => nil

While in configatron they are truthy:

# configatron.allow = false   # unset
p configatron.allow ? "allowed" : "not allowed"
# => "allowed" (but expected "not allowed")

Even if I want to set defaults, I cannot work with the common ruby syntax:

configatron.allow ||= false

And instead, I can only do:

configatron.allow = false unless configatron.has_key? :allow

And in cases where I can't (or prefer to avoid) having defaults, in order to allow "open schema", the only way for me to handle unset keys in the same way as falsy keys, is:

allowed = configatron.has_key?(:allow) ? configatron.allow : false
p allowed ? "allowed" : "not allowed"

Am I missing some functionality in configatron that will make this easier?

If there is no way to alleviate the above issues, I would love to see a change that allows it - even if it will require me to opt-in to this behavior using some config directive (in case it is desired to avoid introducing a breaking change).

Nested 'temp' creating some unexpected behavior

In our tests, we make use of rspec's before/after/around lifecycle hooks to set the state of the test, including configatron settings with configatron.temp. Unfortunately when you have multiple configatron.temp competing with each other (one wrapping the other basically), it produces some results that we didn't expect:

[3] pry(main)> configatron.foo = 1
1
[4] pry(main)> configatron.temp do
[4] pry(main)*   configatron.foo = 2
[4] pry(main)*   configatron.temp do
[4] pry(main)*     configatron.foo = 3
[4] pry(main)*   end
[4] pry(main)* end
3
[5] pry(main)>
[6] pry(main)> configatron.foo
2

In this example, our our tests assumed that the settings would be returned to their original state, which in this example would be configatron.foo = 1

Is there a more elegant way to achieve what we want here with temp? In the short term, we've restored to manually holding the state of the variable we are setting and then resetting it at the end of the before/around block

Script/Runner not finding config.yml

This is probably something obvious so I thought I would ask but when my cron task runs a script/runner like so:

/var/www/www.greenling.com/current/script/runner -e production "FutureDeliveryScheduler.schedule_future_orders" >> /var/www/www.greenling.com/shared/log/cron.log 2>&1

I get this in the cron log:

No such file or directory - /var/www/config/config.yml

Store and retrive?

there is a way to store and retive the information in the local hard drive?

Multi-project configuration loaded from a rails engine?

Hi,

I don't want to duplicate the configuration in my many projects that they all should share anyway so was trying to use configatron for this but something is failing.

inside the rails engine I have config/configatron/*.rb one of those files could look like:

# config/configatron/development.rb
configatron.hosts do |hosts|
  hosts.api   = "http://localhost:3000/"
  hosts.admin = "http://localhost:3001/"
  hosts.jobs  = "http://localhost:3002/"
  hosts.web   = "https://localhost:3006/"
end

The project is a rails engine so no initializer here since that won't work but in my spec/dummy and projects using the engine I have the following initializer.

# config/initializers/configatron.rb
require 'configatron'
Configatron::Rails.init CasinoSaga::Engine.root.join('config', 'configatron')

This works for a few things. If I load it locally and check the rails console I've got values there but on Heroku and when running tests all the values are blank. Any ideas why that is happening and how I might fix it? I thought simply running Configatron::Rails.init CasinoSaga::Engine.root.join('config', 'configatron') would fix any such problem but configatron isn't initialized ok anyway. Using 3.rc something version. Should I downgrade to V2?

Leaks in configatron.temp

We've faced an issue with configatron.temp due to unexpected side effect

  # config changes in  rspec case
  # leaked into other
 configatron.temp do
      #leaks
      configs.each { |config| configatron.origins[config.origin_id] = { app_id: '123' } }
      # doesn't leak
      # configatron.origins = configs.map { |cfg| [cfg.origin_id, { app_id: '123' }] }.to_h
      example.run
end

After skimming through source code of configatron.temp, I humbly suggest authors to consider implementation of configatron.temp with Marshal.dump and Marshal.load, which looks like straightforward solution with rather strong guarantees.

Use as drop-in replacement for Hash

I've been toying around with the idea in our project to use configatron as an alternative to ActiveSupport's HashWithIndifferentAccess. But I'd still like to be able to treat each Configatron::Store object as a duck-typed hash. For example, we use #merge a lot, and I can't get that with configatron without going through #to_h. And I'd like to get a Configatron::Store object back instead of a Hash anyway.

What would you think about turning this into a full drop-in replacement for a hash, similar to HashWithIndifferentAccess? I.e. configatron would delegate ALL Hash methods to @attributes as opposed to just the ones you explicitly listed? There would be a little more work involved, obviously, but you know what I mean.

I'd be happy to fork this and make a different gem if you'd prefer. Just wanted to get your thoughts.

Add Ruby 3.2 Support for Rails apps using this as File.exists? was removed

Getting the following error when I try to upgrade my app to Ruby 3.2. Apparently File.exists? alias has been removed

NoMethodError: undefined method `exists?' for File:Class
/__w/truva/truva/vendor/bundle/ruby/3.2.0/gems/configatron-4.5.1/lib/configatron/integrations/rails.rb:45:in `block in init'
/__w/truva/truva/vendor/bundle/ruby/3.2.0/gems/configatron-4.5.1/lib/configatron/integrations/rails.rb:44:in `each'
/__w/truva/truva/vendor/bundle/ruby/3.2.0/gems/configatron-4.5.1/lib/configatron/integrations/rails.rb:44:in `init'
/__w/truva/truva/config/initializers/configatron.rb:6:in `<top (required)>'
/__w/truva/truva/Rakefile:7:in `require_relative'
/__w/truva/truva/Rakefile:7:in `<top (required)>'
/__w/truva/truva/vendor/bundle/ruby/3.2.0/gems/rake-13.0.6/exe/rake:27:in `<top (required)>'
/home/circleci/.rubygems/gems/bundler-2.4.12/lib/bundler/cli/exec.rb:58:in `load'
/home/circleci/.rubygems/gems/bundler-2.4.12/lib/bundler/cli/exec.rb:58:in `kernel_load'
/home/circleci/.rubygems/gems/bundler-2.4.12/lib/bundler/cli/exec.rb:[23](https://github.com/viewthespace/truva/actions/runs/7254710934/job/19764010589?pr=6395#step:14:24):in `run'
/home/circleci/.rubygems/gems/bundler-2.4.12/lib/bundler/cli.rb:492:in `exec'
/home/circleci/.rubygems/gems/bundler-2.4.12/lib/bundler/vendor/thor/lib/thor/command.rb:27:in `run'
/home/circleci/.rubygems/gems/bundler-2.4.12/lib/bundler/vendor/thor/lib/thor/invocation.rb:127:in `invoke_command'
/home/circleci/.rubygems/gems/bundler-2.4.12/lib/bundler/vendor/thor/lib/thor.rb:392:in `dispatch'
/home/circleci/.rubygems/gems/bundler-2.4.12/lib/bundler/cli.rb:34:in `dispatch'
/home/circleci/.rubygems/gems/bundler-2.4.12/lib/bundler/vendor/thor/lib/thor/base.rb:485:in `start'
/home/circleci/.rubygems/gems/bundler-2.4.12/lib/bundler/cli.rb:28:in `start'
/home/circleci/.rubygems/gems/bundler-2.4.12/exe/bundle:45:in `block in <top (required)>'
/home/circleci/.rubygems/gems/bundler-2.4.12/lib/bundler/friendly_errors.rb:117:in `with_friendly_errors'
/home/circleci/.rubygems/gems/bundler-2.4.12/exe/bundle:33:in `<top (required)>'
/home/circleci/.rubygems/bin/bundle:[25](https://github.com/viewthespace/truva/actions/runs/7254710934/job/19764010589?pr=6395#step:14:26):in `load'
/home/circleci/.rubygems/bin/bundle:25:in `<main>'

https://bugs.ruby-lang.org/issues/17391

Added a PR for this: #112

Type casting problem when sorting array of Configatron::Dynamic values

try this in console:

configatron.test.arr = [Configatron::Dynamic.new {Time.now.to_i}, Configatron::Dynamic.new {Time.now.to_i}]
=> [1413583466, 1413583466]

configatron.test.arr.last.to_s
=> "#Configatron::Dynamic:0x0000000394d218"

This is wrong, it should give a string of the timestamp like this:

Time.now.to_i.to_s
=> "1413583779"

ConfigatronPlus functionality into Configatron?

I have a gem that's nearing readiness for release. https://github.com/anithri/configatron-plus

Basically it adds some wrapper functionality for loading configuration from default files, explicitly defined filenames, and environmental variables. I'm working on a project that's going to have many different parts, and I wanted to be able to easily read configuration from say: app_config.rb, /etc/app/config.rb, ~/.apprc, and the ENV. to accomplish this in code you'd...

require 'configuration-plus'
ConfiguarionPlus.config.env_prefix = "app_"
ConfigurationPlus.sources = ["app_config.rb","/etc/app/config.rb","~/.apprc",:env]
ConfigurationPlus.fetch_sources

ConfigurationPlus would then (in this order)

  1. check to see if app_config.rb is in the current directory, and load it if it is.
  2. check to see if config.rb is in the /etc/app directory, and load it if it is.
  3. check to see if .apprc is in the users home directory, and load it if it is.
  4. load any environmental variables that start with app_

Anyway, I'm still polishing it, and getting it ready to release. But I can't decide if I think it should be added to the Configatron gem directly or not. So I'm asking you what you think. I'm happy to alter the API, re arrange things, and tighten things up as needed, but if you don't think it belongs with the core functionality, I'll just release it on it own.

It's got a pretty good set of green specs , and partial documentation that I will finish.

Let me know or ask me questions. Thanks for reading.

How to share a piece of config

Hi,

I'd like to be able to have some common parts shared (and eventually overwritten) by other parts of the configuration. Example :

configatron.shared.a = 'foo'
configatron.shared.b = 'bar'
configatron.shared.c = 'baz'

configatron.another = configatron.shared
configatron.another.d = 'qux'

configatron.yet_another = configatron.shared
configatron.yet_another.a = 'azerty'

If the configuration is to be copied, we could use configatron.another = configatron.shared.dup. An overwrite wold change only the copied value.

But if it is to be aliases, we could use configatron.another = configatron.shared. An overwrite would change the original value and be reflected in all aliases.

Is such a thing crazy?
I'd have real use case.

Suggestion: Allow asking `configatron.something?`

It would be nice if configatron.param? will simply be (conceptually-) aliased to !! configatron.param

# Allow asking `configatron.something?`
configatron.force = false
p configatron.force  ? "forced" : "not forced"
p configatron.force? ? "forced" : "not forced"
# => "not forced"
#    "forced" (but expected "not forced")

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.