How to Write Command-Line Applications in Ruby with GLI

Przemysław Dąbek March 3, 2015

blink terminalI use many different command-line tools on a daily basis, e.g. git to track changes in projects, autojump to navigate faster between directories, brew to install software and so on. Some time ago I started watching my workflow. What I noticed is that some commands appeared more frequently than the others and they contained more typos. I decided to simplify usage of tools to have less problems with typing all options properly. Here is the short tutorial how to do that easily.

Motivation

In our internal server infrastructure at Lunar we deploy demo and production applications to different containers on different servers.

Let”s assume that to access container with deployed application we need to execute one of the commands below:

ssh user@app.demo.domain # demo
ssh user@app.domain # production

After some time I”ve noticed that I was repeating most of these steps:

  • Make an SSH connection (every single time)
  • Go into application”s directory
  • Run rails console
  • Run tail on application”s logs
  • etc…

Gems for command-line apps

Writing applications with manual arguments parsing didn”t appeal to me so I”ve done research on existing gems. One of first results was Ruby Gems for Command-Line Apps page written by David Bryant Copeland. I browsed through the list and decided to give GLI gem a try.

Design

Let”s design a tool that solves or simplifies executing the steps mentioned earlier. Let”s call it blink.

Usage of blink may look like this:

blink shell app environment # connect an app"s directory
blink rails console app environment # connect an rails console
blink logs app environment # connect anapp"s logs

Implementation

You can follow the steps below or clone the blink-demo repository.

We need to install GLI first:

gem install gli

Then we create a scaffold project:

gli init blink shell rails logs

We focus only on bin and lib directories and following files in the structure:

.
├── bin
│   └── blink
└── lib
├── blink.rb
└── commands
├── base.rb
├── logs.rb
├── rails
│   └── console.rb
└── shell.rb

We create missing files and directories:

mkdir lib/commands
touch lib/commands/base.rb
touch lib/commands/logs.rb
mkdir lib/commands/rails
touch lib/commands/rails/console.rb
touch lib/commands/shell.rb

bin/blink

lib/blink.rb

lib/commands/base.rb

lib/commands/logs.rb

lib/commands/rails/console.rb

lib/commands/shell.rb

Further improvements

Our application is ready to use but we can still:

  • install application (e.g. add bin directory to PATH environment variable)
  • add more commands
  • use configuration files and remove environment-dependent code

Resources

GLI source code (Github)

GLI: Make Awesome Command-Line Applications the Easy Way

GLI: A code walkthrough

ssh -t

Models on a diet – Part II

Krzysztof Knapik February 24, 2015

“Thin controller, fat model” – noooooo!!!

Fat cat We probably all agree that “Thin controller, fat model” was a misconception. When “thin controller” sounds good, “fat model” is just a pain in the…let’s say – lower back ;)

Last week Ania Ślimak was talking about putting model on a diet. She presented a nice approach of reducing fat from models using validation factory. This solution is useful in many cases, but may not solve all the problems, so I wanted to continue this topic.

In the validation factory approach, validations are still stuck to the model and this responsibility is not fully extracted.

Validation rules and the model schema are like to change during their lifetime.

Every time you add/remove a rule or field, you may make existing records invalid in terms of the validation rules connected to the model. You have to maintain their validity, which is often unnecessary.

Validations are often contextual.

Sticking them with models may make using them in other places (e.g. another action or admin panel) is much harder and ends with adding plenty of ifs and unnecessary attributes describing the context.

The same issue happens with other stuff like sending emails in callbacks, which are often (unnecessarily) the model’s responsibilities.

The solution

Let’s not only move validations to the service object, but make model fully isolated from them and keep the data representation as its only job.

Validation service defines validations’ rules, takes a record as an argument and delegates it to the record. Some general logic is extracted to BaseValidator to be usable by other validation services:

And the happy model doesn’t know anything about validations:

But, where to actually call the validations? Model? – we said ‘no’ to that already. Controller? – well… we don’t need to put more responsibilities than handling the request and responding there.

So, let’s introduce another service object called Handler (Creator would a good name too), which sticks everything together:

What’s about the controller? It’s thin and happy as well:

Additionally, we could extract parameter sanitization logic to a service object and make controller even more clean.

Outcome

This way we have code:

  • with reduced model responsibilities
  • a way easier to maintain
  • easy to (unit) test
  • more OOP & closer to Single Responsibility Principle.

How I landed my 13.000 km dream internship

Riccardo Odone February 23, 2015

'Welcome back' drawing on a blackboard

This is my story. The story of a green smiley alien from planet Italy that decided to follow his dream and never listened to the naysayers.


One year ago I was in Chile, experiencing the most amazing adventure of my entire life. Most importantly, there I discovered what I wanted to do in life: web development.

As a matter of fact, during my university exchange, I was lucky enough to meet a bunch of people that, at first made me fall in love with web technologies, then set my enthusiasm on fire and, finally, showed me the bleeding edge stuff down the path.

That’s why approaching the end of my South American studies I felt lost: was my dream over?

In that moment I discovered something great. In fact, there is a place on planet Earth that a group of people is using as a headquarter for their space web missions. And not only they are doing the coolest things, they also have great fun in the process.
That place is called Lunar Logic.

lunar logic observatory illustration

Back then I had a crazy idea, I could have revolutionized my plans and joined those crazy and foolish space travelers for an internship. That way I would have had a whole group of astronauts with whom grow as a developer while writing my master thesis.

I didn’t even have the time to think rationally about it that I was already sold on the idea. Problem was, Lunar didn’t have any position open. Furthermore, they had recently closed the summer internship program.

There was only one way to convince them: I just needed to make the impossible possible.

For a few months I had been researching and studying every possible piece of information I could dig about them. Armed with that knowledge I tailored a perfect CV and a Polish-ed cover letter.

It was a one shot one kill chance, so I bought a flight ticket. Then I sent them my presentation letter, saying that I was going to be in Poland and I would have loved to meet face to face to discuss my application.

The day I got their ok I was already traveling through Poland. It made me super happy but I knew that I would have needed much more than that before celebrating. In fact, I had to face the Demo Day, a day long interview with all the crew.

Our contact happened on August 27th. When they opened the gate of the rocket to let me in, the feeling was strange; I already knew so many things about them and their shuttle, that it all seemed like a meeting with old buddies.

The moment I got into the place I spotted the Happiness Chart, the whiteboard where every Lunar person tracks his or her mood daily using a colored drawing: red for bad, blue for so-so and green for happy.

Happiness Chart

Walking through the hallway the situation got more and more crowded. So much that, when we finally got to the kitchen, the room was literally packed.
What surprised me is that I was the one asking about technical stuff, all of them were more interested about my life, hobbies and experiences.

Suddenly, all the people started gathering in the big room I saw near the entrance. In fact, it was Lean Coffee time: Lunar Logic weekly meeting.

I was stunned by the biggest room in Lunar: it felt relaxing with its two sofas and lots of fluffly bean bags, amusing with its foosball and darts, stimulating with its squared black Ikea library full of books.

Back to Lean Coffee. On the whiteboard the astronauts were writing down, one by one, the topics they wanted to speak about altogether. Then, after a brief vote they discussed every point in the established order.

I was shocked by how much every idea was listened and encouraged. That felt more surprising because every new voice I listened to was supporting a diverse opinion from the previous one. Still the discussion was balanced.

Lunar Logic's sofa room

After the meeting I encountered the captain of the (space)ship and took a seat with him on one of those comfy sofas.
What followed was the most intriguing two-hours interview I have ever had. And that wasn’t because he was drinking a beer in the meanwhile, or maybe it was?

Jokes aside, that conversation turned out to be really challenging. In fact, we both were trying to understand if we could have been a good fit for the job.
That was the moment I decided to drop the bomb. It was a dangerous move but rule number one during interviews is to be honest, so I complied.
Thing is, my situation was fairly complicated because I only had a few months free before coming back to Italy to attend a few more courses and graduate.

“It’s going to be something uncommon anyway so we can bend some details to have you aboard”, that answer ended our chat.
This whole conversation made me super inspired and on the emotional level I got the answer I needed: Lunar is about people, about the group.

At that point the clock on the wall struck 14:00 and I was left in the hands of the nerds. At first, I had to pair program some new functionality. Secondly, we talked about my background as a developer.
I have to be honest, that was the part of the interview where I sucked the most. But it’s just the way I am: ace the impossible things and slip on the easiest ones.

I was 6 hours into the Demo Day but the most important test still had to come. In fact, with three more developers I had to prove my reflexes and physical coordination.
It was Foosball time and it wasn’t ever a matter of being bad. I got completely owned. At some points I couldn’t even see the ball. I guess that their no gravity trainings in deep space made the difference.

The moment I got out of Lunar Logic’s base I only had one thing in mind: I wanted to become a proud astronaut.

I’ll never forget a few days later when, while seated on a bed in the worst hostel ever, I’ve read the Lunar email with their positive answer.

Email from Lunar Logic screenshot

My dream was on. Again.

Now I just had to convince my university and a professor to be a supervisor of mine on a project in Poland that didn’t even exist.
But that’s another story.

If you liked the post ping me on twitter @riccardoodone.
If you hated it you can go drink your Hatorade somewhere else!


This post is dedicated to all my Chilean friends and professors that supported me for a full year and gave me the inspiration and the enthusiasm to undertake this path through web development; without you I would not have a dream to fulfill.

Also, I’ll be always grateful to all the Lunar folks who gave my dream a shot and welcomed me into the family.
I feel proud of being a member of this awesome crew.

Models on a diet

Anna Ślimak February 18, 2015

Models are fat

Fat cat Usually models are very fat. Rails conventions encourages us to put too much responsibility into the poor model. That leads us very quickly very far from Object Oriented Programming. One of the reasons is lots of validations that we usually put into the model.

There is a built in mechanism to extract validations out of the model - validates_with - but it forces you to put all the validations inside one method: validate(record). This means you lose the very handy validation helper methods.

Influenced by Marcin Kostrzewa, I conducted an experiment to get rid of this responsibility from model by extracting all validations, but keeping the very handy validation dsl.

This is how model looked before a diet:

And this is how it looks after:

All the validations are in UserValidator class:

The instance of the UserValidator is created and populated with the data from the model by Validator::Factory class:

The idea

The idea is that in the model you register a specific validator in the Validator::Factory and use built-in Rails mechanism with the general Validator:

Validator has the method validate which is responsible for building the specific validator using Validator::Factory, populating it with the data from model, invoking valid? on it and reassigning errors from the validator to the model. That’s why in the UserValidator we need to define fields method; It needs to return all fields to be validated and then attr_accessor(*fields) will define accessors for them. It’s used by Validator::Factory to populate UserValidator with the data from model. Slim cat

Outcome

In the end we have code which is more object oriented, follows single responsibility principle and extracts responsibility which the model should not have. There is better communication between objects; Code is built with more small objects, each having it’s own specific job to do. We have a closed Validator::Factory class, which can build any specific validator and is open for extension; We can easily add new validators. Our models are leaner so they look more attractive!

Visualizing your business ideas in easy and simple ways has become much easier as many new solutions are appearing on the wave of Lean Startup’s growing popularity. There are differences between the various tools: themes, form, the level of detail and elements on which they focus attention. Learn to use them properly, you’ll become better at analyzing your ideas and product concepts, and at communicating the most important issues facing your new business.

Canvases are a great alternative to traditional business plans, which usually require a lot of documentation and don’t stress the most important information, reducing the clarity and readability of your business model for potential investors, partners and even employees. And, most importantly, they don’t allow entrepreneurs to work with their business ideas in flexible ways.

Business Model Canvas

The most popular new tool for visualising a business plan is the Business Model Canvas, which visually describes the key elements of a new company, service, or product. It focuses on the value which the business will offer customers, with the Value Proposition placed at the center of the canvas. Key partners and market/customer analysis are also important. It is possible to fill out the canvas using online tools (e.g. via the Strategyzer app or Canvanizer page). A useful supplement to that model is the Value Proposition Canvas, which lets you consider and complete information that is helpful for completing  your Business Model Canvas. You should go one to complete the Business Model Canvas if, in your business model, partners and resources are important. In the other canvas models, those parts are less prominent.

Business Model Canvas
Let’s say our business is an app which allows people to design pets clothes, which lets you put your pet in a costume (like that dog in a spider costume).

Lean Canvas

Less popular, but appreciated for its simplicity, is the Lean Canvas. This canvas is focused on users’ problems, which your product or service will solve and the concrete solutions offered. Lean Canvas has two parts: product and market. In contrast to the BMC, it assumes that the value offered to users will be unique, competitive and new. This canvas also adds a very important component: Key Metrics. These are the numbers you will track which will help you to recognize your product’s success. Competitive advantage is the most significant characteristic of the Lean Canvas; In the canvas it’s described as “Unfair Advantage” which explains the product’s competitive advantage (i.e. it is hard to copy or buy). You should choose the LC model if you’re focusing on users’ problems, solutions and measuring the progress of your business.

Lean Canvas
Using that canvas I realized that we need to change the concept a bit. I focused on problems and solutions which we offer (adding clothes created by designers, etc). I also need to change value proposition. I have one position – “Unfair Advantage” which I need to rethink.

Petri Model Canvas

Personally, I usually use either Lean Canvas or Petri’s canvas (FTE canvas), which is its extension. The FTE canvas model places more focus on customers with additional information about the ones that should be paid users. The flow of canvas creation is defined strictly and starts from a “Paid Users” prospective.

Unique to the FTE canvas is the distinction of users who buy your product on an early stage (Early Buyers). This group is often forgotten during a discussion about people who founded their own business. Co-founders are focused on target groups of the ready product, forgetting the natural distribution curve or the product life curve. They forget often that the product needs to first be adopted by users called by Rogers “innovators”, whose characteristics are usually different than those on the mass market. Or, conversely, they treat early adopters as the target group. Forgetting that early buyers are just a small part of all potential clients and achieving market success is connected with reaching a larger number of customers. The Rogers Adoption Curve shows it in a great way, and the FTE canvas distinguishes those groups clearly, too.

This canvas stresses the value of competitor analysis. The Existing Alternatives position focuses the attention of entrepreneurs not only at direct, active competitors, but also the other products and services which already solve the same users’ needs. Startups often forgot about competitors, which is a point often stressed by investors. There is a special canvas dedicated to competition analysis in a lean way.

The important element, which differentiates FTE canvas from Lean Canvas and Business Model Canvas, is the canvas down line, usually responsible for the financial side of the business. Whereas, in the preceding models, the last line included Cost Structure and Revenue Stream, while in the FTE canvas there are: Costs, Customer Acquisition Cost and Customer Lifetime Value (called also LTV or CLV).

As you can see, the structure of the FTE canvas is much more practical and measurable. It allows easy and efficient verification of the business hypothesis. You should choose it if monetisation and the financial side of your business is key for your business (so almost always?).

FTE canvas
There are many questions that I don’t know the answer to in that canvas. I change the KPI’s based on “Paying customer” and “Early buyers” positions. I need to describe, more precisely, the marketing & sales costs.

You need to remember that canvases are only a map of the issues that every startup should consider. There is value in experimenting with these models, because there is no canvas which is always the best – no matter the product or context. You can use more than one canvas in the very beginning; it forces you to look at a product from different perspectives. You can also change a canvas while working with a product (for example from LC to FTE, if, at first, you are working on a global conception and then you’d like to focus more on the financial side). But I don’t recommend completing and actualising a couple of canvases at the same time, because it won’t give you any additional benefits and will take up your time, which should be invested in developing the product. Regardless of which canvas you choose, the key is: if you can’t fill out any canvas in a logical way, you should rethink your business model or even just think again, deeply, about its formula.