What I expect from a great employer

Alright, so here’s my list.

First of all, I expect any decent employer to pass the “Joel Test”

Now, of to my basics:

  • Salary. Don’t try to start out with cheapest offer you can come up. No virtual shares as incentive. I’ve never seen those work out for anybody.
  • Product. In order to care about it, I need a product that solves a concrete problem and is not sales-driven. Bonus points: It makes the world a better place. This excludes everything that is even remotely connected to ecommerce, marketing or advertisting.
  • Commute / home office. Offer me the possibility to do home office one or two days a week if I live more than 20 minutes away. It’s 2014, not 1976.
  • “The mission”: If you’re just exit-driven, don’t bother to approach me. I want to work with real entrepeneurs – that means people who care about the product, the company and the employees and not about the quickest exit possible.

The intricacies:

  • Overhours. They might be necessary sometimes but they certainly should not be the rule.
  • Don’t try to enforce a company culture. This just happens or …it doesn’t. The only thing you as an employer can do is set up the environment for it. Having semi-automated, semi-mandatory team events every month is not the right way to do it.
  • Company meetings. Only have those when you have something to say. Don’t do them regularly because people will just talk because they have to say something.
  • Meetings in general. Don’t do it unless you a) have an agenda, b) have a moderator and c) have a tight time frame.
  • Managers. The less, the better. Delegators are useless at best, in most cases they are harmful
  • No interruptions. Or at least schedule them properly. You know what happens when you interrupt a programmer, don’t you?
  • Give me time to learn and develop myself. It always puzzles me that in an industry where knowledge and learning is everything you’ll rarely find companies that give you time to learn. You’ll hear crap like “We’d like to do it, but we’re not google”. Guess what, genius, that’s exactly the reason why you’re not google. One day a month for open source work and learning new languages and technologies is a win-win for everybody.
  • Don’t be cheap. Don’t make me explain why I need this ebook which costs you 20 Dollars. Don’t try to find the cheapest accomodation possible for a conference. It’s  disrespectful and it kills my motivation.
  • Involve me in the product. If you treat people like ticket slaves this is exactly what you get: ticket slaves.
Posted in Uncategorized | Leave a comment

git workflows and best practices

Everyday git

Preliminary remark: I use a bunch of shortcuts and abbreviations here for git commands which follow the official “git best practices” and you should configure your environment accordingly as well. See https://github.com/troessner/dot/blob/master/.gitconfig

How to create a feature branch / pull request

  • Create feature branch and switch to it

    git co -b feature_branch

  • Publish it on remote

    git ps -u origin feature_branch

Hint: If you use a tool like:

you can get this done even quicker.

  • Do your changes
  • Stage them

git add -p

Yes, that’s a “-p” there. Please do never use

git add .

  • When you think you’re done commit everything

git ci -m ‘Your meaningfull commit message in proper english.’

  • Publish them

git ps

Now you can open up that pull request on github. Tip: Becomes even easier with the github gem.

This pull request should be reviewed and commented by one of your peers before anything else happens.

What should I do after the pull request has been merged?

  • Close the pull request remotely and delete the branch via github interface (there’s a button showing up after you merged / closed that pull request.)
  • Delete the branch locally via

git b -D your_feature_branch

How to squash all commits from on PR into one?

First of all, you need to understand why it is absolutely necessary that your whole PR is one, atomic pull request:

  1.  git-log is one of the most important git tools and if you’re not familiar with it, you really should learn about it (more to come here soon). However, if one feature is split across several commits git-log is useless because I can’t tell what belongs where.
  2. If I realize a feature has gone wrong and I need to remove it from the mainline I can’t do that if that feature is spread across multiple commits which are already intertwined with master without doing potentially dangerous rebasing. This would also require that I do know exactly what commits belong to what feature which is next to impossible, even after a short time.
  3. If one feature is one commit I can easily play around with, e.g. deploy features in different combinations to staging servers.

So how do I do that?

Ok, so let’s say you have 3 commits in your feature branch that do not exist in master and your feature branch is named “fancy_feature”.

First of all we need to find out how many and what commits that are:

The two most common methods would be:

git log fancy_feature –not master

git log master..fancy_feature

However this gets tedious to repeat so you want to do something similar to what I did and add an alias to your bashrc (or whereever it fits you) like this:

alias sh_exclusive_commits=’git log $(git symbolic-ref -q HEAD) –not master –pretty=oneline –abbrev-commit –decorate’

So now, when I execute

sh_exclusive_commits

I get (given that I am on the feature branch of course):

9c5ec4b (HEAD, fancy_feature) Finalize feature.

6b24ba0 Fix foobar.

b3210dc Update foo to do bar.

Now let’s squash those commits into one:

Generally you would do it like that:

git rebase -i master

which tells git to take the last commits starting from HEAD (the commit on top of the branch you’re working on) that are not in master.

Now, if you execute this, you’ll see something like this:

  pick b3210dc Update foo to do bar.$

  pick 6b24ba0 Fix foobar.$

  pick 9c5ec4b Finalize feature.$

# Rebase 82ed078..9c5ec4b onto 82ed078

What you want to do now is:

  • Squash those 3 commits into one
  • Give that one commit a proper name
  • Merge it back into master

To do that this is what the menu should look like:

r b3210dc Update foo to do bar.$

f 6b24ba0 Fix foobar.$

f 9c5ec4b Finalize feature.$

This tells git to “fix up” 9c5ec4b and 6b24ba0 into b3210dc and rename b3210dc in the same step. If you save that file now git will perform those operations and then let you rename b3210dc. Now to the last steps:

git co master

git cherry-pick your_final_commit

Posted in git | 2 Comments

How to make objects behave like ActiveRecords models…

…and make them usable with rails form helpers as well.

1.) Use ActiveModel

Add

    include ActiveModel::Validations

to the top of your class in question. Now you have all the standard validations like

  validates :field, presence: true

at your hands.

2.) Make it possible to initialize your objects ActiveRecord style:

    def initialize(attributes = {})
      attributes.each do |name, value|
        send("#{name}=", value)
      end
    end

3.) Make them usable with rails form helpers

I am not sure if this the “right” way to do it, however it worked pretty well for me.
You need to add

def to_key; nil; end

otherwise rails will complain if you use this object with a form helper:

undefined method `to_key' for

Of course this doesn’t have to be nil, it can be anything that works as a key.

Posted in rails, Ruby | Leave a comment

Elastic Beanstalk and Ruby / Rails – Stay away

Recently I wanted to switch our deployments from manual setups to something more suitable and automatable in terms of scaling, process management and so on.
Since we were already on EC2, Elastic Beanstalk was the first thing that came to mind:

From the docs:

AWS Elastic Beanstalk is an even easier way for you to quickly deploy and manage applications in the AWS cloud. You simply upload your application, and Elastic Beanstalk automatically handles the deployment details of capacity provisioning, load balancing, auto-scaling, and application health monitoring.

Seems like a good fit. Unless it isn’t.

So what’s the problem with Elastic Beanstalk?

Nothing f***ing works. Nothing f***ing works.

First of all, you need to understand one thing: I tried to get a basic rails app up and running. I did absolutely nothing by hand – I only used amazon’s built-in steps. This means I exclusively used amzon’s webinterface. No manual fumbling on the instances itself.

Now, even with this basic setup I had problems all of the time. Below a list errors that randomly popped up and in the same manner disappeared again from deployment to deployment:

All of a sudden my ruby setup seems borked big time:

2013-04-26 08:18:48,080 [INFO] (29466 MainThread) [directoryHooksExecutor.py-29] [root directoryHooksExecutor info] Output from script: /usr/bin/rake:9:in `require’: no such file to load — rubygems (LoadError)
from /usr/bin/rake:9
Rake task failed to run, skipping database migrations

WTF?

Events / logs are not reliable:

Trying to get the logs after a failed deployment gives me:

Failed to pull logs for environment instances. Reason: Some instances have not responded to commands. Responses were not received from [i-52f6fc18].

Or:

In the “Events” Tab I see:

Failed to deploy application

However there is NO error in the logs and despite what the “Events” say, deployment apparently was successful

All of a sudden my rails setup is borked:

From the logs (after more than a dozen deployments):

2013-04-19 10:25:38,717 [INFO] (1831 MainThread) [directoryHooksExecutor.py-29] [root directoryHooksExecutor info] Output from script: rake aborted!
No Rakefile found (looking for: rakefile, Rakefile, rakefile.rb, Rakefile.rb)

(See full trace by running task with –trace)
Rake task failed to run, skipping asset compilation.

Apart from this seemingly random bugs which come and go as they please, I am pretty sure that almost no one is using EB for ruby / rails. You can google for any problem you have and you find nothing. It seems like amazon just added this specific layer because it is hip.

All in all, using Elastic Beanstalk was a horrible experience and I can’t recommend it to anybody. Funny enough I tried out amazon opswork after Elastic Beanstalk and so far, this has been nothing short of fantastic.

Long story short: If you want to use amazon deployments mechanisms, use opswork, not Elastic Beanstalk.

Posted in Uncategorized | Leave a comment

Why you should always merge feature branches as one atomic commit

Since I’ve had this discussion quite often I thought I’d summarize my arguments here

Posted in Uncategorized | Leave a comment

My glorious vim setup

Ok, so maybe it’s not that glorious.

Plugins:

Configuration:

Shamelessly stolen from people with a lot more vim knowledge than I have: My vimrc

Posted in vim | Leave a comment

Here is why you should never outsource coding

…unless you really made sure that the team is actually any good. If you don’t, you get back gems like below.

We like it explicit, don’t we:

public boolean gpsCheck()
{
  if (lm.isProviderEnabled( LocationManager.GPS_PROVIDER )==true )
    return true;
  else
    return false;
}

Why restrict yourself to just one way of saying that something doesn’t exist?


if (price != null || !price.equals("null")) {
if (slogan != null || !slogan.equals("null")) {
if (year != null || !year.equals("null")) {

This is how you should handle email validations:


private void sendInvitation(final String email) {
  if (email == null || email.length() < 5 || !email.contains("@")) {
    Utils.displayMsg(context, R.string.invalidEmail);
    return;
  }
  else if (!email.contains("@")) {
    Utils.displayMsg(context, R.string.invalidEmail);
    return;
  }
  // ...
}

(I especially like the guard in the “else if”. Just to make really sure that we have an @ in there.)

It’s always a good idea to name your variables like existing core java classes:

private String Long;

public String getLong() {
  return Long;
}

public void setLong(String Long) {
  this.Long = Long;
}

Better double check that we really return null if the result is null:

public ArrayList<String> getResult() {
  if (result == null)
    return null;
  return result;
}

If you don’t know how to actually load some kind of configuration in Android, just put api keys in your locale files, because you know how to load those, don’t you?

<string name="GoogleMapAPIKey">My_God_Damn_Api_Key>

Good stuff, isn’t it?

Posted in clusterfuck, java | Leave a comment