Mocha: path to mocha.opts with -f

Mocha is a wonderful (:D) test framework which allows you to write really understandable tests in JavaScript. I’ve already introduced it in a previous article, so today I’ll focus on a pull request I’ve proposed.

Like other programs, you can pass arguments to mocha, like for instance –reporter used to specified a way to display test results. By the way, you should try once the nyan reporter. Concerning mocha, it’s also possible to set arguments in a file named « mocha.opts ». Interesting feature, but the file must absolutely be stored in your test directory.

So the idea is to add an argument: -f, –fileconf <path>. Furthermore, the –fileconf option allows you to specify the configuration file that will be used, by default “/test/mocha.opts”; allowing you to store your configuration file anywhere you wanted. This modification is very useful if you make tests using the same configuration file in many directories. Without –fileconf, you have to copy your file in each directory, and even a small modification must be done on each file. Using -f, you store the mocha.opts file in a unique place, so that any modifications of the file would immediatly impact all tests.

About the code

Add the parameter with commander:

.option('-f,--config <path>','specify the path to configuration file')

Load the file using commander to parse the command line:

//-f, --config
program.parse(process.argv);
var pathConf = 'test/mocha.opts';
if (program.config && exists(program.config)) {
  pathConf = program.config;
}
try {
  var opts = fs.readFileSync(pathConf, 'utf8')
    .trim()
    .split(/\s+/);

  process.argv = process.argv
    .slice(0, 2)
    .concat(opts.concat(process.argv.slice(2)));
} catch (err) {
  // ignore
}

In fact, this code is not available in mocha yet since « parsing twice might have some strange side-effects »…

An other way to augment argv without using commander:

//-f, --config

var pathConf = 'test/mocha.opts'
  , fIndex = process.argv.indexOf('-f')
  , configIndex = process.argv.indexOf('--config');

if(fIndex !== -1 && exists(process.argv[fIndex + 1]) ) {
  pathConf = process.argv[fIndex + 1];
}

if(configIndex !== -1 && exists(process.argv[configIndex + 1]) ) {
  pathConf = process.argv[configIndex + 1];
}

And I’ll finished this article by quoting visionmedia:

Maybe it’s ok but that’s still pretty hacky.

Node-Elastical: Delete by query option

What is Elastical?

Elastical is a Node.js client library for the ElasticSearch REST API.

That’s it for the presentation.

Until a few weeks ago, it wasn’t possible to delete data by query without using a hack. The hack was the following:

client.delete('twitter', 'tweet', '', {q: 'user:Shay'} );

Here, we set id to an empty string and we use the options parameter to perform a search on user with value Shay. Not so practical at all.

Using curl to interact with ElasticSearch, it is possible to delete by query:

curl -XDELETE 'http://localhost:9200/twitter/tweet/_query' -d ' 
  { "term" : { "user" : "kimchy" } 
}
'

This handy way of deleting things in ElasticSearch was not possible with Elastical (unless, you managed to use the hack above).

So I’ve added a new parameter options.query which allow us to perform such a query more easily.

client.delete('twitter', 'tweet', '', {query:
  { "term" : { "user" : "kimchy" } } 
});

When using the query parameter, id and all other options except ignoreMissing will be ignored.

Let’s take a quick look at the code involved:

if(params.query) {
  url = '/' + encode(this.name) + '/' + encode(type) + '/_query';

  this.client._request(url, {method: 'DELETE', json: params.query}
  , function (err, res) {
    if (err) {
      if (ignoreMissing && res && res.found === false) {
        return callback(null, res), undefined;
      } else {
        return callback(err, res), undefined;
      }
    }
    callback(null, res);
  });
} else {

It’s pretty simple. First, we need to build the url, then we’re requesting ElasticSearch on the given url, passing the query in the json parameter. If options.query doesn’t exist, then the original code is used.

As a conclusion, delete by query is now available in Elastical and you should use it!

 

ElasticSearch: Delete By Query API

[NodeJs] Spawn ou la création de processus fils

Un petit mot sur la façon de créer des processus fils sous node.
Pas compliqué et bien pratique, pour réaliser le cas de test d’une nouvelle fonctionnalité de npm par exemple.

Regardons le prototype:
child_process.spawn(command, [args], [options])
command correspond au programme appelé, ls, grep ou autre…
[args] est un tableau contenant tous les arguments qui seront passés au programme appelé via command.
[options] Plusieurs possibilités, dont le fait de pouvoir définir des règles pour le comportement de stdin, stdout et stderr.

Exemple:

//Set the no-proxy configuration
var noProxy = spawn(node, [npm, 'config', 'set', 'noproxy=localhost']
, { stdio: 'ignore' });

Ici, on crée un processus fils node avec pour paramètres: npm config noproxy=localhost.
On indique également que les entrées et sorties seront ignorées: { stdio: ‘ignore’ }.

Il est bien sûr intéressant de pouvoir effectuer une action particulière dès que notre fils se termine. Ceci est possible grâce à .on(‘exit’, function() { //CODE } ).
Soit avec l’exemple précédent:

noProxy.on('exit', function (code) {
console.log('noProxy process exited with exit code '+code);
});

Concernant les entrées/sorties, il est possible de laisser le processus écrire dans celles du processus parent en spécifiant cette fois: { stdio: ‘inherit’ }.
Un autre point utile consiste à récupérer le contenu de la sortie standard du processus fils.
Pour ce faire, on utilise les options suivantes: [‘ignore’, ‘stream’, ‘ignore’].
stdin et stderr sont ignorés, seule reste stdout.
On peut donc récupérer les données via .stdout.on(‘data’, function (data) { //CODE } ) , où data contient les données.
Pour reprendre l’exemple de npm, on peut ainsi récupérer la valeur de la variable de configuration proxy et la stocker dans une variable locale proxySave

var getProxy = spawn(node, [npm, 'config', 'get', 'proxy']
, ['ignore', 'stream', 'ignore']);
getProxy.stdout.on('data', function (data) {
proxySave = data.toString().trim();
});

Voilà pour les principales infos concernant spawn. Pour en savoir plus, direction la doc officielle ;).

[Conky] Script de démarrage

Conky est maintenant configuré… Prochaine étape, le démarrage automatique à l’ouverture de la session. On se place donc dans notre home où on va créer un dossier .conky pour y placer le script: mkdir .conky. On va ensuite écrire le script dans un fichier que l’on nommera .conkyboot.sh : vim .conkyboot.sh; utilisez ici l’éditeur avec lequel vous êtes à l’aise, nano, vi, vim ou autres.

Le script est très simple et tient en trois lignes:

#!/bin/bash
sleep 20;
conky -d;

Il faut ensuite rendre le fichier exécutable: chmod +x .conkyboot.sh.
Dernière étape, programmer l’exécution du script à chaque démarrage de la session. Pour cela, onglet Système – Préférences – Applications au démarrage. Puis Ajouter, et compléter le champ avec /home/user/.conky/.conkyboot.sh en remplaçant user par votre nom d’utilisateur. Remplissez le champ Nom avec Conky par exemple.

Et voilà, votre conky devrait désormais s’afficher automatiquement 20 secondes après l’ouverture de votre session.

[Conky] Afficher son IP publique

J’avais laissé Conky de côté un petit moment, et j’ai pris le temps ce soir de le réinstaller. Pas encore touché au démarrage automatique lors de la connexion, je veux d’abord vérifier s’il le fait de lui même ou pas. Mais trêve de bavardage, le sujet qui m’intéresse est celui de l’affichage de l’IP publique. J’avais déjà trouver comment afficher mon adresse ip locale et l’adresse de la passerelle.

La solution que j’ai trouvé consiste à aller interroger le site ip.nu avec curl. Néanmoins, le taux de rafraîchissement de conky étant de 2s dans mon cas, il faut trouver un moyen de lancer la commande à un intervalle beaucoup plus long. Notre adresse IP publique n’étant de toute façon pas susceptible de changer toutes les 10s.

Pour ce faire, on utilise donc texeci tempsEnSeconde qui nous permet d’appeler la commande à intervalle de temps régulier. On a donc: texeci 400 curl ip.nu. Toutes les 5 minutes, on interroge donc le site ip.nu. Toutefois, en l’état, le retour est le suivant:

<html>
    <head>
        <title>ip</title>
    </head>
    <body>
        Your IP address is 80.42.124.42
    </body>
</html>

Pas très pratique à afficher dans notre conky. Prochaine étape donc, la récupération dans toute ces balises, de l’adresse ip avec comme vous le devinez certainement un petit grep et une regex. Ce qui nous donne: curl ip.nu | grep -Ewo ‘\b([0-9]{1,3}\.){3}[0-9]{1,3}\b’. Résultat de cette commande: 80.42.124.42. Nous avons notre ip! Par précaution, on peut encore appliquer un uniq, au cas le site se mettrai à renvoyer plusieurs fois l’ip dans sa requête. Donc finalement: curl ip.nu | grep -Ewo ‘\b([0-9]{1,3}\.){3}[0-9]{1,3}\b’ | uniq. On notera au passage que Richard M. Stallman est l’un des auteurs de uniq

AUTHOR
       Written by Richard M. Stallman and David MacKenzie.

On peut maintenant ajouter notre code dans le fichier de conf .conkyrc, ce qui nous donne:

${alignc}Public IP: ${texeci 400 curl ip.nu | grep -Ewo '\b([0-9]{1,3}\.){3}[0-9]{1,3}\b' | uniq}