Giter Site home page Giter Site logo

docile's People

Contributors

ajedi32 avatar bitdeli-chef avatar cmkoller avatar dependabot[bot] avatar domon avatar dslh avatar eregon avatar gitter-badger avatar gogainda avatar hosamaly avatar jochenseeber avatar ktdreyer avatar le0pard avatar lkdjiin avatar ms-ati avatar ms-tg avatar mtasaka avatar pragtob avatar rrrene avatar taichi-ishitani avatar tomeon 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

docile's Issues

Can't use this hash

Can't do this:

variable PARAMETER_VARIABLE.create {
name :bar
value {:alpha => {:default => 1}, :beta => {:default => 2}, :charlie => {:default => 3}, :delta => {:default => 4}}
}

for something like this:

class Parameter
attr_reader :name

      def initialize(name, metadata)
        @name = name
        super({:name => name, :metadata => metadata})
      end

      def Parameter.create(&block)
        Docile.dsl_eval(ParameterBuilder.new, &block).create
      end
    end

    class ParameterBuilder
      def name(name)
        @name = name
      end

      def value(value)
        if value.is_a? Hash
          @value = {:child => value}
        elsif value.is_a? Array
          @value = {:default => value}
        else
          @value = value
        end
      end

      def create
        Parameter.new(@name, @value)
      end
    end

How to start?

The examples make it look easy but they are all examples when the DSL code lives in the same file as the DSL implementation, which is hardly useful.

How would I actually run it if
@sauce_level = :extra

pizza do
cheese
pepperoni
sauce @sauce_level
end

was in a separate file from the rest?

How to execute a method from a context in a different context?

Hi,

We're using Docile on Avo to manage some parts of our DSL.
We're experiencing an issue where a method call within the block is not executing in the desired context.
Here's a simplified example of the problem:

require "docile"

module HasItems
  attr_reader :items

  def initialize
    @items = []
  end

  def field(id)
    @items << id
  end
end

class Panel
  include HasItems
end

class Resource
  include HasItems

  def panel(&block)
    panel = Docile.dsl_eval(Panel.new, &block)

    puts "Panel items: #{panel.items}"
  end

  def extracted_fields
    puts "Context inside extracted_fields method: #{self}"
    field :extracted
  end

  def fields
    field :id

    panel do
      puts "Context inside panel do block: #{self}"
      extracted_fields
    end
  end
end

resource = Resource.new
resource.fields
puts "Resource items: #{resource.items}"

Result:

Context inside panel do block: #<Panel:0x00007fd830d3d488>
Context inside extracted_fields method: #<Resource:0x00007fd830d3d758>
Panel items: []
Resource items: [:id, :extracted]

Expected result (ignoring the context prints):

Panel items: [:extracted]
Resource items: [:id]

We'd like to make it as easy as possible to extract methods in the most natuarl way, as a method that they can run inside our custom blocks (panel, tab, sidebar, and more).

When the panel block it's executed the extracted_fields method is not found, so it falls back to the @__fallback__ context which is the resource's context. The problem here is that the code from extracted_fields was called from the panel block with the intention to add a field to that panel, but it was added to the resource.

We've found 2 workarounds

1 - Pass the context to the method

We don't like this approach as it makes the user learn yeat another pattern that they might implement badly and doesn't feel that natural.

def extracted_fields(context)
  puts "Context inside extracted_fields method: #{self}"
  context.field :extracted
end

def fields
  field :id

  panel do
    puts "Context inside panel do block: #{self}"
    extracted_fields(self)
  end
end

2 - Make extracted_fields return a Proc and instance_exec it

It seems unnatural again to have a method run a block. But mor importantly, they have to call instance_exec inside the panel block which we don't want

def extracted_fields
 puts "Context inside extracted_fields method: #{self}"

 -> { field :extracted }
end

def fields
 field :id

 panel do
   puts "Context inside panel do block: #{self}"
   instance_exec &extracted_fields
 end
end

Both workarounds require public DSL interaction, and one of our goals is to keep the public DSL as simple as possible.

Ideal scenario(s)

The ideal scenario would be that they declare the methods on the resource file and just rub them inside the custom blocks (panel, tab, sidebar, and more).

def extracted_fields
  field :extracted
end

def fields
  field :id

  panel do
    extracted_fields
  end
end

Next ideal scenario

If that's impossible, we'd like to expose a simple method call or something similar that would be simple to implement and least destructive.

def extracted_fields
  field :extracted
end

def fields
  field :id

  panel do
    unpack_fields extracted_fields
    # or maybe
    unpack_fields -> { extracted_fields }
  end
end

Is there a more elegant solution or best practice within Docile to ensure that method calls within a block execute in the expected context while avoiding the need for additional public DSL interactions?
We'd greatly appreciate your help and guidance on this matter.

Thank you!

Remove support for 1.8.7 and perhaps all EOL Rubies

It now appears that, in addition to being end-of-life for years, Ruby 1.8.7 is no longer runnable on Travis CI.

For comparison, Github Actions supports no Rubies older than 2.1.

Therefore, it's now time to remove testing, and then support, for Ruby 1.8. In Docile, this will result in actual code changes, as code paths and choices do exist solely to support 1.8 today.

How to use this ticket

I'd like to use this ticket to capture (a) plans and notes on what code can change to remove this support, and (b) links to every PR that pertains to removing this support. The final PRs should be for a new minor version.

What about Ruby 1.9, etc?

Do you use Docile on an end-of-life ("EOL") Ruby version, such as 1.9.3? If so, please respond to this ticket to let me know. If nobody is actively following this project and using EOL Rubies, I'd like to consider removing support for all of them. However, I would prefer to continue to support any Rubies that are actually in use by folks following this project, so please respond if you would be impacted!

Checklist

  • Remove 1.8.7 and REE from Travis CI (see #61)
  • singleton_class - stop using the 1.8.7 fallback pattern
  • FallbackContextProxy#instance_variables - stop supporting Strings on 1.8
  • docile.gemspec and on_what.rb - remove all pinned dependencies for 1.8
  • README and any other documentation
  • HISTORY.md
  • ??? Please suggest more items below!

Superclasses, Children and unexpected results (self is not what it should be)

Hi there!

First, thanks a lot for your work! ๐Ÿ’š

Problematic Script

require "docile"

class Parent
  attr_reader :children

  def initialize
    @children = []
  end

  def add_child(clazz, &block)
    child = clazz.new
    children << child

    Docile.dsl_eval(child, &block) if block
    child
  end
end

class CustomParent < Parent
  def do_stuff
    add_child Parent do
      wanna_be_custom
    end
  end

  def wanna_be_custom
    add_child CustomParent
  end
end

parent = CustomParent.new
parent.do_stuff

p parent.children

Actual Output

Both Children are added to the main parent/within the block self isn't shifted to the child

[#<Parent:0x000055794759c598 @children=[]>, #<CustomParent:0x00005579475ab7a0 @children=[]>]

Expected Output

the main parent has one child, which itself then has the CustomParent as a child. (within the block self correctly is the child)

[#<Parent:0x000055d997c50460 @children=[#<CustomParent:0x000055d997c5b658 @children=[]>]>]

This output can currently be achieved in 2 ways:

  1. inline wanna_be_custom
  def do_stuff
    add_child Parent do
      add_child CustomParent
    end
  end
  1. in add_child, instead of instantiating the passed in class just use self.class (yes this changes semantics but might give a hint as to the source of this)
  def add_child(clazz, &block)
    child = self.class.new
    children << child

    Docile.dsl_eval(child, &block) if block
    child
  end

Might be related to #31 but it's marked fixed ๐Ÿคทโ€โ™‚๏ธ

edit: After a good night sleep I finally realized that of course this is about self being the wrong thing so much like #31 ;)

Potential thread safety issue?

Hi Marc!

I'm experimenting with some multi-threaded code that uses Docile and I think I may have encountered a thread safety issue. I'm able to reproduce with the following code (depends on the https://github.com/grosser/parallel gem):

require 'parallel'
require 'docile'
class MyClass
  def run_in_threads
      Parallel.each(
         [ Array.new, Array.new ],
        in_threads: 2
     ) { |array| Docile.dsl_eval_with_block_return(array, &block) }
  end
  
  def block
      lambda { do_some_work }
  end

  def do_some_work
     sleep(rand)
     push 1
  end
end

MyClass.new.run_in_threads

This pretty reliably gives me:

Traceback (most recent call last):
        8: from /Users/mdiscala/.gem/ruby/2.6.6/gems/parallel-1.19.2/lib/parallel.rb:211:in `block (4 levels) in in_threads'
        7: from /Users/mdiscala/.gem/ruby/2.6.6/gems/parallel-1.19.2/lib/parallel.rb:360:in `block in work_in_threads'
        6: from /Users/mdiscala/.gem/ruby/2.6.6/gems/parallel-1.19.2/lib/parallel.rb:519:in `with_instrumentation'
        5: from /Users/mdiscala/.gem/ruby/2.6.6/gems/parallel-1.19.2/lib/parallel.rb:361:in `block (2 levels) in work_in_threads'
        4: from /Users/mdiscala/.gem/ruby/2.6.6/gems/parallel-1.19.2/lib/parallel.rb:510:in `call_with_index'
        3: from (irb):237:in `block in run_in_threads'
        2: from (irb):241:in `block in block'
        1: from (irb):246:in `do_some_work'
NoMethodError (undefined method `push' for #<MyClass:0x00007fa66f90c9b0>)

When I run this with only a single thread (changing in_threads: 1), the output comes as expected:

irb(main):273:0> MyClass.new.run_in_threads
=> [[1], [1]]

From my reading of the code, it seems that Docile achieves the ability for do_some_work to call methods on the DSL object by adding a method_missing call to the base class (see https://github.com/ms-ati/docile/blob/master/lib/docile/fallback_context_proxy.rb#L54). The gem then cleans up after itself after the calls are complete https://github.com/ms-ati/docile/blob/master/lib/docile/fallback_context_proxy.rb#L54.

My hunch is that I get the method missing error because the clean up happens in one thread and then removes the methods for the other one. I could also imagine getting into cases where the push method ends up writing to the wrong array, depending on the timing. Is that understanding correct?

If so, it seems like this may be difficult to make thread safe. The best I can think of is to (1) assign the receiver to a thread variable in https://github.com/ms-ati/docile/blob/master/lib/docile/fallback_context_proxy.rb#L5, (2) have the method missing definition dispatch calls to the receiver pulled from the thread variable, and (3) never cleanup the method_missing definition.

This doesn't quite seem worth it to support to me, but am curious for your take on all of the above!

Happy holidays & hope all is well!
--Mike

Use Rubocop in CI

With support dropping for Ruby 1.8.7 in #58, is it time to instrument Rubocop in CI, and bring the entire codebase into line with its recommendations?

[DEPRECATION] #adapters is deprecated. Use #profiles instead.

Full message on Ruby 2.7.5:

/ruby-2.7.5/gems/docile-1.4.0/lib/docile/fallback_context_proxy.rb:93:in `method_missing': [DEPRECATION] #adapters is deprecated. Use #profiles instead.

Happens possibly when using Simplecov, from 0.16.0 till newest.

Warning related to key word argument

Hi @ms-ati ,

Following warning related to key word argument is displayed when an method including key word argument is called withing DSL block.

/opt/rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/docile-1.3.2/lib/docile/fallback_context_proxy.rb:87: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call

Execute this example code then you will see the above warning.

class Foo
  def bar(baz: 0)
  end
end

require 'docile'
Docile.dsl_eval(Foo.new) do
  bar(baz: 1)
end
  • Ruby version: ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-linux]
  • Docile version: 1.3.2

Move from Travis CI to Github Actions (blocked by Ruby < 2.1 support)

With experience of both, I've found maintenance of CI in Github Actions quite a bit easier than in Travis CI.

Therefore, when the day arrives that we support only Rubies supported in Github Actions, I'd like to plan to transition.

Checklist

  • Add Github Actions CI configuration, in parallel with current Travis CI
  • (blocked on Ruby versions supported) Remove configuration for Travis CI

DSL object is replaced when #dsl_eval is nested

I found strange behavior that DSL object is replaced when #ds_eval is nested.
Here is sample code to re-produce this issue.

require 'docile'

class Foo
  def display
    p 'foo'
  end
end

class Bar
  def display
    p 'bar'
  end
end

foo = Foo.new
bar = Bar.new

Docile.dsl_eval(foo) do
  display # 1st
  Docile.dsl_eval(bar) do
    display # 2nd
  end
  display # 3rd
end

Execute above code, you will see following output:

$ ruby docile_test.rb
"foo"
"bar"
"bar"

The 3rd #display call should output "foo" because foo object is DSL object.
However it's seemed that DSL object of outer block is replaced with DSL object of innter block (bar) because actual output is "bar".

rspec testsuite fails with ruby 3.3.0dev

Testing with ruby 3.3.0dev (I tried: ruby/ruby@8cb906d ), docile git head ( 08cf67d ) rspec testsuite fails like:

$ rspec spec
.....
Failures:

  1) Docile.dsl_eval when DSL have NoMethod error inside raise NoMethodError error from nil
     Failure/Error:
       expect { push_element }.
         to raise_error(
           NoMethodError,
           /undefined method `push' (for|on) nil:NilClass/
         )

       expected NoMethodError with message matching /undefined method `push' (for|on) nil:NilClass/, got #<NoMethodError: undefined method `push' for nil> with backtrace:
         # ./spec/docile_spec.rb:242:in `push_element'
         # ./lib/docile/fallback_context_proxy.rb:93:in `method_missing'
         # ./spec/docile_spec.rb:249:in `block (6 levels) in <top (required)>'
         # ./spec/docile_spec.rb:249:in `block (5 levels) in <top (required)>'
         # ./lib/docile/execution.rb:35:in `instance_exec'
         # ./lib/docile/execution.rb:35:in `exec_in_proxy_context'
         # ./lib/docile.rb:46:in `dsl_eval'
         # ./spec/docile_spec.rb:248:in `block (4 levels) in <top (required)>'
     # ./spec/docile_spec.rb:249:in `block (5 levels) in <top (required)>'
     # ./lib/docile/execution.rb:35:in `instance_exec'
     # ./lib/docile/execution.rb:35:in `exec_in_proxy_context'
     # ./lib/docile.rb:46:in `dsl_eval'
     # ./spec/docile_spec.rb:248:in `block (4 levels) in <top (required)>'

Finished in 0.03959 seconds (files took 0.10392 seconds to load)
45 examples, 1 failure

Failed examples:

rspec ./spec/docile_spec.rb:247 # Docile.dsl_eval when DSL have NoMethod error inside raise NoMethodError error from nil

This is due to :
ruby/ruby#6950
https://bugs.ruby-lang.org/issues/18285

instance variables are overwritten with nil value when DSL and block contexts are same

Instance variables of DSL context object are overwritten with nil value when DSL conetext object and block context object are the same object.

Here is example code:

require 'docile'

class DSLContext
  def foo(v = nil)
    @foo = v if v
    @foo
  end

  def process_code(code)
    Docile.dsl_eval(self, &binding.eval("proc { #{code} }"))
  end
end

dsl_context = DSLContext.new
dsl_context.process_code 'foo 1; p foo'
p dsl_context.foo

I think the result of above code should be like below:

1
1

but the actual result is below:

1
nil

self is overwritten with nested blocks

In your full person tree example, it illustrates a very interesting bug. (Well, it may not be a bug, but it's definitely something I would like to be able to avoid.)

If we change the code to:

p = person {
  puts "1a: #{self}"
  name 'John Smith'
  puts "1b: #{self}"
  mother {
    puts "2a: #{self}"
    name 'Mary Smith'
  }
  puts "1c: #{self}"
  father {
    puts "3a: #{self}"
    name 'Tom Smith'
    mother {
      puts "3a1: #{self}"
      name 'Jane Smith'
    }
    puts "3b: #{self}"
  }
  puts "1d: #{self}"
}

Then, we would think all the "1x" selfs would be the same, all the 2x selfs would be the same, and so on. But ,they're not. You actually end up with:

1a: #<PersonBuilder:0x000000000331f260>
1b: #<PersonBuilder:0x000000000331f260>
2a: #<PersonBuilder:0x000000000331df28>
1c: #<PersonBuilder:0x000000000331df28>
3a: #<PersonBuilder:0x0000000003317e98>
3a1: #<PersonBuilder:0x00000000033164d0>
3b: #<PersonBuilder:0x00000000033164d0>
1d: #<PersonBuilder:0x0000000003317e98>

Which is a distinct problem. I run into this in one of the tests in DSL::Maker (a quasi-DSL for creating DSLs). I've read your code and I think the problem is here - it should avoid setting self, but I'm not sure.

Roll back backtrace

Hi @ms-ati ,

I have an enhancement request about backtrace.

When a NoMethodError is raised inside the given block, the 1st entry of its back trace is not the original location.
For example,

require 'docile'

foo = Object.new
bar = Object.new

Docile.dsl_eval(foo) do
  Docile.dsl_eval(bar) { fizz_buzz }
end

Execute above code then you can get following error message.

C:/Ruby/Ruby25-x64/lib/ruby/gems/2.5.0/gems/docile-1.3.1/lib/docile/fallback_context_proxy.rb:55:in `block in initialize': undefined method `fizz_buzz' for main:Object (NoMethodError)
        from C:/Ruby/Ruby25-x64/lib/ruby/gems/2.5.0/gems/docile-1.3.1/lib/docile/fallback_context_proxy.rb:84:in `method_missing'
        from C:/Ruby/Ruby25-x64/lib/ruby/gems/2.5.0/gems/docile-1.3.1/lib/docile/fallback_context_proxy.rb:55:in `block in initialize'
        from C:/Ruby/Ruby25-x64/lib/ruby/gems/2.5.0/gems/docile-1.3.1/lib/docile/fallback_context_proxy.rb:84:in `method_missing'
        from docile_backtrace.rb:7:in `block (2 levels) in <main>'
        from C:/Ruby/Ruby25-x64/lib/ruby/gems/2.5.0/gems/docile-1.3.1/lib/docile/execution.rb:26:in `instance_exec'
        from C:/Ruby/Ruby25-x64/lib/ruby/gems/2.5.0/gems/docile-1.3.1/lib/docile/execution.rb:26:in `exec_in_proxy_context'
        from C:/Ruby/Ruby25-x64/lib/ruby/gems/2.5.0/gems/docile-1.3.1/lib/docile.rb:43:in `dsl_eval'
        from docile_backtrace.rb:7:in `block in <main>'
        from C:/Ruby/Ruby25-x64/lib/ruby/gems/2.5.0/gems/docile-1.3.1/lib/docile/execution.rb:26:in `instance_exec'
        from C:/Ruby/Ruby25-x64/lib/ruby/gems/2.5.0/gems/docile-1.3.1/lib/docile/execution.rb:26:in `exec_in_proxy_context'
        from C:/Ruby/Ruby25-x64/lib/ruby/gems/2.5.0/gems/docile-1.3.1/lib/docile.rb:43:in `dsl_eval'

The entry for the original location is this but the top entry is for docile's code.

docile_backtrace.rb:7:in `block (2 levels) in <main>'

I'd like to roll back the backtrace to the original entry for perspicuity like below.

docile_backtrace.rb:7:in `block (2 levels) in <main>': undefined method `fizz_buzz' for main:Object (NoMethodError)
        from docile_backtrace.rb:7:in `block (2 levels) in <main>'
        from C:/Ruby/Ruby25-x64/lib/ruby/gems/2.5.0/gems/docile-1.3.1/lib/docile/execution.rb:26:in `instance_exec'
        from C:/Ruby/Ruby25-x64/lib/ruby/gems/2.5.0/gems/docile-1.3.1/lib/docile/execution.rb:26:in `exec_in_proxy_context'
        from C:/Ruby/Ruby25-x64/lib/ruby/gems/2.5.0/gems/docile-1.3.1/lib/docile.rb:43:in `dsl_eval'
        from docile_backtrace.rb:7:in `block in <main>'
        from C:/Ruby/Ruby25-x64/lib/ruby/gems/2.5.0/gems/docile-1.3.1/lib/docile/execution.rb:26:in `instance_exec'
        from C:/Ruby/Ruby25-x64/lib/ruby/gems/2.5.0/gems/docile-1.3.1/lib/docile/execution.rb:26:in `exec_in_proxy_context'
        from C:/Ruby/Ruby25-x64/lib/ruby/gems/2.5.0/gems/docile-1.3.1/lib/docile.rb:43:in `dsl_eval'

Use docile with root class declaration

Hi. Thanks for all your work!

I am the maintainer of https://github.com/avo-hq/avo. Avo is an admin panel framework where you can build apps very fast! It achieves that through an extendable and flexible DSL.

This is just a sample. The result of this you can visit here.

class PostResource < Avo::BaseResource
  field :id, as: :id
  field :name, as: :text, required: true, sortable: true
  field :body, as: :trix, placeholder: "Enter text", always_show: false, attachment_key: :attachments, hide_attachment_url: true, hide_attachment_filename: true, hide_attachment_filesize: true
  field :cover_photo, as: :file, is_image: true, as_avatar: :rounded, full_width: true, hide_on: []
  field :cover_photo, as: :external_image, name: "Cover photo", required: true, hide_on: :all, link_to_resource: true, as_avatar: :rounded, format_using: ->(value) { value.present? ? value&.url : nil }
  field :audio, as: :file, is_audio: true
  field :excerpt, as: :text, hide_on: :all, as_description: true do |model|
    ActionView::Base.full_sanitizer.sanitize(model.body).truncate 130
  rescue
    ""
  end

  field :is_featured, as: :boolean, visible: ->(resource:) { context[:user].is_admin? }
  field :is_published, as: :boolean do |model|
    model.published_at.present?
  end
  field :user, as: :belongs_to, placeholder: "โ€”"
  field :status, as: :select, enum: ::Post.statuses, display_value: false
  field :comments, as: :has_many

  filter PostStatusFilter

  action TogglePublished
  
  tool PostInfo
end

I'd like to change the way we build the DSL. At the moment we use static methods to get the fields and build the final object.
Now, we're introducing wrappers like tab or panel.

class PostResource < Avo::BaseResource
  panel "Main info" do
    field :name, as: :text, required: true, sortable: true
    field :body, as: :trix, placeholder: "Enter text", always_show: false, attachment_key: :attachments, hide_attachment_url: true, hide_attachment_filename: true, hide_attachment_filesize: true
  end

  tab "Files" do
    field :cover_photo, as: :file, is_image: true, as_avatar: :rounded, full_width: true, hide_on: []
    field :audio, as: :file, is_audio: true
  end
end

I know that you usually have to give docile a block with the DSL, but is there a way to use docile and pick up the fields from the resource root class like above?

Thank you!

Question: Why the nested proxies?

Hey, I was just looking over the code base here and I was pleasantly surprised at how small and easy to understand it is. There is one thing though that I'm a bit confused about.

On this line, you set the proxy context to a proxy of a proxy. Why is that? Why not just proxy the block context directly?

Question about use of DSL object's private method

Hi @ms-ati ,

I have a question about use of DSL object's private method.

I tried to call DLS object's private methods via Docile.dsl_eval but I got NoMethodError.
Here is a small script to reproduce this problem.

require 'docile'
class Foo
  private
  def foo; end
end
Docile.dsl_eval(Foo.new) { foo } # => NoMethodError (undefined method `foo' for main:Object)

Is this correct behavior?
If you think that DSL methods should be public then I think this is correct behavior.
If you think that Docile.dsl_eval should behave like #instance_eval then I think this problem should be resolved.

Bug: Docile 1.3 breaks cfer

See how this PR to bump Docile to 1.3.2 in the cfer project breaks its specs:

https://travis-ci.org/seanedwards/cfer/builds/601409476

RuntimeError:
  Expected a value or block when setting property DocileUndoFallback
# ./lib/cfer/block.rb:93:in `method_missing'
# /home/travis/.rvm/gems/ruby-2.5.5/gems/docile-1.3.2/lib/docile/fallback_context_proxy.rb:87:in `method_missing'
# /home/travis/.rvm/gems/ruby-2.5.5/gems/docile-1.3.2/lib/docile/execution.rb:29:in `exec_in_proxy_context'
# /home/travis/.rvm/gems/ruby-2.5.5/gems/docile-1.3.2/lib/docile.rb:43:in `dsl_eval'
# ./lib/cfer/block.rb:12:in `build_from_block'
# ./lib/cferext/aws/iam/policy_generator.rb:15:in `statement'
# ./lib/cferext/aws/iam/policy_generator.rb:20:in `allow'
# /home/travis/.rvm/gems/ruby-2.5.5/gems/docile-1.3.2/lib/docile/fallback_context_proxy.rb:87:in `method_missing'
# ./lib/cferext/aws/iam/policy_generator.rb:54:in `block in <module:IAM>'
# /home/travis/.rvm/gems/ruby-2.5.5/gems/docile-1.3.2/lib/docile/execution.rb:26:in `instance_exec'
# /home/travis/.rvm/gems/ruby-2.5.5/gems/docile-1.3.2/lib/docile/execution.rb:26:in `exec_in_proxy_context'
# /home/travis/.rvm/gems/ruby-2.5.5/gems/docile-1.3.2/lib/docile.rb:43:in `dsl_eval'
# ./lib/cfer/block.rb:12:in `build_from_block'
# ./lib/cferext/aws/iam/policy_generator.rb:48:in `generate_policy'
# ./lib/cferext/aws/iam/policy_generator.rb:53:in `<module:IAM>'
# ./lib/cferext/aws/iam/policy_generator.rb:5:in `<module:AWS>'
# ./lib/cferext/aws/iam/policy_generator.rb:4:in `<module:CferExt>'
# ./lib/cferext/aws/iam/policy_generator.rb:3:in `<top (required)>'
# ./lib/cferext/aws/iam/policy.rb:1:in `require'
# ./lib/cferext/aws/iam/policy.rb:1:in `<top (required)>'
# ./lib/cfer.rb:368:in `require'
# ./lib/cfer.rb:368:in `block in <top (required)>'
# ./lib/cfer.rb:368:in `each'
# ./lib/cfer.rb:368:in `<top (required)>'
# ./spec/spec_helper.rb:64:in `require'
# ./spec/spec_helper.rb:64:in `<top (required)>'
# ./spec/cfer_spec.rb:1:in `require'
# ./spec/cfer_spec.rb:1:in `<top (required)>'

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.