10 Aug 2014

Meique 1.0 is there

Meique, my oldest pet project that still alive, was finally considered ready to get a 1.0 tag!

Meique is a C/C++ build system that aim to be simple to use, fast enough and whatever I would want. The project first commit on github dates from December 2009, and now after 5 years and 359 commits, it’s here, Enjoy!

29 Jul 2014

Capistrano 3 deploy for ":deploy_via, :copy" orphans

Capistrano 2 had a feature that enabled deploy by copying the project tarball to the remote server instead of git cloning it from the remote server, Capistrano 3 doesn’t had this feature. The problem of cloning it from the remote server is that sometimes the remote server doesn’t have access to the git repository and adding access to it is not desirable.

Just a note, or rant: Capistrano isn’t a good example of well documented project and Ruby doesn’t have clear semantic on what is public API and what should be considered private API, so I’m not 100% what I did is a hack or a honest use of their API. Anyway this works with Capistrano 3.2.1.

The code, hack, solution, whatever you call it

In Capistrano 2 times the elders of Google told me that a “set :deploy_via, :copy” should be enough to do the job, with Capistrano 3 Google just says it’s possible with few lines of code, but doesn’t say how.

The code bellow is in deploy.rb, hope you understand how it works by reading the comments.

# This is important, since the solution was tested only with 3.2.1
lock '3.2.1'

set :application, 'Hello'
# We will tell a white lie to Capistrano
set :scm, :git

# release id is just the commit hash used to create the tarball.
set :project_release_id, `git log --pretty=format:'%h' -n 1 HEAD`
# the same path is used local and remote... just to make things simple for who wrote this.
set :project_tarball_path, "/tmp/#{fetch(:application)}-#{fetch(:project_release_id)}.tar.gz"

# We create a Git Strategy and tell Capistrano to use it, our Git Strategy has a simple rule: Don't use git.
module NoGitStrategy
  def check

  def test
    # Check if the tarball was uploaded.
    test! " [ -f #{fetch(:project_tarball_path)} ] "

  def clone

  def update

  def release
    # Unpack the tarball uploaded by deploy:upload_tarball task.
    context.execute "tar -xf #{fetch(:project_tarball_path)} -C #{release_path}"
    # Remove it just to keep things clean.
    context.execute :rm, fetch(:project_tarball_path)

  def fetch_revision
    # Return the tarball release id, we are using the git hash of HEAD.

# Capistrano will use the module in :git_strategy property to know what to do on some Capistrano operations.
set :git_strategy, NoGitStrategy

# Finally we need a task to create the tarball and upload it,
namespace :deploy do
  desc 'Create and upload project tarball'
  task :upload_tarball do |task, args|
    tarball_path = fetch(:project_tarball_path)
    # This will create a project tarball from HEAD, stashed and not committed changes wont be released.
   `git archive -o #{tarball_path} HEAD`
    raise 'Error creating tarball.'if $? != 0

    on roles(:all) do
      upload! tarball_path, tarball_path

# Attach our upload_tarball task to Capistrano deploy task chain.
before 'deploy:updating', 'deploy:upload_tarball'

This worked for me™.

21 May 2014

Display Ruby version on prompt

The problem: I have multiple versions of Ruby installed and want to be sure about what version is the default on a terminal session.

Solution: Display the version on prompt!

I already do it for git branches, to show Ruby version is even simpler, on your .bashrc

RUBYVERSION='$(ruby --version | cut -f2 -d\ )'
PS1="\u \w [${RUBYVERSION}] \$ "

Of course you will change the PS1 to fit your needs with colors, etc… or your prompt will be pretty gray and ugly, BTW here is mine:

RUBYVERSION='$(ruby --version | cut -f2 -d\ )'
GITPS1='$(__git_ps1 "(%s)")'
PS1="\033[01;32m\u\033[0m \w \033[31m${GITPS1}\033[0m \033[35m[${RUBYVERSION}]\033[0m\n\$ "
06 May 2014

Ruby on QtCreator

After some days recovering from a septoplasty I got some time to put love on my new pet, not a dog, not a cat, just something non-organic, i.e. yet another pet project. This time it’s a plugin to add Ruby language support on QtCreator, a C++/Qml IDE.


Because I want to would be enough, but as I’m in a good mood let me explain in a single paragraph:

I use QtCreator for C++, It’s faster and code navigation, auto-completion and refactoring works as expected. I want to have these features when doing Ruby programming, besides it’s fun to write this kind of stuff.

So the project is hosted on github, I’m working on it when I can, however it already have some features:

Project Manager

QtCreator is a project oriented IDE, however I dislike the bureaucracy related to project setups on most IDEs, so I went to the simpler approach: open a .rb file and all .rb files under the directory will be added to the project, later I plan to add the many extensions used on Ruby and Ruby related files like .rhtml, .ru, etc.

Project Manager

A project manager means you can type “Ctrl+K” on QtCreator to open any project files.

Basic syntax highlight

It’s working, just need to be improved a bit to recognize regexes, in string variables, symbols, etc. It’s very easy to add this, but as the basic stuff is working I’ll concentrate on other things and improve the highlight as I need it.

Syntax highlight

Basic code navigation

Basic code navigation is working too via the “Ctrl+K menu”, you can see (and navigate) all methods of the current file (“. “ shortcut) or all project methods (“m “ shortcut).

Syntax highlight

The backend for this is based on regular expressions, my first attempt was using a Ruby-based Ruby parser but it was too slow for the task taking 6 seconds to parse a 20K lines files while my simple C++ version took 385 miliseconds, still slow but is enough for now.


This is simple, type: “def foobar”, hit enter and see the cursor when you expect it to be.

The future

The features I want to write ASAP are:

How to install and test?

Hmmm, there’s no docs at all, so consider the next lines as a documentation:

mkdir build
cd build
meique --QtCreatorSources=PATH_TO_QTCREATOR_SOURCE ..


This is it, if you want to help me on this just mail me, leave a comment or ping me on IRC.

23 Apr 2014

It's benchmark time!

I started to write my own build system for C++ years ago, at my own pace, one line at the time… and sometimes no lines at all. Last months I did work a bit more on it and nowadays I would consider it in a pretty good shape, so it’s time for a benchmark!

The motivations behind of benchmarking meique (BTW this is the project name) was the most pure act of human curiosity, mainly after read about the tup benchmak.

Meique is slower than tup, on the other hand it doesn’t need the “complicated” tup setup, run with suid, etc. So my comparison here is with 2 other contenders: CMake/make and CMake/ninja.


The metodology is very similar to the one used by the tup benchmak, just the code generator differ, so there’s a dummy C project with 4 shared libraries, and a main.c that uses them all, the number of files per shared libraries increase in each round, first 10 then 100, 1000 and 10000. i.e. 41, 401, 4001 and a 40001 files project. On each round the following operations are done:

Except for clean build, all other operations are repeated 3 times and the mean is used as result, there are also some other details that you can check in the script.

The computer used was a 8 cores intel i7 machine with 16GB on a hardware enabled RAID 0, make was ran with -j9.


For my surprise, meique is faster than CMake/make and as expected it’s slower than CMake/ninja. Since speed is a concern but not the meique main focus as it’s on ninja I consider the results very good.

Ninja isn’t showing in the results due to a bug, it can’t link a shared library with 10000 files due to the very long argument list, meique had this very same bug, now fixed.

1.95x faster on the 40K files project! And I don’t know why because clean build is the most simple task.

There are still much room for improvements on meique, so the next goal is simple: to be faster than a ninja! ;-)