We visited Rails Girls Warsaw

I was invited to coach at last week’s Rails Girls Warsaw, and I’m very delighted with being given such an opportunity.

Three of Coins is by no means a RoR company – we write Chef cookbooks, Vagrantfiles run in our blood, and one of the best ways to increase our heart rate is to iterate through backup systems, looking for the Perfect One.

Having said that, I do believe engaging in initiatives that increase the diversity of our community is important enough to spend time learning new technologies. Even intermediate Rails knowledge is enough to help other people get started! In my case, not-so-distant memories of the issues I myself encountered at the beginning of my Rails path allowed me to better understand (and prepare for) questions and problems that might arise during the workshops.

Wonderful organizing team from Warsaw

Wonderful organizing team from Warsaw (Anksfoto)

To make sure that participants got the best out of the weekend, each coach was looking over a group of just three students. Although most attendees had no prior programming experience, one member of my team had learned C during computer science classes at her university – classes designed to actually introduce programming languages, classes that, suffice to say, did not encourage to study programming, nor did they shed light on what programming is about.

The group I was coaching. Yes, we had chocolate!

The group I was coaching. Yes, we had chocolate! (Anksfoto)

Of course, not everyone has to know how to program, and not every participant of the workshop wanted to pursue a programming career. Knowing how this stuff works is an advantage in many fields though, even if the position you hold in your company / non-governmental organization is not the most technical one. And seeing how my team’s enthusiasm rose as workshop time passed, how they stated they want to continue their programming education made me very happy. I had a chance to donate some of my time towards increasing the diversity in our, still homogeneous, programming community.

Rails Girls Warsaw participants

Rails Girls Warsaw participants (Anksfoto)

If you’re interested, check out Rails Girls Warsaw’s Facebook page. If you’re wondering about coaching, you’ll find a list of local Rails Girls workshops here – as you can see, there’s plenty of locations to choose from! And if you are (or you know) Polish, there’s a message board for Rails Girls Warsaw attendees, where participants can share their problems and accomplishments, supported by most of the coaches of previous editions. Give it some thought – educating other is always an invaluable learning experience.

Bundler and rvm: remember about login shell

Bundler and the newest rvm (1.23.1) might give you a bit of a hard time, especially if you’re a less experienced Linux user. You install bundler by running gem install bundler in your GNOME Terminal and it’s a success, but when you want to actually run bundle  in your git repository folder, you might get a message like this:

/home/marta/.rvm/bin/bundle: line 32: gem: command not found

ERROR: Gem bundler is not installed, run gem install bundler first.

No matter how many times you run gem install bundler, nothing changes. You’ll receive a similar message if you run bundler in your Rails app folder:

ERROR: Gem bundler is not installed, run gem install bundler first.

Running gem list in the terminal will show you have bundler installed, and which bundle will return the path to the gem… but bundle -v will return the above mentioned error. So what’s going on?

Before you start digging in the ~/.rvm/bin/bundle source code and wonder what’s wrong with paths (it might seem as if there’s a problem with interpreting the proper path to the bundler gem), be sure to check if you have your Run command as login shell option ticked in your terminal’s preferences (in GNOME Terminal: Edit -> Profile Preferences -> Title and Command). When this option is left unchecked, Terminal won’t be able to find bundler when it’s being asked to execute it. That’s why you see bundler on the gem list, but it won’t be found when you call it.

Rvm might give you a hint on that login shell option, but unfortunately in completely different circumstances. If this option is left unchecked and for some reason you want to switch to an older version of Ruby, typing rvm use 1.8.7 will return:

RVM is not a function, selecting rubies with 'rvm use ...' will not work.

You need to change your terminal emulator preferences to allow login shell.
Sometimes it is required to use /bin/bash --login as the command.
Please visit https://rvm.io/integration/gnome-terminal/ for a example.

If all you want is to use the most recent version of Ruby, it might take some time before you actually run this command and thus stumble over that information. Whether you’re a less experienced Linux user or a regular that reinstalled her system recently, remembering about login shell might save you loads of time.

Help MiniGit: need opinion on syntax

MiniGit is a small Ruby gem to talk with Git command line in a straightforward way. You can write, say, git.commit(:amend => true, :reuse_message => true), and have it do the right thing. No fancy model objects for repos, commits, and branches. No magic. Well, a little bit of magic, just to make it simple and comfortable to use.

One of the quirks is capturing Git’s output. As of now, MiniGit either lets git use the original console, or captures its whole stdout and returns it as a string. Without stripping the trailing newline, or any logic. Simple and straightforward – but pretty uncomfortable: to, say, make sure there are no changes to the work tree, you write git.capturing.diff.strip.empty?. It’s a handful, and don’t get me started on splitting the output into lines.

I want it to be simple. I want to be able to get the output as string – stripped or not, as I prefer at the moment. I want to be able to iterate over the lines, and don’t have the lines include the trailing newline. I want to be able to discard the output, or to display it only when there’s an error. And I don’t want to type too much to achieve that. But I have no good concept of how to write it.

A custom magic method (such as MiniGit#capturing) for each case would clutter the namespace and be hard to maintain. And it would involve a lot of output. The next idea – a custom MiniGit#[] method to get a customized instance – this syntax is reserved for git config integration: git['user.email'] is too pretty and intuitive to waste it on anything else.

Next thing I thought of was overloading unary operators: -git could discard output (like prefixing Make lines), ~git could capture stdout, etc. Two issues here: one is that there’s still a very limited number of these operators. Still, there’s a limited number of things I may want to do with Git’s output, so this may not even be a problem. Second issue is that method call binds closer than any operator: -git.push would mean -(git.push), and I’d need to add extra parentheses to say (-git).push – ugly! Not to mention it would require users to memorize what each of the symbols means.

The idea I’m thinking of right now may be short enough, but it requires a bit of magic, and I’m not sure if it’s nice & convenient magic, or testrocket flashy & useless magic. If I’d need to use parentheses anyway, I may override binary operators to mimic shell redirection syntax. Instead of magic capturing method, one could write:

Each of these expressions would create a new, specialized instance (in most cases cached in the parent instance to avoid allocating too many short lived instances, at cost of sometimes storing a few too many) just the way MiniGit#capturing and #noncapturing. Other modifiers could make it e.g. return a boolean variable to indicate success rather than always raising exception on error and requiring user to rescue when they need to check status.

Update: a more straightforward option would be a method that would be quicker to type, and accept either a known keyword, or any MiniGit subclass; something like this:

Write me what you think

What do you think: nice? uselessly convoluted? confusing? stupid? Or maybe you have any better ideas for that? I’ll happy to hear any input. You can also help by upvoting on Hacker News to get more people here.

Just use the poll here – it’s not directly published as a comment, but sent directly to me. I will update the article to include the results after a few days. If you’d like me to be able to reply, include your e-mail – but it’s not required in any way.

Waiting to hear from you!

Don’t name your config Toolfile (or .tool.yml)

There is a pattern, mostly used in Ruby world, that if you write a command line tool, named – say – The Tool, and it has a configuration file tied to a project you use it with, then the tool’s configuration fie is called Toolfile, and lives in the root of the project’s directory.

Don’t do that. Please.

I suppose that this started a couple centuries ago, with mother of all the build tools Make and its Makefile. Ruby build tool Rake used the existing convention for build tools, and named its configuration file Rakefile. This makes sense: in a software project, build script is the entry point. It’s logical and convenient that it lives in top-level directory, and it’s easy to locate, because the name is capitalized.

Rake followed a useful convention for build script. But then, all other tools followed Rake without stopping to think if it’s useful. Now I have a repository that has a Rakefile, Thorfile, Gemfile, Berksfile, Vagrantfile, and Strainerfile – there are more Toolfiles in there than real content.

The other custom is to name the config .tool.yml – also in project root. While Toolfiles clutter the directory by being too visible, dotfiles files do the opposite – they disappear. Some projects get this right and use dotfiles or dot-directories for stuff that should be hidden: .rvmrc, .bundle, or even .chef are good examples. Still, .travis.yml or .rspec are ugly. Even without the dot, cucumber.yml or Jekyll’s _config.yml smell quite bad.

How to name configuration files, then? Simple: use a config directory. Let me put all the config in the config/ subdirectory instead of cluttering the root and making it harder to spot the README file. Seriously, what would be wrong with config/thor.rb, config/gems.rb, config/berkshelf.rb, or config/travis.yml? It would be even possible to adapt to different projects’ conventions by using a dotfile (that is supposed to be hidden) pointing to the directory, and looking for the config like this:

  • If .config is an empty file, always use Toolfile and don’t look at any directory
  • If .config is a file, go with `cat .config`/tool.rb
  • If .config is a directory or symlink pointing to one, `realpath .config`/tool.rb
  • If there is no .config, but config/tool.rb exists, use it
  • At the end, try Toolfile

By default, tool would look for config/tool.rb or Toolfile, and any project that uses a different config directory could use .config file or symlink to override this. Vendorificator already partially implements that, and I think that I’ll soon release a small gem that would deal with config files, including the .config override. Some other options may be useful, like finding multiple config file fragments by directory or glob.
Let’s hope that in a year or two I’ll be able to move at least some of the configuration files away and won’t need to find my project’s files between the configs!

SSL CA certificates on OSX

This is more of a note-to-self than a full post, but maybe this will be helpful to someone. Anyway, recently I’m working mostly with cloud infrastructure, Ruby, and bits of Python. On my OSX machine, Ruby Amazon EC2 libraries would fail, because they could not verify the server (see excon#13). Turns out that OSX, unlike Linux, keeps root CA certificates in its keychain, and not all libraries and programs know how to access it. The default directory for certificates, /System/Library/OpenSSL/certs/, is empty.

What do I do about it? Simple: steal certificates from Debian (using dpkg from macports):

Now, excon connects to EC2 servers safe that at least some authority signed off on the connection, and I can sleep safely at night.