Symfony2 DevelopmentBundle

I am working on a custom development Command classes that I plan to put up as a bundle.

Initially the idea is to automate the repetitive time consuming and forgetful moments that go by when working on a sf2 project. So far I have created this command so one can use it like this:

php app/console git:c1 --message="your commit message [completed: 343]" --branch="ClosingTickets"

Instead of this:

git add . && git commit -m "your commit message [completed: 343]" && git push origin ClosingTickets

Or a more longer process which is the whole idea like this:

php app/console git:c2 --message="your commit message [completed: 343]" --branch="ClosingTickets" --new="NextSprint"

Instead of typing to die some flow commands:

git add .
git commit -m "your commit message [completed: 343]"
git checkout master
git pull origin master
git merge ClosingTickets
git push origin master
git checkout -b NextSprint

I have also explored a way to attach some pre-commit hooks like it is done here for formatting code before committing however the formatter code that I like it is not available on the CLI. Perhaps I should use this one provided. But just waiting for the response. Again as I said earlier, the idea is to automate some tasks to save us work. So for instance using pre-commit or post-commit hooks could be a low level automation, whereas sf2 custom commands could be another level of automation. The disadvantage of the pre-commit hook is that it is not as portable and requires work to set it up. The sf2 approach needs some setup now but perhaps less in the future, and if we gather several custom commands on sf2 then we can just use it as a bundle readily available to any project. We want to automate long processes so we can further get analytic-like by products. For instance we could consider developing some commands to use tools to instruct or set some tasks to be run upon demand on a jenkins server or simliar :D!

If you have any ideas please provide them into the comments as they will be helpful into developing more functionality into this already working set of commands. Also I am not sure what git/sf2 flow is best for sf2 development so if you have any ideas please comment below. Thanks!

Some links that I ran into when researching this topic:

Logrotate Symfony 2 Monolog Logs

I did take a look at logrotate and seems feasible. I wonder if we should create a bundle to include commands to set the /etc/logrotate.d/sf2log file with the required specification like :

/home/cordoval/sites-2/project1/app/logs/dev.log {
        rotate 4

and another command option to run the

$ logrotate /etc/logrotate.conf

I was even thinking on something like:

watch logrotate /etc/logrotate.conf

for hourly rotation or shorter periods of time

this could perhaps be easily embedded into:

php app/console monolog:streamhandler:create --e=dev --interval=2 --path=default
php app/console monolog:streamhandler:watchrotate --e=dev

In order to navigate inside the log files one can use the multitail command described here.

Here there is a copy of the key bindings for multitail:

One can press the following keys:
q     quit the program
F1    this help
/     search in all windows
shift + /  highlight in all windows
b     scroll back
B     scroll back in ALL windows merged into
      one window
I     toggle case sensitivity for searches
a     add a new window or add another file/
      program to an existing window
d     delete a window (or a file/program from a
s     swap the location of 2 windows
e     enter/edit regular expressions
f     enter/edit in line filter regexps
c     set/change colors (only works if your
      terminal supports colors)
C     edit the r/g/b components of a color
b     scrollback in the buffer of a window
v     toggle vertical split
0...9 set a mark in a window so that you can
      easily see what has changed since the last
      time you looked
R     restart a window
ctrl + v  select conversion scheme(s)
ctrl + t  toggle subwindow before lines
Y     send a signal to a window (for commands)
y     set linewrap
o     wipe (clear) a window
O     wipe all windows
T     truncate a logfile
g     make screendump
r     redraw screen
I     toggle case sensitivity for searches
l     list keybindings
i     info
t     statistics
j     set window sizes
z     hide/unhide a window
u     hide all windows but the one selected
U     unhide all windows
w     write a script which starts multitail
      with the current settings (the files that
      are monitored, regular expressions, etc.)
n     clear the buffer of a window
N     clear all buffers of all windows
m     set the size of a buffer
k     enter a (limited) terminal-mode
p     pause all windows
P     (un-)pause one window

In my opinion learning to use multitail is a better option than leaning to do this since we don’t know the line numbers.

Behat + Symfony 2 Secret: How To Subcontext MinkContext

Update: Check comments for solution. Thanks everzet.

Behat is a scenario framework. It means that you can describe scenarios for the interaction between user and the browser and use those as your acceptance criteria. A scenario is basically a telling of what is to happen (then), in which circumstances it is going to happen (given), and what is causing the thing that is going to happen (when).

Put it the other way around, in each scenario, and there can be as many as needed, there is a set of steps to be taken for setting things up (given), for acting things that cause things to happen (when), and for describing things that should happen (then).

Each scenario comprises several steps that are described in a human like language. The specification can then be run without a problem, however, there is no way to make the web application at hand what the words of a step mean unless they are tied to the browser on which the web application is running. The link between browser and human like language steps is called a step definition, step description, or is also called step contextualization. It contextualize the human steps by interpreting the human like language steps and determining the manner in which they are run into code that controls a browser client driver.

Behat allows to have multiple ways of interpreting steps. These ways or manners of interpreting are called contexts. So contexts hold rules for interpretation or also called step definitions. In order to set all the interpretation rules straight Behat allows for organization contextualizing and grouping certain rules for certain contexts and using them when needed.

The use case for multiple contextualization can be seen this way. Imagine an app that reacts differently for different type of users. Say the app behavior is similar to all, but the interaction is different. Some users like to do a lot of clicks on some things a certain way, using links a certain way, reset their password, or contact support through specific channels or even chat a certain way. Even more simple, imagine that a user uses the accessibility features of a site for blind users and the regular user use the regular features of a site for people that can see. These are two different contexts. A step can be for instance: “When I login”. Both user blind and no blind will login eventually. However, the interpretation of the same step will take different routes. One will touch the screen or type whereas perhaps the other will speak up or trigger some actions that end up in the same action, that is log in.

Mink comes with a context of its own premade and home cooked. Moreover Behat allows us to use multiple contexts as subcontexts from a top root FeatureContext file. This post is about showing how to make use of subcontexts and how to instantiate MinkContext as one of those subcontexts we can use.

So in our FeatureContext class we have the following:

class FeatureContext extends BehatContext
    public function __construct(array $parameters) {
        $this->useContext('clicking', new ClickingContext($parameters));
        $this->useContext('dropoff', new DropoffContext($parameters));
        $this->useContext('mink', new MyMinkContext());

And we create a MyMinkContext class like:

class MyMinkContext extends MinkContext{
 // your step definitions here

Notice we are extending our homemade class from MinkContext. And we are using it as subcontext since we aliased it to ‘mink’ above. The usage of how to get to methods/steps defined in the context is shown elsewhere in other posts of this site and on the Behat documentation.

The idea shown here is that the organization for contexts and subcontexts fosters horizonal reusability before we get traits on php5.4. What this means in terms of application development? It means that one can organize contexts and run multiple context-based scenarios, do comparisons for certain usage cases through different patters of usage, etc.

Update: This warning is wrong.
Warning: It is important for reason of updating that you use Behat classes on your use clauses when coding. If you use BehatBundle or other can give you problems. So unless otherwise said, use the Behat classes.

Adapted explanation by everzet:
BehatBundle makes Behat to inject Kernel instead of parameters array into context constructor by default, whereas Behat creates context with array of context parameters.
In addition to this there is more information related to the use of methods for different contexts, especially the methods MinkContexts brings into the table. Therefore there are 3 ways of doing this:

1) add mink-related steps in MinkContext child
2) record newly created MinkContext in your FeatureContext instance variable, so you'll have access to it's methods (like getSession()) later
3) use getMainContext()->getContext('MINK_CONTEXT_ALIAS')->getSession

So here we give example of what we have been talking about implementing a nice aliasing taken from here:

namespace Acme\DemoBundle\Features\Context;
use Behat\BehatBundle\Context\BehatContext,
use Behat\Gherkin\Node\PyStringNode,
 * Feature context.
class FeatureContext extends BehatContext
     * BehatBundle's main context constructor gets
     * KernelInterface instance as single parameter
    public function __construct($kernel)
        // Instantiate and use BehatBundle's MinkContext with provided $kernel
        $this->useContext('mink', new MyMinkContext($kernel));
     * Get Mink session from MinkContext
    public function getSession($name = null)
        reutrn $this->getSubcontext('mink')->getSession($name);

And the MyMinkContextClass here:

namespace Acme\DemoBundle\Features\Context;
use Behat\BehatBundle\Context\MinkContext as BaseMinkContext,
use Behat\Gherkin\Node\PyStringNode,
 * Mink-enabled context.
class MyMinkContext extends BaseMinkContext

And here I just dump a very good explanation on all the details seen so far and problems I ran into:


If you use BehatBundle – use it’s contexts. If you don’t use BehatBundle – use Behat or Mink context as parent. Where’s the confusion???

The main difference between them is that BehatBundle’s contexts gets kernel instance injected into constructor instead of array of parameters. That’s all. BehatBundle provides extensions for both MinkContext and BehatContext which:

Gets kernel instead of array of parameters into __constructor()
Gets services out of service container (bound to kernel) instead of instantiating them by hands
Gets parameters out of service container (bound to kernel) instead of maintaining them by hands
That’s all.

So, if you use BehatBundle – extend Behat\BehatBundle\Context\BehatContext, it’ll give you access to kernel and container in child class. BUT don’t forget to provide kernel instance into it’s constructor.

Behat provides BehatContext with basic functionality
Mink provides MinkContext layer on top of the BehatContext functionality
BehatBundle overrides both BehatContext and MinkContext with kernel, container and services knowledge, so you can talk with your Symfony2 app through them
Also, in counterpart with Behat\BehatBundle\Context\BehatContext, which does nothing except defining some helper methods, Behat\BehatBundle\Context\MinkContext describes step definitions and hooks, needed for Mink. And as you remember – you can’t have 2 same definitions in suite. So, you can extend OR use Behat\*\Context\MinkContext only once!

Hope you have enjoyed this post, if you feel like so please donate. Thanks!