update TODO, next planned steps
[catagits/Catalyst-Runtime.git] / TODO
1 # Known Bugs:
2
3    - Bug ->go or ->visit causes actions which have Args or CaptureArgs called
4      twice when called via ->go or ->visit.
5
6      Test app: http://github.com/bobtfish/catalyst-app-bug-go_chain/tree/master
7
8 # Compatibility warnings to add:
9
10   - $self->config should warn as config should only ever be called as a
11     class method (TESTS).
12
13 # Proposed functionality / feature additions:
14
15 ## Log setup needs to be less lame
16
17 So Catalyst::Plugin::Log::* can die
18 in a fire. Having $c->log_class would be a good start. kane volunteered
19 to do some of this.
20
21 Simple example: Catalyst::Plugin::Log::Colorful should just be a
22 subclass of Catalyst::Log, no ::Plugin:: needed.
23
24 See also: Catalyst::Plugin::Log::Dispatch and
25 http://github.com/willert/catalyst-plugin-log4perl-simple/tree
26
27 # REFACTORING
28
29 ##  The horrible hack for plugin setup - replacing it:
30
31  * Have a look at the Devel::REPL BEFORE_PLUGIN stuff
32    I wonder if what we need is that combined with plugins-as-roles
33
34 ## App / ctx split:
35
36   NOTE - these are notes that t0m thought up after doing back compat for
37          catalyst_component_class, may be inaccurate, wrong or missing things
38          bug mst (at least) to correct before trying more than the first 2
39          steps. Please knock yourself out on the first two however :)
40
41   - Eliminate actions in MyApp from the main test suite
42   - Uncomment warning in C::C::register_action_methods, add tests it works
43     by mocking out the logging..
44   - Remove MyApp @ISA controller (ask metaclass if it has attributes, and if
45                                   so you need back compat :/)
46   - Make Catalyst::Context, move the per request stuff in there, handles from
47     main app class to delegate
48   - Make an instance of the app class which is a global variable
49   - Make new instance of the context class, not the app class per-request
50   - Remove the components as class data, move to instance data on the app
51     class (you probably have to do this for _all_ the class data, good luck!)
52   - Make it possible for users to spin up different instances of the app class
53     (with different config etc each)
54   - Profit! (Things like changing the complete app config per vhost, i.e.
55     writing a config loader / app class role which dispatches per vhost to
56     differently configured apps is piss easy)
57
58 ## GSOC
59
60 ### Next steps - planned:
61
62   - Test custom container
63     - writing some tests which verify that the models you think should be
64       there are there, and that they received their dependencies as arguments
65     - i.e. Model::Bar should get params { foo => $model_foo } when being
66       constructed, etc
67     - Need to test that if you have a standard component Frotz
68       and a customized component Fnar, and Fnar depends on Frotz
69     - And yeah, some tests that the customised components actually work via
70       $c->model('Foo'), and that COMPONENT is called (or not called)
71       as appropiate and that ACCEPT_CONTEXT is called (or not) as appropriate
72
73   - Kill flush_request_services
74     - we're already passing $ctx in when we locate services so the ::Request
75       lifecycle can just stash the object in, or retrieve the object from the
76       stash
77
78 ### Next steps - less planned:
79
80   - Creating service()-like sugar for component
81
82   - Test cases for extending the container in an application.
83     - Using the sugar added in the previous item
84     - Test when Model::Foo depends_on Model::Bar
85     - Test for component Foo => ( lifecycle => 'Singleton', class => 'My::External::Class', dependencies => { config => depends_on("config") } )
86     - Fix ^^ so that you can get your component's namespaced config nicely.
87
88   - Tests for using the container outside of Catalyst
89     - Custom container which adds some (very simple) services which are initialized from
90       the application config file (note plain services, not components)
91     - Depend on (and test) these inside Catalyst
92     - Test loading container outside Catalyst, and these services working
93     - Test Catalyst / MyApp is not loaded
94
95 #### Extending my app, notes
96
97 Basically try to implement something like this (starting out without the sugar!), and see how it breaks
98 and what needs to be done to fix it!
99
100 ##### Eventual syntax
101
102 package MyApp::Container;
103 use Catalyst::IOC;
104     
105     container $self, as {
106             container model => as {
107                 component Foo => (); # As per default!
108                 component Bar => (dependencies => ['/model/Foo']); # Magic!
109                 component Baz => ( lifecycle => 'InstancePerContext );
110                 component Quux => ( lifecycle => 'Singleton' ); # ACCEPT_CONTEXT not called
111                 # Catalyst::Model::Adaptor example
112                 conponent Fnar => ( lifecycle => 'Singleton', class => 'My::External::Class', dependencies => { config => depends_on('config')} );
113                 #                                                                                               ^^ FIXME - gets whole config, not Model::Foo
114                 #                                                                                                  There should be a 'nice' way to get the 'standard' config
115             };                    
116             # Note - implementation of BB may need to be changed to support making sure existing 
117             # services actually get overridden. not sure how the default container behaves when doing that
118             # above code would build the constructor injection as it currently does,
119             # defaulting to the class name in the right namespace as declared by the surrounding container
120             # as well as adding using the catalyst-specific service class
121     };
122
123 1;
124
125 ##### To start with
126
127 package MyApp::Container;
128 use Moose;
129
130 extends 'Catalyst::Container;
131
132 after BUILD => sub {
133     my $self = shift;
134     my $model_container = $self->get_sub_container('model');
135     my $service = Catalyst::IOC::ConstructorInjection->new(
136         name      => 'Baz',
137         class     => 'MyApp::Model::Baz',
138         dependencies => [
139             depends_on( '/application_name' ),
140             depends_on( '/config' ),
141             depends_on( '/model/Foo' ),
142         ],
143         lifecycle => 'InstancePerContext',
144     );
145     $model_container->add_service( 'Foo', $service );
146 };
147
148 ### To polish off / t0m review
149
150     locate_components service vs setup_components method
151       - can we be more lazy?
152       - should setup_components be a service that things like the ->component lookup
153         can depend on?
154
155     -    my $accept_context_args = $self->param('accept_context_args');
156     +    my $accept_context_args = $params{accept_context_args};
157     ^^ This (may be) wrong! I am thinking the service should be allowed to mangle the 
158        accept_context args, no?
159        Without this change, the user could make a custom service which mangled the param, and use 
160        Catalyst/IOC/Service/WithAcceptContext.pm, with this change, that module will always see the
161        un-mangled version?? However, without this change, shit doesn't work...
162
163 ### Known issues
164
165     - Broken $instance->expand_modules() in setup_components and figure
166       out later how to bring it back
167
168     - expand_component_module
169
170     - People wrapping locate_components in Catalyst.pm