Mirmo Dynamics

To content | To menu | To search

Quick and dirty getpass implementation in bash

How to ask for a password from within bash:

function getpass() {
  stty -echo
  read -p "$1" $2 ; echo
  stty echo
}

Usage:

getpass "Your Prompt: " PASSWORD
echo $PASSWORD

De qui se moque-t'on ?

Derrière ce titre un peu faible, se cache un billet qui va, potentiellement, changer votre vie. Pour autant que vous écriviez des tests unitaires (mais tout le monde fait ça ici non ?). En effet, je vais vous parler d’un truc génial: Mockery. Mockery, c’est un framework de Mock (il parait qu’on dit Bouchon en français, mais c’est vraiment trop ridicule), écrit par Pádraic Brady, qui fait partie de la core team du Zend Framework. Du lourd quoi.

Bon, mais d’abord, pour les nouveaux, qu’est-ce donc qu’un Mock ? Je ne saurais mieux l’expliquer que Padraic dans son superbe blogpost, mais pour les pressés, on va faire une version courte. Un mock est un remplacement d’objet pour isoler un test. Par exemple, on peut créer des mocks de base de données pour éviter d’instancier tout Propel a chaque test. Voilà, ça c’est pour la théorie.

Toujours pas clair ? Un petit exemple alors. Tout à l’heure j’ai écris des tests (disons pour une classe qui s’appellerait Foobar). C’est une super classe, qui fait son job, pas de problème, mais qui demande en constructeur 2 objets: un Foo et un Bar. Disons que Foo et Bar coûtent un peu cher à instancier. J’ai donc 2 choix: instancier des vrais objets (c’est mal, mais c’est qu’on fait en général), ou utiliser des mocks (c’est bien, mais on le fait pas parcequ’on a la flemme d’écrire les mocks). Qu’à cela ne tienne, avec Mockery, c’est fait en 2 coups de cuiler a pot:


$foo = Mockery::mock('Foo', array('getCreatedAt' => date('Y-m-d H:i:s'));
$bar = Mockery::mock('Bar', array(
'getIsSaved' => true,
'getTitle' => 'recherche titre',
'getDescription' => 'recherche description',
'getIsPublic'=> true ));
$object = new Foobar($foo, bar);

Donc ça c’est la forme un peu « rapide » de création de mock. Pour chaque méthode que je spécifie dans l’array d’options, mockery assigne en valeur de retour la valeur en face. Donc $recherche->getTite() renverra « recherche titre » par exemple. C’est cool non ? Bien sur on peut aller super loin avec Mockery, comme par exemple dire « la méthode tartenpion de l’objet pmsipilotUser doit etre appelé avec en paramètre perlinpinpin et renvoyer un objet MerlinLenchanteur et ne doit être utilisée qu’une fois sinon la terre explose »:


$merlin = new MerlinLenchanteur();
$user = Mockery::mock('pmsipilotUser');
$user->shouldReceive('tartenpion')->with('perlinpinpin')->once()->andReturn($merlin);

(ok je triche encore un peu on ne peut pas vraiment faire exploser la terre)

Par contre si on veut vérifier que tout a bien été appelé comme on l’a défini, il ne faut pas oublier de le dire a la fin: Mockery::close(); Un dernier exemple pour vous convaincre de la puissance de Mockery. On rencontre souvent du code qui viole la Loi de Demeter, et qui de fait devient difficile à tester. Point de chichi avec Mockery, car il permet aussi de Mocker une chaine d’appels complète très simplement: 

$mock = Mockery::mock('demeter'); $mock->shouldReceive('foo->bar->quux->roflpwn->demeter')->andReturn('omgponies');

Magique non ? Pour encore plus de trucs magiques, je vous invite à lire la doc sur la page github de mockery. Voilà j’espère que ça vous aura donné envie d’utiliser un peu plus de Mocks dans vos tests :-)

A la découverte de la SPL: SplFileObject

Note: ce post est une cross-post d'un article que j'ai posté sur le blog technique de mon employeur (PMSIpilot)

La SPL, ou Standard PHP Library, est un ensemble de classes disponibles dans PHP qui regroupe bon nombre de fonctionnalités fort utiles, mais souvent méconnues. Prenons par exemple aujourd'hui SplFileObject. Cette classe facilite l'itération sur le contenu d'un fichier en mettant à notre disposition un... itérateur (dingue ça).

Exemple: disons qu'on a un fichier /tmp/foobar.csv avec le contenu suivant:
foo;bar
baz;quux
Nous pouvons simplement parcourir les lignes avec le code suivant:
<?php

$file = new SplFileObject('/tmp/foobar.csv');

foreach($file as $line)
{
$data = explode(';', $line);
}
C'est pas mal non ?

On pourra arguer qu'on arrive au même genre de résultat en utilisant file, mais l'empreinte mémoire est loin d'être la même (sans compter l'approche object de SplFileObject qui va nous permettre plus tard de faire des trucs rigolos).

Mais il y a encore mieux. SplFileObject gère le format CSV, de deux manières différentes. Vous pouvez au choix utiliser SplFileObject#fgetcsv ou bien (pour garder une API cohérente) expliquer à SplFileObject que le fichier que vous traitez est un CSV. Attardons nous sur cette dernière méthode (toujours avec le même /tmp/foobar.csv):
<?php

$file = new SplFileObject('/tmp/foobar.csv');
$file->setFlags(SplFileObject::READ_CSV);
$file->setCsvControl(';');

foreach($file as $data)
{
var_dump($data);
}
Magique !

Vous pouvez bien évidemment (comme on le disait plus haut) surclasser SplFileObject pour lui ajouter tout un tas de trucs rigolos (par exemple chez nous on détecte les BOM, et on configure automatiquement les fichiers CSV).

Bien sur, SplFileObject permet bien d'autres choses, quasiment tout ce que vous pouvez faire avec les fonctions utilisant un handler fopen est disponible (à quelques exceptions près, comme par exemple fread) (globalement c'est assez orienté lecture ligne par ligne).

Just back from Prague

I'm back from a one week vacation in Prague, and god it was fun. A pint of beer is at most 2 EUR over there, can you imagine that? (mostly asking french people here, since a pint is more like 7/8 EUR in Paris).

The city itself is nice, although I'm not sure I'm going to re-visit it anytime soon. There are lots of churches, beautiful east-styled chuches, then you get to visit the jewish district, with synagogas, the cemetery, etc. Then more churches. The Prague is castle is nice too. And some more churches. In all honesty, I liked the city, but nothing fancy here.

People from Prague are very nice, contact is easy, and the speak a very good english (as opposed to japanese people for example). The cheap alcohol seems to ease the contact too (it's the first time I actually had a conversation in the toilets).

So globally, it was a very good week :-) Now to get back with productivity, I have a lot of work to do on Springbok, mostly about mongo stuff and all, but that's another story that I'm going to tell later!

Leaving Sensio Labs, moving to Lyon

Last monday was my last day at Sensio Labs, and next saturday will be my last day in Paris. I'm moving to Lyon, and will be working as a symfony developer for a software editing company.

This will be a huge change in my life, a change that I was looking forward eagerly.

Symfony Live 2010, now what ?

Yesterday was the second and last day of the Symfony Live's conferences (I'm not counting the trainings).

So what was it all about ? Great talks were given, announcements were made (Nils Aderman, phpbb's lead developer suggested phpbb4 would run on top of Symfony 2), and most important (as as I'm concerned), great people were met. It's been a real pleasure to put a face on names like @denderello, @skoop, @webmozart, and frenchier people like @vjousse, @timbarray or @nsilberman. It's also been very interesting to meet people that I didn't previously know, of course!

From a personnal point of view, I've learnt a lot this year. This was my very first english-spoken presentation (I've already given a talk last year but it was in french), and I was a bit nervous to say the least. So basically, I kind of screwed my talk. I also learnt that a talk requires a lot of preparation, much more than I had put in this one actually, that's another reason why this talk was not as good as expected by several attendees. Anyway, I'm now aware of these flaws, and I'm going to work hard for my next talk :-)

The culminating point of the event was, of course, the revelation of Symfony 2's preview release. Symfony 2 is going to be awesome, really, and if you don't believe me, just go check the official website or Fabien's presentation. And if you're still not convinced, well, too bad for you :-) (you can also try it, it's all available on github.

What is really awesome about Symfony 2 is how it borrows concepts from other frameworks and kindly adapts them to PHP. The bundle system for example, while not exactly a new concept per-se (I guess Fabien got a lot of inspiration from django on this one) will totally change the way we, Symfony 2 users, will write web applications, and I'm really looking forward to see what great use people will make of the framework (more on that in another blog post).

The 2.0 resume

With the emergence of new web-based developper tools like Github and Stack Overflow. Building a concrete resume has never been so easy.

If you're French (or maybe there have been attempts as well in other countries but I've not heard of them), and working in IT, you must have already seen those crappy video-resume attempts, so-called 2.0 resumes meant to show off one's mastering of bleeding edge technologies. Why were those attempts miserable failures ? Apart from being ridiculous, they did not demonstrate anything. Anyone can fire up any newbie-friendly video editing software and come up with a video or flash based resume, or even build a dynamic one using PHP, python, javascript or something.

With Github for example, not only can they see the result of your work, but they can see your real work, the actual code you wrote, the project you participed in, the actual code you contributed. In a nutshell, they can truly see what you're worth (that is, technically speaking). Stack Overflow, and LinkedIn Q&A before it, etc, has the same quality. They make you go public.

In an industry where profiles and adaptability matter at least as much as pure skill, having a way to see how people work, what project they get involved in and how they behave with fellow developers is an invaluable resource for recruiters. So here's one piece of advice I'd give to any developer looking forward to being hired: work your numeric identity:

  • Answer questions on Stack Overflow and/or LinkedIn Q&A
  • Host your projects on public websites like GitHub or CIA.vc
  • Contribute to opensource projects (not only it permits you to show off your skill, but you are going to learn stuff as well)

And Don't forget to include them in your online resume through RSS/Atom feeds or direct link to your profiles!

Introducing IPS, a PHP interactive shell

It's been a while now since I first looked up for an interactive PHP shell. There quite a lot of projects in the wild, such as PHP_Shell, PHPInteractiveTerminal, iphp, phpsh, etc, but none that would actually satisfy me (either they didn't fulfill my requirements or they were only toy projects or...). Until today ! I am very pleased to announce PHPInteractiveShell, a (nearly) full-featured interactive shell for PHP.

Key features include:

  • Fault tolerant: will not die on fatal errors
  • Readline support (only history for now)
  • Multiline support: start your if on a line and finish it on another
  • Plugins support: easily extend the shell capabilities
  • Bootstrap support: easily setup an environment inside your shell
  • Config file support: easily configure your shell behavior

The whole thing is still in beta stage, so feel free to fork it, play with it and report any issue!

The symfony 2009 advent calendar: "More with symfony"

I am very pleased to relay that news: the symfony 2009 advent calendar is now available on the symfony project website:

It has been a tough work from all the people involved in this project (including me ;), and I'm really happy to see that it's finaly on the tracks :-)

New blog style

Unless you read this from an RSS aggregator, you have certainly noticed the new style on this blog, thus making this post useless (that is why I actually hope you read this through an aggregator).

Ok so this might not be the prettier blog style you've ever seen, but I kind of like it, I made it myself (actually, it's heavily inspired from readability) and it's, well, readable.

Please keep your comments for yourself, unless you really have an usability problem :-)

ps: this is also an I'm still alive post.

Symfony Pot, le mercredi 21 octobre à Paris

Discuter de symfony entre geeks autour d'une (ou plusieurs) bière(s), ça vous tente ? Alors rendez-vous le mercredi 21 octobre au Hall's Beer, un bar a bière fort sympathique à la carte des bières fort conséquente, situé d'une manière fort convenante à Chatelet les Halles, 68 rue Saint Denis très exactement (lien google map pour les fainéants). On peut aussi y manger pour ceux qui ont faim.

Début des hostilités à 19h. Venez nombreux !

PS: ceux qui viennent auront l'occasion de discuter d'un projet francophone de grande envergure autour de symfony (il y a un indice caché dans ce post).

Dynamic directory with sfValidatorFile

Say you have a form with a file upload (field image of your model for example), and that you want to save your file in a directory depending on its filename. For example, the file foobar.jpg shall be stored in fo/ob/foobar.jpg. All you have to do is implement a generateImageFilename method in your model:

  public function generateImageFilename(sfValidatedFile $file)
  {
    $filename = $file->generateFilename();
    return sprintf('%s/%s/%s', substr($filename, 0, 2), substr($filename, 1, 2), $filename);
  }

And voila !

For more information on what's happening there, see sfFormDoctrine::saveFile() (around line 510 of plugins/sfDoctrinePlugin/lib/form//sfFormDoctrine.class.php)

Help Symfony: fix one bug per day and win some gifts !

Today is the first day of the "1 day / 1 ticket" Symfony event.

Starting from today, each ticket you close (or help closing) from this list by either submitting a patch, submitting unit tests, etc will earn you points. At the end of the month, gifts are attributed to people with the most points.

This is a fun and exciting way to help your (hopefuly) favorite opensource project ;)

For more details on rules, please see the official page.

subversion, tags and externals

It's been brought to my attention today (by my fellow developper hartym) that there is a HUGE problem with tags in subversion.

The problem is very simple, when you create a tag for your project, and that your project uses svn:externals (quite a common situation), externals in the tags ARE NOT FROZEN. Which means that, if you checkout your tag at a T time, and an external gets modified at T+x, a checkout at T+x will not be the same than the one at T.

Wow.

I'm going to seriously consider switching to git.

Debriefing Symfony Live 2009

Bon ben voilà, vendredi dernier était le grand jour pour moi: ma première conférence. Que dire, sinon que les conditions n'auraient pas pu etre pires ? J'avais déjà un peu les chocopétoches, parceque perso parler en public, j'ai un peu du mal, je n'étais pas non plus entièrement satisfait des slides, mais j'imagine que c'est normal, et puis je parlais devant pas mal de personnes qui m'impressionnent un peu. Bref, autant dire que vers 8h30 (ma conf étant a 9h), je faisais pas trop le fier.

8h30, c'est l'heure à laquelle mon portable a sonné pour m'annoncer que mon co-conférencier serait à la bourre. Ok super, c'est lui qui a la dernière version des slides, c'est lui qui fait la première partie, wow, trop bien. Ni une ni deux, j'en parle à mon boss, qui décide de swapper sa conf (10h) avec la mienne. Le coeur léger (malgrès le fait que parler après mon boss, ça me foutait un peu les boules (il parle très bien)), je m'en vais décharger ma haine sur twitter.

8h58, mon boss vient me voir: écoute, les gens viennent voir symfony 2, là y'a pas tout le monde, si on leur dit a 10h quand ils vont arriver que ben désolé symfony 2 c'était à 9h finalement, ça le fait pas, donc tu vas faire ta conf. Décomposition. Mais je vais remplacer Hugo dans ta conf.

Ok. Très bien. Je vais brancher mon pc sur le rétro, obligé de rebooter sous windows pour avoir la sortie VGA qui marche (on ne ricane pas dans le fond, et oui ça doit surement marcher sous linux, mais pas trop le temps de chercher là), je ressors le vieux PDF des slides de y'a un mois, et zou, on part en petite impro. Fabien (mon boss) commence à parler, c'est chouette, ça se passe bien, jusqu'a environ une vingtaine de slide, où on se rend compte que, ben, y'a plus de slides. Gros gros moment de solitude. A partir de là, c'est freestyle complet.A mon tour de parler, la gorge désséchée, une petite tremblote de la main qui tient le micro, mais ça va, j'arrive quand meme a débiter mon petit laius, à quelques oublis près.

On finit sur la petite séance de questions, qui s'est plutot bien passé (merci à la personne qui a parlé de code coverage, c'est typiquement le truc qui était dans les slides et que j'ai oublié).

Bref, au final, je ne suis pas mort, personne ne m'as hué à la sortie, et ça me fait une expérience vraiment enrichissante du blablatage en public.

Quelques leçons que j'ai tiré de tout ça:

  • toujours, TOUJOURS, etre pret à etre laché seul dans la nature, meme si on a une confiance aveugle en son co-conférencier, on ne sait jamais ce qui peut arriver
  • NE PAS se mettre devant le rétroprojecteur, ça illumine
  • parler en public, quand on maitrise assez son sujet, c'est pas si sorcier que ça

Et surtout, ce que je retiendrais le plus: je pense que ce qui me faisait le plus peur avant la conf, c'était le public. Quand on parle en public, on peut penser avoir à défendre son steack, et le défendre contre qui ? le public. Il n'en est rien. On est meme au contraire en position de force par rapport au public, parcequ'on possède une connaissance qu'il convoite (sinon il ne serait pas là). Donc voilà, le public, ce n'est pas l'ennemi, c'est un ami qui nous veut du bien.

Dernière chose: ça me désole vraiment que la conf ce soit déroulée comme ça, et pour m'excuser, je vais publier une petite série d'articles sur les tests unitaires et fonctionnels, avec notament les exemples présents dans les slides qui n'ont pas pu etre montrés. Stay tuned.

PS: Les conférences étaient filmées, elles seront mises en lignes fin de semaine prochaine sur http://www.phptv.fr/

Quelques photos en attendant:

Speaking at Symfony Live 09

For those not following me on twitter (shame on you), I will be speaking about unit and functional testing in Symfony (with a tiny bit of continuous integration too) at Symfony Live 2009. I will not be alone since my workmate Hugo Hamon will be under the spotlights with me. Also, the talk will be given in french.

Hope to see you there :)

SQLSTATE[HY000]: General error: 1005 Can't create table '*' (errno: 150)

You may or may have not already stumbled upon this rather obscure error message (no, I'm not starting a serie on obscures error messages). Well the first thing to think when you encounter this is your foreign keys. This message generally denotes a failure in foreign keys creation, for example when the two columns you are trying to link are not of the exact same type (that is, you can't link an integer(4) to an integer(11)).

Now what if you are absolutely certain that your two columns are of the same type ? I just had the problem with this piece of doctrine schema (simplified for example purpose):

Media:
  columns:
    image:           { type: string(255), notnull: true, unique: true }

ExplorationMission:
  columns:
    probe_image:         { type: integer, notnull: true }
  relations:
    ProbeImage:          { class: Media, local: probe_image, foreign: id, onDelete: 'SET NULL' }

Can you spot the problem ?

It's rather obvious when you know it, but I spent rather some time cursing mysql in vain. The point is that there is a major logic error in this schema. it declares the probe_image as NOT NULL while it gently asks the FK to set it null on delete. See ?

Hope it saves some frustration :-)

Ajax query failing unexpectedly ?

I was gently doing some ajax black voodoo when I came upon this obscure-ish error in my firebug console:

Error: uncaught exception: [Exception... "Component returned failure code: 0x805e000a [nsIXMLHttpRequest.open]"  nsresult: 0x805e000a (<unknown>)"

What the fuck I though. And then after some (useless) firefox rebooting, I decided to ask the all-mighty Google.

No shit, he said, I know what you are talking about, and thou shall find more informations at this place, and to point me to this thread, where you can read the following:

AdBlock Plus was killing it HAH!

And then I disabled AdBlock Plus, and exactly as the writings told, it worked.

Customizing actions in symfony's admin generator

A quick tip about symfony's admin generator: if you want to have a custom action, with the following generator.yml bit for example (actions prefixed with an underscore are builtin admin-gen actions):

form:
  actions:
    _delete:  ~
    _cancel:  ~
    _save:    ~
    _save_and_add: ~
    custom: ~

You can totally customize the link generated for this action (to add javascript for example) using the generator helper in your module's lib/ directory:

[php]
public function linkToCustom($object, $params)
{
  return '<a href="#" onclick="console.log(\'woohoo\'); return false;">log woohoo</a>';
}

You get passed the current object as an argument, and whatever parameters you passed in the generator.yml:

    custom: { label: 'WOOHOO' }
[php]
public function linkToCustom($object, $params)
{
  return '<a href="'.url_for($this->getUrlForAction('custom')).'" onclick="console.log(\'woohoo\'); return false;">'.__($params['label']).'</a>';
}

Also, as you can see that standard helpers are available too.

Symfony Live les 11 et 12 Juin 2009

Sensio Labs organise les 11 et 12 juin l'événement Symfony Live. Voilà tout est presque dit, cliquouillez le lien pour plus d'infos.

Symfony Live Flyer

- page 1 of 39

Thème Time Flies par David Yim