Giter Site home page Giter Site logo

config_mapper's People

Contributors

aidansteele avatar alisonrosewarne avatar mdub avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

config_mapper's Issues

Feature request: deprecations

It'd be super cool if I could just set deprecated: true on an attribute/component.

Or alternatively set it to a "deprecation_message" rather than just a boolean.

But it'd be nice if you could do this at a component level, as well as individual attributes.

One would have to ask for these deprecations manually, after the config was loaded. E.g. config.deprecations.each{|key, message| logger.warn("DEPRECATED: #{key} - #{message}") }

Since the config struct itself has no concept of a logger, or what might happen with deprecations, it simply needs the ability to mark a particular thing as deprecated, and a means to access all that info.

Let me know if you'd be interested in something like this at the global layer, otherwise I'll hack something for our specific needs.

Configuration Documentation

We're currently using ConfigMapper::ConfigStruct classes for defining our configuration data structure, and also maintain a separate 'configuration reference' yaml document for our users.

E.g. for the following code:

class State < ConfigMapper::ConfigStruct

  component :position do
    attribute :x, default: 0
    attribute :y, default: 0
  end

end

We would also write a companion config-reference.yml document containing:

position: 
  type: Object
  description: |
    The position of our object
position.x:
  type: Integer
  description: |
    x-coordinate
position.y:
  type: Integer
  description: |
    y-coordinate

It would be great if ConfigStruct elements (attributes, components and component_dicts) supported some additional documentation options, so that a config reference document could be generated.

I'm thinking this would involve adding description option to all elements and a type option for attributes, e.g.

component :position, description: "The position of our object" do
  attribute :x, default: 0, description: "x-coordinate", type: Integer
  attribute :y, default: 0, description: "y-coordinate", type: Integer
end

Then exposing a method on ConfigStruct objects (maybe #reference_yaml?) that would return a yaml object of the config-reference data above.

Happy to make a PR but would like some feedback first :)

"0 is not a symbol nor a string" error when providing an Array rather than a Hash

Given a simple target object

class Position

  attr_reader :x
  attr_reader :y

  def x=(arg)
    @x = Integer(arg)
  end

  def y=(arg)
    @y = Integer(arg)
  end

end

pos = Position.new

configuration from a Hash is fine:

ConfigMapper.configure_with({"x" => 1}, pos)
pos #=> #<Position:0x007fc3bf8a55e0 @x=1>

but passing an array throws a TypeError

ConfigMapper.configure_with(["x"], pos)
TypeError: 0 is not a symbol nor a string
	from ...

We should catch the exception, and return a helpful error message.

Config for Hashes of objects seems to not be working.

Hi @mdub,

Hope you are going well! Cheers for the work you have put into maintaining this gem.
Was inspired to use it after your chat at REA Ruby guild.

Only thing is I am having trouble running the example in the README for mapping nested config.

require 'config_mapper'
require 'config_mapper/config_struct'

class Position < ConfigMapper::ConfigStruct

  attr_reader :x
  attr_reader :y

  def x=(arg); @x = Integer(arg); end
  def y=(arg); @y = Integer(arg); end

end

positions = Hash.new { |h,k| h[k] = Position.new }

config_data = {
  "fred" => { "x" => 2, "y" => 4 },
  "mary" => { "x" => 3, "y" => 5 }
}

ConfigMapper.configure_with(config_data, positions)
puts positions["fred"].x            #undefined method `x' for {"x"=>2, "y"=>4}:Hash (NoMethodError)
puts positions["mary"].y

If I use version 1.2 I can get it to work, so seems like this changed from version 1.2 to 1.3

These are the two release commits

git diff 007d777a1e44926337db41179770ed96c68e47f4 18fb8aa381ec54909404aa98aee258e51e4d76a1

Seems like the noteable change was from using dict_mapper to collection_mapper for hashs.

Unsure if nested config was purposely removed or if this is a bug.

Implement a way to define lists of components

We would like a way to define lists. In my head, the config would look like this:

people:
-
  name: danial pearce
  awesomeness: 10
  preferences:
    drink: beer
    food: burgers
-
  name: fred
  awesomeness: 2
  preferences:
    drink: water

And the model might look something like this:

class Config < ConfigMapper::ConfigStruct
  component_list :people do
    attribute :name, String
    attribute :awesomeness, Integer, default: 0
    component_dict :preferences do
      attribute :drink, String
      attribute :food, String, default: "parmas"
    end
  end
end

Which would map to PORs like so:

{
  "people": [
    { "name": "danial pearce", "awesomeness": 10, "preferences": { "drink": "beer", "food": "burgers" } },
    { "name": "fred", "awesomeness": 2, "preferences": { "drink": "wine", "food": "parmas" } },
  ]
}

I think doing the above is currently possible by creating a Types::People, and using component :people, type: Types::People although I've not yet tried. I think the above would be a nicer solution in the long run, as the entire config definition would be in 1 place instead of spread out across multiple types, where the "type" also has other stuff mingled in with it and doesn't read quite as nice as a simple config definition.

Allow for relationships

In a situation of nested components, it would be handy for child nodes to know about their parents.

component_dict :teams do
  attribute :name

  component_dict :services do
    attribute :name

    def full_name
      "#{_parent.name} - #{service.name}"
    end
  end
end

At the moment, I think within the context of a service here, you don't have any access to the parent object. So something like this is not possible.

I'm not entire sure what options are available for implementing this, but happy to have a crack if you can give some guidance. Or just tell me it's a really bad idea ๐Ÿ˜„

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.