Open dialogs from shell scripts

Using the dialog command you can launch ASCII-art dialogs from your shell scripts.

Check out man dialog for a list of supported dialog types. Aside from simple text boxes or choice dialogs, it supports more advanced interactions like file pickers or progress bars.

Example: Yes/no choice

dialog --yesno "Erase the world?" 0 0

yesno.png

Example: Menu with multiple opt...

CSS tests and experiments

The pages listed here contain tests and experiments about features, possibilities, browsers’ bugs concerning CSS.

That is, over 200 experiments.

CSS font metrics in detail

Line-height and vertical-align are simple CSS properties. So simple that most of us are convinced to fully understand how they work and how to use them. But it’s not. They really are complex, maybe the hardest ones, as they have a major role in the creation of one of the less-known feature of CSS: inline formatting context.

For example, line-height can be set as a length or a unitless value 1, but the default is normal. OK, but what normal is? We often read that it is (or should be) 1, or maybe 1.2, even the CSS spec is unclear on that...

Capybara: Disable sound during Selenium tests

If the application under test makes sound, you probably want to disable this during integration testing.

You can use the args option to pass parameters to the browser. For Chrome:

Capybara.register_driver :selenium do |app|
  Capybara::Selenium::Driver.new(app, browser: :chrome, args: ["--mute-audio"])
end

I haven't found a corresponding command line option for Firefox.

Hat tip to kratob.

How to search through logs on staging or production environments

We generally use multiple application servers (at least two) and you have to search on all of them if you don't know which one handled the request you are looking for.

Rails application logs usually live in /var/www/<project-environment-name>/shared/log.
Web server logs usually live in /var/www/<project-environment-name>/log.

Searching through single logs with grep / zgrep

You can use grep in this directory to only search the latest logs or zgrep to also search older (already zipped) logs. zgrep is used just like grep ...

Never use SET GLOBAL sql_slave_skip_counter with a value higher than 1

If you have a replication error with MySQL and you know the "error" is okay (e.g. you've executed the same statement at the same time on 2 masters which sync each other), you can skip this error and continue with the replication without having to set up the slave from the ground up.

stop slave;
set global sql_slave_skip_counter = 1;
start slave;

But what if you have multiple errors which you want to skip? (e.g. you've executed multiple statement at the same time on 2 masters which sync each other)
Still do not use a value highe...

Error "undefined method last_comment"

This error message may occur when rspec gets loaded by rake, e.g. when you migrate the test database.

NoMethodError: undefined method 'last_comment' for #<Rake::Application:0x0055a617d37ad0>

Rake 11 removes a method that rspec-core < 3.4.4 depends on. To fix, lock Rake to < 11 in your Gemfile:

  gem 'rake', '< 11', # Removes a method that rspec-core < 3.4 depends on

Geordi hints

Reminder of what you can do with Geordi.

Note: If you alias Geordi to something short like g, running commands gets much faster!
Note: You only need to type the first letters of a command to run it, e.g. geordi dep will run the deploy command.

geordi deploy

Guided deployment, including push, merge, switch branches. Does nothing without confirmation.

geordi capistrano

Run something for all Capistrano environments, e.g. geordi cap deploy

geordi setup -t -d staging

When you just clon...

How to tackle complex refactorings in big projects

Sometimes huge refactorings or refactoring of core concepts of your application are necessary for being able to meet new requirements or to keep your application maintainable on the long run. Here are some thoughts about how to approach such challenges.

Break it down

Try to break your refactoring down in different parts. Try to make tests green for each part of your refactoring as soon as possible and only move to the next big part if your tests are fixed. It's not a good idea to work for weeks or months and wait for all puzzle pieces ...

Enabling ** in your bash

You may know the double asterisk operator from Ruby snippets like Dir['spec/**/*_spec.rb'] where it expands to an arbitrary number of directories.
However, it is disabled by default on most systems. Here is how to enable it.

If you check your globstar shell option, it is probably disabled:

$ shopt globstar
globstar           off

In that case, ** behaves just like * and will match exactly 1 directory level.

$ ls spec/**/*_spec.rb
spec/models/user_spec.rb

To enable it, run

shopt -s globstar

The double ast...

Ruby: String representations of regular expressions

Ruby's regular expressions can be represented differently.
When serializing them, you probably want to use inspect instead of to_s.

For the examples below, consider the following Regexp object.

regexp = /^f(o+)!/mi

to_s

Using to_s will use a format that is correct but often hard to read.

>> regexp.to_s
=> "(?mi-x:^f(o+)!)"

inspect

As the Ruby docs say:

...

It's OK to put block elements inside an <a> tag

In general, you should not put a block element inside an inline element. So don't do this:

<span>
  <div>text</div>
</span>

The browser will think you wrote invalid HTML by accident, and will sometimes reorder elements silently.

There is one notable exception: It's OK to wrap block elements in a <a> tag in HTML5 (not 4). The spec says:

The a element may be wrapped around entire paragraphs, lists, tables, and so forth, even entire sections, so long ...

Puppet: Could not evaluate: Field 'device' is required

If you get an error like this for a puppet mount:

$ > puppet agent --test 
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Loading facts
Info: Caching catalog for example.makandra.de
Info: Applying configuration version '1483001792'
Info: Computing checksum on file /etc/fstab
Info: FileBucket got a duplicate file {md5}34b9adc036cf1dbd2392df84f921547d
Notice: /Stage[main]/Foobar/Swap_file::Files[default]/Mount[/var/swapfile]/ensure: defined 'ensure' as 'defined'
Error: /Stage[main]/Foobar/Swap_file::Files[default]/Mount[/var/s...

Bundler: Gemfile.lock is corrupt & gems are missing from the DEPENDENCIES section

So you're getting this failure when running bundle install on an older project:

Your Gemfile.lock is corrupt. The following gems are missing from the DEPENDENCIES section: 'archive-tar-minitar' 'hoe' 'rcov'

This happens when you are using a new version of Bundler with a project that was bundled with a very old version of Bundler. For reasons unknown, the Bundler dependency API returns different dependencies for some gems (like ruby-debug or rainpress) than the dependencies found in the downloaded gemspecs. While old versi...

Summarizing heredoc in Ruby and Rails

This card tries to summarize by example the different uses of heredoc.

  • In Ruby << vs. <<- vs. <<~
  • In Rails strip_heredoc vs. squish

strip_heredoc should be used for a text, where you want to preserve newlines. (multi-line -> multi-line)

squish should be used for a text, where you want to squish newlines. (multi-line -> one-line)

Ruby 2.3+

def foo
  bar = <<~TEXT
    line1
    line2
    line3
  TEXT
  puts bar.inspect
end
foo => "line1\nline2\nline3\n"

Read more: [Unindent HEREDOCs in Ruby 2.3](/m...

A case for different breakpoints

The linked article states that CSS breakpoints should group "similar" screen sizes and thus be at:

  • 600px "narrow"
  • 900px "medium"
  • 1200px "wide"
  • (1800px) "huge"

By choosing these breakpoints, most device screens will be somewhere between two breakpoints, and not at the very edge of them.

The ranges could be called:

  • narrow (< narrow)
  • medium (narrow - medium)
  • normal (medium - wide)
  • wide (wide - huge)
  • huge (> huge)

Debugging cucumber feature with javascript + firefox vnc

TL;DR Debugging problems with javascript errors in cucumber tests is sometimes easier in the browser. Run the test, stop at the problematic point (with Then pause from Spreewald 1.7+) and open VNC for Firefox.

Features:

Fix external Displays switching not on when plugging notebook in docking station

If your external displays not switching on or showing a weird behavior (for e.g. all displays getting the same configuration all the time) you can fix it by switching off all external displays and re-enabling only one in the first step. Afterwards you can apply your whole configuration via xrandr. This behavior could be a bug in the kernel and may be fixed in linux 4.8.

Example display configuration

Screen 0: minimum 8 x 8, current 5760 x 1200, maximum 32767 x 32767
eDP1 connected 1920x1080+0+0 (normal left inverted right x axis...

How to fix: Bundler 1.13 breaks parallel_tests

When running tests via parallel_tests, you may encounter an error:

cannot load such file -- parallel_tests/gherkin/runtime_logger
Error creating formatter: ParallelTests::Gherkin::RuntimeLogger (LoadError)

This will happen when you upgrade Bundler to version 1.13.x and appears to be "by design" since there is a Bundler config option to restore previous behavior.

You can fix it by setting that flag. You should commit the resulting config file into the repository!

bundle config --local disable_exec_load true

There is a Git...

Aruba: Stubbing binaries

When testing your command line application with Aruba, you might need to stub out other binaries you don't want to be invoked by your test.

Aruba Doubles is a library that was built for this purpose. It is not actively maintained, but works with the little fix below.

Installation

Install the gem as instructed by its README, then put this Before block somewhere into features/support:

Before do
  Arub...

Ruby: Writing specs for (partially) memoized code

When you're writing specs for ActiveRecord models that use memoization, a simple #reload will not do:

it 'updates on changes' do
  subject.seat_counts = [5]
  subject.seat_total.should == 5
  # seat_total is either memoized itself, or using some
  # private memoized method
  
  subject.seat_counts = [5, 1]
  subject.seat_total.reload.should == 6 # => Still 5
end

You might be tempted to manually unmemoize any memoized internal method to get #seat_total to update, but that has two disadvant...

Copy to clipboard without flash (clipboard.js)

We used zeroclipboard.js in some of our projects but now we switched to clipboard.js because it does not rely on flash. Flash support of the major browsers has ended.

Some more advantages of clipboard.js:

  • it consists only of a single javascript file, so it does not trigger additional requests with rails
  • it automagically provides user feedback by selecting the text it has copied
  • it provides callbacks for success and error which make it easier to add custom behaviour after copying to the clipboar...

Subclassing module

Yesterday I stumbled across a talk in which the guy mentioned module sub-classing. I was curious what you can do with it and found his blog post with a cool example. It allows you to inject some state into the module you are including elsewhere. Check it out!

class AttributeAccessor < Module
  def initialize(name)
    @name = name
  end

  def included(model)
    super
    define_accessors
  end

  private

  def define_accessors
    ivar = "@#{@name}"
    define_writer(ivar)
    define_reader(ivar)
  end

  def define_writer(ivar)
    ...

How to monitor Sidekiq: A working example

In order to have monitoring for Sidekiq (like queue sizes, last run of Sidekiq) your application should have a monitoring route which returns a json looking like this:

{
  "sidekiq": {
    "totals": {
      "failed": 343938,
      "processed": 117649167
    },
    "recent_history": {
      "failed": {
        "2016-11-06": 1,
        "2016-11-07": 46,
        "2016-11-08": 0,
        "2016-11-09": 0,
        "2016-11-10": 0
      },
      "processed": {
        "2016-11-06": 230653,
        "2016-11-07": 230701,
        "2016-11-08"...