Introducing JVM - The Java Version Manager

Last years it becomes more and more common to work in different projects running on different versions of Java. There still some running on Java 6, and there are tons already running on Java 8.

That's nice!

What isn't nice is to change JAVA_PATH and PATH every time you work on other project.

JVM aims to help you with that.

It's basically a shell script that you load on your bashrc or zshrc. It will then listen on folder change events. If you cd to a project running on Java 7, and you have Java 8 on your PATH, JVM will do the ~magic~ for you. :sparkles:

But how it works?

Basically, JVM will search for pom.xml files. If any is found, search for a java.version property in it. If it's found, search for matching installed Java, otherwise, JVM will look for .java-version file, and, if found, try to set a matching Java version to your PATH, otherwise do nothing.

Currently, it works Mac OS X and Ubuntu only, but, of course, pull requests are welcome.

For further info, take a look at the project's README.

Comment this post here.

Dump a PostgreSQL table as insert statements

FYI: Like the previous post, this is a really quick tip.

This week I'm working closely to the "front-end guy". Not that I don't know how to front end, but he is helping me.

We are developing an internal tool, that, for this first version, will use only a few tables of one of our databases.

Doing the "back end" part of it, I created tons of rows in my local database, and, in order to properly test the front end part, the "front end guy" needed some data. He could just create a lot of rows in that table. That would be easy. And boring. And inaccurate.

Dump an entire database is also boring, and usually takes a lot of time. Besides, he only needs one table.

So, I dumped that one table in the form of inserts. pg_dump, with some parameters, can easily do that:

pg_dump \
  -h localhost \
  -p 5432 \
  -U user -W \
  --table="table-name" \
  --data-only \
  --column-inserts \
  database-name > table.sql

So, I just had to send him this table.sql file somehow, and he had to execute that SQL file in his database, which can be easily done with the pg command:

psql \
  -h localhost \
  -p 5432 \
  -U user \
  database-name \
  -f table.sql

That's it. A quick and useful tip that I have used many times and will probably use many more.

Comment this post here.

Find non-ASCII chars

FYI: This is a really quick tip.

Sometimes things break because of random characters, like . Those kinds of characters may break, for example, shellcheck and other tools based on hlint:

hGetContents: invalid argument (invalid byte sequence)

Also, who likes those stupid chars? Nobody does!

Fixing that

The first step is to find them. I had some of them in my dotfiles project, as you can see in this pull request.

So, using grep, I created the nonascii function:

nonascii() {
 LANG=C grep --color=always '[^ -~]\+';
}

The usage is simple:

~/.dotfiles master
❯ cat osx/set-defaults.sh | nonascii
# Don’t animate opening applications from the Dock
# Don’t prompt for confirmation before downloading
# Add the keyboard shortcut ⌘ + Enter to send an email in Mail.app
# Disable smart quotes as it’s annoying for messages that contain code
# Don’t automatically rearrange Spaces based on most recent use
# Disable smart quotes and smart dashes as they’re annoying when typing code
# Disable the “Are you sure you want to open this application?” dialog
# Remove duplicates in the “Open With” menu

it won't be shown here, but all nonascii chars are in red.

Fix it now is straightforward, but, without this list, it would take a big amount of time to read the entire file paying attention to this kind of detail.

:beers:

Comment this post here.

Integrating Minitest with Shippable

I know, everyone uses Travis. I have nothing against it. But in case you want to test and/or use Shippable, this might be just the guide for you. I will also show how to setup that nice tabs with the test and coverage reports.

Rationale

I'm writing this post because I found no blog post or anything compiling all the needed steps, just some parts here and there. I want to make it easy for new users to start testing their stuff using an Continuous Integration system.

So, this is my attempt to compile all that in a how-to like blog post.

The good stuff

First thing we need is the .shippable.yml file. Mine looks like this:

language: ruby
rvm:
  - 2.1.2
script:
  - bundle exec rake test
env:
  global:
    - CI_REPORTS=shippable/testresults COVERAGE_REPORTS=shippable/codecoverage

The env is required for that nice tabs I said before to work.

Don't forget to add the required stuff to Gemfile:

source "https://rubygems.org"
gem "rake" # make sure you have rake here!
# ...
group :development, :test do
  gem "minitest"
  gem "simplecov"
  gem "simplecov-csv"
  gem "minitest-reporters"
end

I also created a Rakefile (so I can call it in the .shippable.yml file):

require 'rake/testtask'
Rake::TestTask.new do |t|
  t.pattern = "spec/*_spec.rb"
end

The last thing we need is the spec/spec_helper.rb file:

require "simplecov"
require "simplecov-csv"
SimpleCov.formatters = [
  SimpleCov::Formatter::HTMLFormatter,
  SimpleCov::Formatter::CSVFormatter,
]
SimpleCov.coverage_dir(ENV["COVERAGE_REPORTS"])
SimpleCov.start # you might want to pass 'rails' and/or a block here
require "minitest/autorun"
require "minitest/reporters"
MiniTest::Reporters.use!([
  MiniTest::Reporters::DefaultReporter.new,
  MiniTest::Reporters::JUnitReporter.new(
    ENV["CI_REPORTS"] || "coverage/ci"
  )
])
require_relative "../lib/mylibrary" # change to your library here

Most of this stuff is for Shippable to correctly parse test and coverage results. The order of the stuff here does matter. Don't change it if you don't know what you're doing.

With that being said, now, our specs will just have to require our spec_helper, and everything should work like magic when you run bundle exec rake test.

Troubleshooting

I had some trouble with compatibility issues related to Ruby's minitest. To clarify: there is the minitest gem and the minitest inside Ruby itself. If you use RVM (Shippable does), you will find it under ~/.rvm/rubies/ruby-VERSION/lib/ruby/2.1.0/minitest/.

Unfortunately for me, I use rbenv, and, for some reason I don't yet understand, rake test worked beautifully. With Shippable and RVM, I got this:

/home/shippable/.rvm/gems/ruby-2.1.2/gems/minitest-5.5.1/lib/minitest/assertions.rb:17: warning: already initialized constant MiniTest::Assertions::UNDEFINED
/home/shippable/.rvm/rubies/ruby-2.1.2/lib/ruby/2.1.0/minitest/unit.rb:80: warning: previous definition of UNDEFINED was here
Emptying /home/shippable/workspace/src/bitbucket.com/repo/repo/shippable/testresults

To fix that, I just had to change the rake test to bundle exec rake test (as already demonstrated in the .shippable.yml file in the beginning of this post). Simple fix for a hard-to-understand problem.

Comment this post here.

How to write a good tech job description

Recently I saw a job description of a Brazilian company, more or less like this:

Be a CompanyNamer

See job openings for City

  • Java Developer

Needed Knowledge

  • Bunch of technologies and certifications

Now, what's wrong with this?

For starters, there is no description of the actual job. "Java developer" of what? In which part? What challenges would I have?

You should also tell what your company and products do. Not everyone knows your big little company, doesn't matter how famous you think they are. Please, describe them.

Also, about this company-as-a-verb thing... I particularly think it's stupid. But that's just my opinion.

In my point of view, a good job description may look like:

A paragraph describing your company and its products.

A paragraph describing the job itself, maybe with a list of common tasks on a common day.

A list of stuff you should be good at to apply.

Another list with stuff that gives you "extra points".

I also like when the company talks about culture. While this doesn't guarantee that the culture is actually good, it usually means that the company at least care about that.

I also recommend you take a look at some "cool" tech companies. They usually have this solved already. Some examples are GitHub, Spotify, Rdio, Atlassian and Facebook.

But, well, this is just my opinion. A good site to see how to not write a job description is AvoidThisJob. If you like to see other opinions, you can simply Google about it. There are plenty of people talking about this stuff.

Comment this post here.

Jekyll: Reading time without plugins

Estimated reading time of a post is a feature that became popular, I believe, with Medium.

There are plenty of Jekyll plugins that address this problem, but, if you want to deploy at GitHub Pages, you can't use those plugins (GitHub will run with the --safe flag).

So, I created a snipped of pure Liquid code to fix that.

So, the first thing we will want to do is get the word count. That's pretty, actually:

{% assign words = content | number_of_words %}

Now, we need to divide this number with something. This something is called Word per minute (WPM). According to Wikipedia, an average person can read 180 words per minute in a computer monitor. Now it became really easy to do the rest:

{{ words | divided_by:180 }} mins

But, what if the post has less than 180 words? Actually, even if it has more, 350 words, for instance, when divided by 180, will result in 1.94, Liquid will round it down to 1, so, the user will see "1 mins", which is weird. To fix that, we have to check if it has less than 360 words, because any number great or equal 360 will result in 2+ mins, which still plural.

That said, the solution is quite simple:

{% if words < 360 %}
  1 min
{% else %}
  {{ words | divided_by:180 }} mins
{% endif %}

So, to keep it organized, I put all this in a read_time.html in my _includes folder:

<span class="reading-time" title="Estimated read time">
  {% assign words = content | number_of_words %}
  {% if words < 360 %}
    1 min
  {% else %}
    {{ words | divided_by:180 }} mins
  {% endif %}
</span>

And then I just include it in my post layout:

{% include read_time.html %}

And it works, as you can see here. Hope you like! :beers:

Comment this post here.

OpenSourcing my blog again

Once upon a time, my blog was OpenSource. People liked it and forked it tons of times, but they never change some stuff (disqus, analytics).

I got irritated and closed it.

Now, I'm reopening it again. I improved the README so I hope now it's clear that people should change some stuff.

Hope you like it.

Comment this post here.

Jekyll with Sass

I followed @mdo recent article "Using Sass with Jekyll", and wanted to point out the results.

I'm using some version of Lanyon with some custom stuff. So, I had 4 CSS files:

Requests

Summing it up, ~22K. It's not a lot, but, thinking about mobile 3G plans that are shit (like brazilian ones), why not save some bytes and requests?

So, I moved all those files to a _scss subfolder, and changed their extensions to .scss instead of .css.

Then, in my public/css folder, I created a styles.scss like this one:

---
# Needed for jekyll...
---

@import "poole";
@import "syntax";
@import "lanyon";
@import "carlos";

Also, I added the following section to my _config.yml:

sass:
  sass_dir: _scss
  style: :compressed

Finally, changed my _includes/head.html to import only the new styles.css:

<link rel="stylesheet" href="/public/css/styles.css">

And boom! It worked. With this, my previously four requests of ~22K went to one request with 12.8K!

Request

Besides that, now I have all the power that Sass provides, in my blog, without any hacks. And it works on GitHub pages!

Comment this post here.

Flamewars

Or:

How I went from a annoying linuxfag to just a random guy who uses unix-based systems and drops a few jokes about how Windows sucks instead of try to convince each and everyone to use a real operating system.

When I first discovered Linux, I was amused. I thought "this is great! Why there is so few people using it?. I can change anything! I can compile things. I command! I'm root!" Then, young and dumb, I followed the linuxfag tribe and started to try to convince people to use Linux instead of Windows. No, really, I tried to convince designers to drop Windows and Photoshop and use Linux and Gimp instead. I don't really know why nobody beat me to death. I would do it if I wasn't me.

After some time, I realized that it's stupid to do this. This is all politics. Nobody gives a shit about Windows piracy - not even Microsoft. It's pretty much like a drug dealer, but worse: they let you use it for free and make believe that there is nothing else out there (do you parents even know what an operating system is?), then, they charge other people (or you, without you know it).

It's quite simple:

  • You are taught since you're a child how to click the "Start" menu and do things;
  • You'll go study somewhere (school, college, whatever) and work somewhere;
  • You'll need to use a computer;
  • You don't know anything else but Windows (alongside 90% of people);
  • Companies and Schools and Colleges and shit buy Windows and Office licenses;
  • MS wins, without bothering you and your piracy;
  • But, if you buy a laptop with Windows included, you are paying for it;
  • MS wins, again, without bothering you and your piracy.

As the majority uses Windows, people will do more softwares for Windows. That's why there is no Photoshop for Linux, for example. This is the most fundamental concept of economics: Supply and demand. To make it even worse, there is a concept misunderstanding (free software) that people who use Linux don't like to buy things - as they seem to like "free software", but, as fun as this may sound, they believe that people who download and install a pirate copy of Windows do - and will buy they shit.

My "Free software" argument was shit. People don't really care about other stuff I do, like security, freedom, ability to change things, compatibility with some development stuff and so on. People want it to work. People want it easy. People want to play the last FPS on the market. They don't want to battle a driver incompatibility error, neither learn how to use other music player, or deal with Wine errors while trying to emulate a Windows game.

The thing is, what works for me, might not work for you. For me it's easy to open a terminal and type commands, but not for my mother. I enjoy learning this kind of stuff, but most of my coworkers and friend don't.

We have to admit, Microsoft did a good job "addicting" everyone to their "drug". After that, I realized that people will use what they like more, it doesn't really matter what I say about it. The same goes about programming languages and almost any flamewar about technology out there.

So, I end this flamewar thing. The only thing I do now is a few jokes with my coworkers and friends about how they actually need to use a real operating system to do whatever they're trying to do. It's funny for me, even if most people don't get it. Anyways, I don't care.

Comment this post here.

My personal goals for 2015

Well, 2014 is now almost over, and I didn't accomplish most of things I planned to. I see now that I set goals almost impossible to accomplish in that amount of time.

Well, I did read one book per month, for example (well, actually, I read ~1,5 books per month). I do keep doing exercises. I did changed jobs. I learned a lot of stuff. But, I didn't bought a car (yet I'm paying it). I didn't keep studying music. I didn't learn and profit in 2 more languages. That's quite a shame.

So, for this new year, I will aim to "accomplishable" things, following something I read in "The Passionate Programmer".

So, those are my goals for 2015:

  • Read 2 books per month (it was quite easy to do 1,5);
  • Keep practicing my English;
  • Do at least one post every two weeks here;
  • Master one new programming language;
  • Continue to do exercises;
  • Stop paying rent and buy an apartment or something.

Except the last item, all of those are things that I want to actually keep doing the whole year. The last item, though, is the more challenging, because it involves money, and the current Brazilian economy may not let me do anything, so, even if it's a little out of my control, I will focus to try to do it.

Those are my goals, what about yours?

Comment this post here.