Syntax highlighting of code blocks with markdown

When you write comments or Readme on github, you can add an optional language identifier to enable syntax highlighting.

For example, for Ruby code:

```ruby
def initialize(budget:, start_date: Time.zone.today, end_date:)
  @budget = budget
  @end_date = end_date
  @start_date = start_date
end
```

and the result will be:

Imgur

2020-03-10 by Tatiana Panferova

Ignore whitespace when looking at a diff

Some pull requests look terribly messy, especially if most of the changes are due to changing the indentation level.

To look at these diffs in a nicer way, you can use git diff -w, which ignores whitespace.
This allows you to see the more interesting changes much easier.

This also works on GitHub and GitLab.
Just add ?w=1 at the end of the URL.

2020-02-20 by Florian Zinggeler

Filter finding files by creation date

Find files that were created within the past 7 days

$ find /path/to/dir/ -mtime -7
./file_from_yesterday
./file_from_three_days_ago

Find files that were created until 7 days ago

$ find /path/to/dir/ -mtime +7
./file_from_ten_days_ago
./file_from_thirty_days_ago
2020-02-07 by Mario Schüttel

Docker swarm keeps a tasks.db file which can grow large...

Some of our deployments suddenly failed mysteriously: docker: Error response from daemon: OCI runtime create failed: container_linux.go:346: starting container process caused "process_linux.go:319: getting the final child's pid from pipe caused \"EOF\"": unknown.

Various commands showed something was wrong:

# docker service ls
insdns4o4bu8        xxx_1     replicated          0/1           xxx   *:8000->8000/tcp
dggj6i4actyn        xxx_2     replicated          0/1           xxx   *:8001->8001/tcp
# docker node ls
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS
ux3enftr6krhlrp8bbodo2q1l *   wsdocker6           Down                Active              

systemctl status docker finally gave the right hint:
swarm component could not be started before timeout was reached

Which sent me to this issue comment which finally resolved the issue.

Turns out docker swarm has a tasks.db file which can get corrupted somehow.

2020-01-29 by Florian Zinggeler

Migrate from MySQL (or MariaDB) to Postgres

There’s a neat tool for macOS (maybe others too) to migrate a MySQL/MariaDB database to Postgres:

brew install pgloader

Here’s how I used it then:

createdb my_database_name
pgloader \
  mysql://root@localhost/my_database_name \
  postgresql://localhost/my_database_name

Very simple. It migrated a MariaDB 10.2 database to Postgres 12 without any issues.

2020-01-23 by Mario Schüttel

Debug Docker build steps

If a Docker build fails, you can inspect the intermediate steps.

The Rails asset compilation step below fails:

Step 10/12 : ADD . $APP_HOME
 ---> af4f399351dc
Step 11/12 : RUN bin/rake assets:precompile
 ---> Running in b5d9eec28028
...

We can run a command in the context of the last successful step:

docker run -it af4f399351dc sh
2020-01-17 by Dimiter Petrov

"not"-scopes in ActiveRecord::Enum

ActiveRecord::Enum got a nice new feature in Rails 6.

class User < ApplicationRecord
  enum status: [:active, :inactive, :radioactive]
end

The Model automatically receives these methods

User.active             # where(status: 0)
User.not_active         # where.not(status: 0)

User.inactive           # where(status: 1)
User.not_inactive       # where.not(status: 1)

User.radioactive        # where(status: 2)
User.not_radioactive    # where.not(status: 2)

The Model’s objects get these methods (unchanged since Rails 5)

user.active?        # status == 0
user.active!        # update!(status: 0)

user.inactive?      # status == 1
user.inactive!      # update!(status: 1)

user.radioactive?   # status == 2
user.radioactive!   # update!(status: 2)

https://api.rubyonrails.org/v6.0.0/classes/ActiveRecord/Enum.html

2019-12-19 by Mario Schüttel

Create a working copy from a bare git repository

Bare git repositories don’t have a working copy where you can read and edit files. Instead it contains what is usually in the .git subdirectory of a repository. You can re-create a “traditional” repository by cloning the bare repository.

git clone --local bare-repo-path project-name
2019-12-10 by Dimiter Petrov

Ruby: Use cover? instead of include? for ranges

include? compares every object of an array, while cover? checks if an item fits between the end points.

This difference makes it much faster to use cover? for ranges.

Example:

    one_hundert_years_ago = Date.today - 100.years
    today = Date.today

    t = Time.now
    (one_hundert_years_ago..today).include?(Date.tomorrow)
    puts Time.now - t
    # => 0.029056

    t = Time.now
    (one_hundert_years_ago..today).cover?(Date.tomorrow)
    puts Time.now - t 
    # => 3.4e-05 (= 0.000034)
2019-11-26 by Mischa Steiner

git stash --include-untracked

Let’s say you have modified a file in a git repository and have also created a new file, but not added it to the repository yet:

$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   README.md

Untracked files:
  (use "git add <file>..." to include in what will be committed)

    notes.txt

no changes added to commit (use "git add" and/or "git commit -a")

If you run git stash, the untracked file remains in the working copy:

$ git stash
Saved working directory and index state WIP on master: 0f25a2b Initial commit
$ git status
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)

    notes.txt

nothing added to commit but untracked files present (use "git add" to track)

Chances are the untracked files are related to the change you are trying to make and would like to bundle them in that stash.

The --include-untracked option (or -u in its short version) allows you to do just that:

$ git stash -u
Saved working directory and index state WIP on master: 0f25a2b Initial commit
$ git status
On branch master
nothing to commit, working tree clean

That’s a nice alternative to adding the untracked files and making a “work in progress” commit.

2019-11-26 by Dimiter Petrov

ActionDispatch::SystemTestCase no longer inherits from ActionDispatch::IntegrationTest in Rails 6.0.1

With Rails Release 6.0.1, ActionPack comes with this breaking change:

ActionDispatch::SystemTestCase now inherits from ActiveSupport::TestCase rather than ActionDispatch::IntegrationTest

Link to CHANGELOG

That means that some useful helper methods won’t be available anymore in system tests.

In one project we use a method fixture_file_upload that was affected by this change. We brought this back by including the corresponding module in ApplicationSystemTestCase:

class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
  include ActionDispatch::TestProcess::FixtureFile

  # ...
end
2019-11-08 by Mario Schüttel

Adding a limit to ActiveRecord "last" method

ActiveRecord supports adding a LIMIT to your SELECT statement through the last method:

User.last(10)

results in the following SQL query:

User Load (0.4ms)  SELECT `users`.* 
FROM `users` ORDER BY `users`.`id` DESC LIMIT 10
2019-10-02 by Antonia Horincar

Explicitly mount files with docker-compose

When mounting files in docker compose, like this:

volumes:
  - ./file-to-mount:/target/file-to-mount

an empty directory is created inside the container, if the file-to-mount does not exist! This leads to annoying debug sessions…

One can use the following syntax (with docker-compose 3.4), to mount a file more explicitly:

    volumes:
      - type: bind
        source: ./file-to-mount
        target: /target/file-to-mount

Now, when the file does not exists, it is not possible to start the container.

invalid mount config for type "bind": bind source path does not exist...
2019-09-18 by Philipp Koster

Run command line scripts from within Rake tasks

My usual approach when writing Rake tasks is to import a library and then use its API:

require_relative '../slides'

namspace :slides do
  desc 'Create an empty slideshow'
  task :new do
    Slides.new.write_to_disk
  end
end

Sometimes that is impractical: the API is not public, or you need to invoke a standalone script which only has a command line interface.

I found out Rake implements a ruby method which lets you invoke the ruby program directly:

task :new do
  ruby 'create_slideshow.rb'
  puts 'Created a new slideshow.'
end

There is also a sh method, which allows you to run system commands. Make sure to use the multiple argument version and avoid passing it unfiltered user input.

2019-09-11 by Dimiter Petrov

Install mysql gem on Mac OS X

According to this Gist.

brew install mysql
brew install openssl
gem install mysql2 -v '0.5.2' -- --with-ldflags=-L/usr/local/opt/openssl/lib --with-cppflags=-I/usr/local/opt/openssl/include
2019-09-05 by Andy Pfister

Step through migrations in Rails

tl;dr db:forward is the opposite of db:rollback

bin/rails db:migrate

runs all pending migrations.

If you want to migrate to a specific DB version, you can use

bin/rails db:migrate VERSION=20190730123456

which is rather cumbersome, especially if you only want to run one migration. Therefore you can use

bin/rails db:forward

You can combine it with variable STEP to execute multiple migrations.

bin/rails db:forward STEP=5
2019-08-02 by Mario Schüttel

rubocop-rails

rubocop 0.72.0removes all Rails cops, since they “[…] want RuboCop to be focused just on Ruby […]” (and I agree with them), see PR #5976.

In order to use the Rails cops after rubocop 0.72.0, we need to add rubocop-rails gem and require it as a dependency in .rubocop.yml:

require:
  - rubocop-rails
2019-07-29 by Mario Schüttel

Enumerable#grep

Ruby enumerables respond to grep. You can use it to quickly filter a collection with a regular expression.

['Marta', 'Mario', 'Bill'].grep(/Ma/)
# => ['Marta', 'Mario']
2019-07-12 by Dimiter Petrov

Update nested maps in Elixir

Being a functional programming language, Elixir is a bit different from other languages when it comes to update a nested data structure.

For example, in javascript we could do:

data = {
  inner: {
    one: {
      a: 1
    },
    two: {
      b: 45
    }
  }
}

data.inner.one.a = 2

In Elixir you have to build a new map with the updated information, for example:

data = %{
  inner: %{
    one: %{
      a: 1
    },
    two: %{
      b: 45
    }
  }
}

new_one = %{data.inner.one | a: 2}
new_inner = %{data.inner | one: new_one}
new_data = %{data | inner: new_inner}

which is not very handy.

In other functional languages like Haskell, there are libraries like Lenses that aims to solve the problem. In Elixir the kernel have an put_in function that acts in a similar way:

data = put_in(data, [:inner, :one, :a], 2)

You can find other similar functions in the Kernel documentation

2019-06-13 by Tiziano Puppi

The query function in Ecto Repo (Elixir)

There is a hidden function in Ecto which is the function query in the Repo module.

This is a wrapper around the Ecto.Adapters.SQL.query and it is injected in the Repo module of your application. It can be called in this way:

MyApp.Repo.query("SELECT * FROM mytable")

This function can also take an array of query parameters like:

MyApp.Repo.query("""                                           
SELECT * FROM mytable
WHERE id = $1
""", [42])

This is quite handy when you need to debug in production, and there is no database client available.

2019-06-07 by Tiziano Puppi

Union, Difference and Intersect with Ruby Arrays

Union

> [:a, :b, :c].union([:b, :c, :d])
 => [:a, :b, :c, :d]
# or 
> [:a, :b, :c] | [:b, :c, :d]
 => [:a, :b, :c, :d]

“Union all” / Concat

[:a, :b].concat([:b, :c])
 => [:a, :b, :b, :c]
# or
[:a, :b] + [:b, :c]
 => [:a, :b, :b, :c]

Difference

> [:a, :b, :c].difference([:b, :c, :d])
 => [:a]
# or
[:a, :b, :c] - [:b, :c, :d]
 => [:a]

Intersect

> [:a, :b, :c] & [:b, :c, :d]
 => [:b, :c]
2019-06-07 by Mario Schüttel

The sample output HTML element

There is an HTML element called <samp> meant for representing computer program output. The specification document has this humorous example:

<p>The computer said <samp>Too much cheese in tray
two</samp> but I didn't know what that meant.</p>