Commits on Aug 14, 2016
  1. @racke
  2. @racke
Commits on Aug 13, 2016
  1. @cromedome


        [ BUG FIXES ]
        * Fix memory leak in plugins. (Sawyer X)
        * GH #1180, #1220: Revert (most of) GH #1120. Change back to using
          MooX::Types::MooseLike until issues around Type::Tiny are resolved.
          Peter (@SysPete) Mottram
        * GH #1192: Decode body|query|request_parameters (Peter Mottram)
        * GH #1224: Plugins defined with :PluginKeyword attribute are now
          exported. (Yanick Champoux)
        * GH #1226: Plugins can now call the DSL of the app via $self->dsl
          (Sawyer X)
        [ ENHANCEMENTS ]
        * PR #1223: Add YAML::XS to Recommends (Peter Mottram)
        * PR #1117: If installed, use HTTP::XSCookies and all cookie operations
          will be faster (Peter Mottram)
        * PR #1228: Allow register_plugin() to pass @_ properly (Sawyer X)
        * PR #1231: Plugins can now call the syntax of plugins they loaded
          (Sawyer X)
        * PR #1151: Note that config is immutable after first read (Peter Mottram)
        * PR #1222: Update list of files generated by `dancer2 -a`, make name of
          sample app consistent (Daniel Perrett)
    cromedome committed Aug 13, 2016
  2. @cromedome

    Merge branch 'fix/gh-1230'

    cromedome committed Aug 13, 2016
  3. @cromedome

    reflect changes

    cromedome committed Aug 13, 2016
  4. @cromedome

    Add documentation for how Plugin2 changes work.

    Documented the following three behaviors:
    * How plugins use app DSL with $self->dsl
    * Demonstrate how plugins can use other plugins
    * Explain how hooks are added when a plugin uses another plugin
    cromedome committed Aug 13, 2016
Commits on Aug 12, 2016
  1. @xsawyerx @cromedome

    Safer version:

    Instead of assuming that if a "dsl" method is available than a
    "app" method is available, we're "eval"ing both calls at once.
    xsawyerx committed with cromedome Aug 10, 2016
  2. @xsawyerx @cromedome

    Allow import of plugins' DSL into other plugins (and more):

    The reason plugins calling DSL on other plugins doesn't work
    is because we explicitly only allow importing plugins DSL
    from applications.
    The way we verify this is by trying to call "app" attribute
    on the consuming class. Plugins don't have this. The change
    I made here is to check if "->dsl->app" is also available,
    which is available in plugins.
    This fixed GH #1230.
    xsawyerx committed with cromedome Aug 10, 2016
  3. @xsawyerx @cromedome

    Tests for GH #1230:

    This test show-cases the problem (and my offered solution to it)
    of having plugins loading other plugins and getting their DSL
    It creates an app (and to make it more fun, it sets the appname
    to a class that doesn't exist) and two plugins. The first loads
    the second. They both provide DSL keywords.
    It then tries to use the inner plugin's keyword in either the
    app, the appname class, or the plugin itself, hoping that it will
    work in the plugin itself - which fails right now.
    xsawyerx committed with cromedome Aug 10, 2016
  4. @cromedome

    Merge branch 'fix/gh-1226'

    cromedome committed Aug 12, 2016
  5. @cromedome

    reflect changes

    cromedome committed Aug 12, 2016
  6. @xsawyerx @cromedome

    Do not require plugins loaded from apps:

    Once I moved the creation of the "dsl" method on the consumer
    class, some tests failed. Thanks, SysPete for pointing that to me!
    The tests failed because they loaded plugins outside Dancer Apps.
    The code that created the "dsl" method could not find it in the
    caller tree because there was no Dancer App that could implement
    "dsl". It croaked.
    Instead, I made this optional. If you load a plugin from inside an
    App, the plugin will get the "dsl" method leading to the App DSL.
    However, now if you load a plugin outside an App, it just doesn't
    do that.
    There is one case in which we demand that there is an App, and
    that is when someone registers a plugin using the backwards compat
    layer DSL keyword "register_plugin". In that case, you definitely
    MUST be inside the scope of an App.
    Thanks again, SysPete!
    xsawyerx committed with cromedome Aug 9, 2016
  7. @xsawyerx @cromedome

    Make it work on proper D2P2 syntax:

    New Dancer2 plugins should not call register_plugin(). It's only
    a shim layer for previous architecture structure.
    The solution I wrote used register_plugin() to do the work. Now
    it does it when imported.
    xsawyerx committed with cromedome Aug 9, 2016
  8. @xsawyerx @cromedome

    Remove redefined warning

    xsawyerx committed with cromedome Aug 8, 2016
  9. @xsawyerx @cromedome

    Provide "dsl" method to access the DSL object:

    At first I thought of bridging the gap by allowing the plugin to access
    the consumer class. The problem is that 1. It's an implementation
    detail which does not make the plugin syntax nicer at all, and 2. I
    couldn't figure out how to do that. :)
    Instead, knowing I have the DSL class, I add a method to the plugins
    to allow access to the DSL object. This allows any method to call
    the DSL methods directly.
        package Dancer2::Plugin::MyPlugin;
        use Dancer2::Plugin;
        sub my_thing {
            my $self = shift;
            # define a new GET route with the DSL methods:
            $self->dsl->get( '/' => sub {...} );
    xsawyerx committed with cromedome Aug 8, 2016
  10. @xsawyerx @cromedome

    Refactor consumer finding functions:

    For clarity, I'm separating this chunk to explain what it does
    better. It seeks in the caller tree the DSL. It finds a callback
    which, when called, will return the DSL object.
    xsawyerx committed with cromedome Aug 8, 2016
  11. @xsawyerx @cromedome

    Add tests for GH #1266:

    This test is fairly simple and exemplifies what happens when we
    don't distinct between caller class and consumer class.
    First, what we have in the test:
    This is a Dancer2 App. It sets the "appname" to "OtherApp". It
    then loads another Dancer2 App: App::Extra.
    OtherApp is not a package which exists and that adds another
    element in this, explained below.
    * App::Extra
    Another Dancer2 App which sets "appname" to "OtherApp" as well.
    It defines a single route which sets the status to 500, and then
    loads a plugin which should change it to 200.
    * Dancer2::Plugin::Test::AccessDSL
    A simple plugin which will verify the different classes
    (consumer, caller) and will try to change the status by calling
    the DSL itself. The "dsl" method does not even exist at this point,
    so it fails.
    From the plugin's perspective (where we want to call "status"), the
    caller class is the plugin class: Dancer2::Plugin::Test::AccessDSL. The
    caller does not have the DSL keywords. We know this and it's a
    limitation we agreed to live with: Plugins will not call DSL keywords.
    They can't.
    The "appname", from everyone's perspective is "OtherApp". This package
    does not exist, so you cannot call "OtherApp->status", because it is
    not a class that exists.
    The consumer class is App::Extra (which calls on Dancer2, adding the
    DSL to it, making it the consumer. The test shows this part does indeed
    The problem is that the caller class and consumer class are not the
    same, and they are not the same as the "appname". Because of this, they
    cannot call any methods even through the "appname". If the "appname"
    had been the same as the caller class (as in, we wouldn't use the
    "appname" to rename the app, or if that was an actual package that
    existed), it probably would have worked. I have not tested this.
    xsawyerx committed with cromedome Aug 8, 2016
  12. @cromedome
  13. @cromedome

    reflect changes

    cromedome committed Aug 12, 2016
  14. @yanick @cromedome
  15. @yanick @cromedome

    Bring the dealing with sub attributes in the BEGIN stage

    without that, the subroutines tagged by :PluginKeyword
    are not being caught in time to be exported with the rest
    Fixes #1224
    yanick committed with cromedome Aug 9, 2016
  16. @cromedome
  17. @cromedome

    reflect changes

    cromedome committed Aug 12, 2016
  18. @xsawyerx @cromedome

    Allow register_plugin() to pass @_ properly:

    This is inside an eval block, so I think it needs to be escaped
    so it would be used as a literal.
    Can someone approve this for me?
    xsawyerx committed with cromedome Aug 8, 2016
  19. @cromedome
  20. @cromedome

    reflect changes

    cromedome committed Aug 12, 2016
  21. @xsawyerx @cromedome

    Clean up tests:

    The benchmark had wrong titles. I also split up the bake vs. the
    crush. It's just easier for me to read it that way.
    xsawyerx committed with cromedome Apr 7, 2016
  22. @SysPete @cromedome
  23. @SysPete @cromedome

    Dancer::Test must push Cookie set in request_from_env back into $ENV

    Dancer2::Core::Request now uses cookies method from Plack::Request to
    crush cookies, when HTTP::XSCookies is not available, which
    relies on cookies being found in $self->env->{HTTP_COOKIE} rather than
    $self->header('Cookie'). This works fine for a real PSGI request where
    the HTTP_COOKIE environment variable will be set correctly but fails
    when Dancer::Test dancer_response is called like so:
       dancer_response( GET => '/headers',
                headers => [
                    [ 'X-Sent-By' => $sent_by ],
                    [ 'Cookie' => "foo=bar" ],
    Simplest fix is a small hack to Dancer2::Test to push any Cookie header
    back into the HTTP_COOKIE environment var. I don't want to put a nasty
    hack into core for a deprecated test module.
    SysPete committed with cromedome Feb 2, 2016
  24. @SysPete @cromedome

    select crush_cookie flavour during complile of Core::Cookie

    Use a BEGIN block to set the pp/xs flavour of to_header method during
    compile instead of on every call of the to_header method. Not having
    branch selection on each call saves a tiny amount of cpu.
    SysPete committed with cromedome Feb 1, 2016
  25. @SysPete @cromedome
  26. @SysPete @cromedome

    Use HTTP::XSCookies in Core::Cookie if available.

    - Capitalise all cookie field names when using pure-Perl baker as per
      RFC6265. HTTP::XSCookies does the same.
    - Run cookies.t tests against pure-Perl and HTTP::XSCookies code paths
    SysPete committed with cromedome Jan 31, 2016
  27. @SysPete @cromedome

    Optional use of HTTP::XSCookies in Core::Request

    If available use XSCookies to crush cookies else use Plack::Request.
    Once crushed via either method cookies still have to be converted to
    Cookie objects.
    Both crushers discard malformed cookies which have no value so alter
    tests to revert part of commit c2b7bd8.
    SysPete committed with cromedome Jan 31, 2016
  28. @SysPete @cromedome
  29. @cromedome