Upgrading from Capistrano 2 to 3
Capistrano 3 is a major rework of the framework and requires several adjustments to your deploy configuration files. The biggest change is that they moved away from their custom DSL and use Rake instead. For connecting with and operating on the servers, they bring a new gem SSHKit which does the heavy lifting. It's SSHKit's DSL that is used anywhere inside the Rake tasks. See #Resources at the bottom for examples.
Step 1: Upgrade guide
For migration from 2 to 3, follow this tutorial: [Capistrano 3 Upgrade Guide](https://semaphorec...
Configuring RubyGems to not install documentation by default
When installing gems, a lot of time is spent building locally installed documentation that you probably never use.
We recommend you disable documentation generation for gem install by default.
Note that Bundler won't install documentation, so this advice applies only when installing gems manually.
If you don't already have it, create a ~/.gemrc file. The gemrc is a Yaml file, so add the following line to add default switches to the gem command.
gem: --no-document
(If you do n...
Use rbenv-each to run a command for every installed Ruby version
The linked rbenv plugin rbenv-each is very helpful to keep QoL gems up to date that are not part of the Gemfile.
For example, you can bump the geordi version for all your rubies with the following command:
rbenv each gem update geordi
Another useful example would be to bulk-update bundler or rubygems.
Note that rbenv-each hasn't been updated since 2018, but it is fully functiona...
Rbenv: How to remove a gem installed from a Github source
Normally you can list all gems of the current ruby version with gem list, which also includes the gems of you Gemfile. These can be uninstalled with gem uninstall gemname.
List and uninstall a gem installed via Bundler from Github
This does not work for gems installed directly from Github. They do not appear in gem list.
Show all gems installed via Github by bundler:
ls ~/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/bundler/
Remove a gem installed via Github by Bundler:
rm -rf ~/.rbenv/versions/2.4.1/lib/ruby/gems/2....
Upgrade guide for moving a Rails app from Webpack 3 to Webpack 4
Webpacker is Rails' way of integrating Webpack, and version 4 has been released just a few days ago, allowing us to use Webpack 4.
I successfully upgraded an existing real-world Webpack 3 application. Below are notes on everything that I encountered.
Note that we prefer not using the Rails asset pipeline at all and serving all assets through Webpack for the sake of consistency.
Preparations
- Remove version locks in
Gemfileforwebpacker - Remove version locks in
package.jsonforwebpackandwebpack-dev-server - Install by ca...
Debug Ruby code
This is an awesome gadget in your toolbox, even if your test coverage is great.
-
gem install ruby-debug(Ruby 1.8) orgem install debugger(Ruby 1.9) - Start your server with
script/server --debugger - Set a breakpoint by invoking
debuggeranywhere in your code - Open your application in the browser and run the code path that crosses the breakpoint
- Once you reach the breakpoint, the page loading will seem to "hang".
- Switch to the shell you started the server with. That shell will be running an irb session where you can step thr...
Migration from the Asset Pipeline to Webpacker
This is a short overview of things that are required to upgrade a project from the Asset Pipeline to Webpacker. Expect this upgrade to take a few days even the diff is quite small afterwards.
Preparations
1. Find all libraries that are bundled with the asset pipeline. You can check the application.js and the application.css for require and import statements. The source of a library is most often a gem or a vendor directory.
2. Find an working example for each library in the application and write it down.
3. Find out the ver...
Limiting GitLab CI runner to specific branches or events
Use rules to include or exclude jobs in pipelines.
Rules are evaluated in order until the first match. When a match is found, the job is either included or excluded from the pipeline, depending on the configuration. The job can also have certain attributes added to it.
rules replaces only/except and they can’t be used together in the same job. If you configure one job to use both keywords, the linter returns a key may not be used with rules error.
GitLab 12.3 introduced rules. You can use them in your .gitlab-ci.yml in your proj...
Get rid of WARNING: Nokogiri was built against LibXML version 2.7.7, but has dynamically loaded 2.7.8
If you get this warning on your local machine one of these steps might help:
Rebuilt the gem with the newer library
gem install --no-rdoc --no-ri nokogiri -- --with-xml2-include=/opt/local/include/libxml2 --with-xml2-lib=/opt/local/lib
If you still get the error, try to uninstall all nokogiri versions with
gem uninstall nokogiri
and install nokogiri again.
Fixing the issue on servers
However, on our servers this probably will not work. On the server, gems are stored in the ../shared/bundle/ruby/:version/gems dire...
Terminator setup for Procfile-based applications for more comfortable debugging
We use foreman to start all necessary processes for an application, which are declared in a Procfile. This is very convenient, but the outputs of all processes get merged together. Especially while debugging you might not want other processes to flood your screen with their log messages.
The following setup allows you to start Terminator in a split view with the Rails server running in the left pane and all remaining processes running via foreman in the right pane. It was heavily inspired by [this card](https://makandracards.com/makandr...
New Firefox and gem versions for our Selenium testing environment (Ubuntu 14.04+)
Firefox 5.0.1, which we were using for most Rails 2.3 projects, does not run on Ubuntu 14.04 any more. Here is how to update affected projects.
-
Update (or create)
.firefox-versionwith the content:24.0
If you haven't installed Firefox 24 yet, the next time you run tests with Geordi, it will tell you how to install it. -
On a Rails 2 project:
-
Update your Cucumber-related gems as described in Upgrading Cucumber and Capybara, including
cucumber_spinnerandlaunchy. -
If you...
-
Deal with certain travis CI failures
Travis changed their default distribution from Ubuntu 14.04 (trusty) to 16.04 (precise). This might break your test setup for new builds.
You can solve this issue by freezing your test distribution in the .travis.yml to Ubuntu 14.04 until you have the time to solve all the issues you will have in 16.04:
dist: trusty
Error details
Here are few indicators that you ran into this issue:
Connection to the PostgreSQL database does not work anymore
Your travis-ci builds might have started failing on the usual
psql -c...
Fix for mysql2 error "Incorrect MySQL client library version! This gem was compiled for x.x.x but the client library is y.y.y."
This should be fixed in the latest LTS-branches of our mysql2 fork, 0.2.x-lts and 0.3.x-lts.
Use
gem 'mysql2', git: 'https://github.com/makandra/mysql2', branch: '0.2.x-lts' # for Rails 2.x
gem 'mysql2', git: 'https://github.com/makandra/mysql2', branch: '0.3.x-lts' # for Rails 3.x
in your Gemfile, and do a
bundle update mysql2
Background
mysql2 used to check that the client library used at runtime actually matches the one it was compiled against. However, at least on Ubunt...
Thread-safe collections in Ruby
When using threads, you must make your code thread-safe. This can be done by either locking (mutexes) all data shared between threads, or by only using immutable data structures. Ruby core classes like String or Array are not immutable.
There are several gems providing thread-safe collection classes in Ruby.
concurrent-ruby
The concurrent-ruby gem provides thread-safe versions of Array and Hash:
sa = Concurrent::Array.new # supports standard Array.new forms
sh = Co...
rbenv: A basic introduction
Why
We have projects that have been developed using many different versions of Ruby. Since we do not want to constantly update every old project, we need to have many Ruby versions installed on our development machines.
Rbenv does that for us.
How it works
Rbenv installs ruby version and ruby gems to ~/.rbenv/versions/VERSION_NUMBER/.... This way many different Rubies can be installed at once.
When you run ruby or gem or bundler or any other Ruby binary
- rbenv looks for a file...
Test a gem in multiple versions of Rails
Plugins (and gems) are typically tested using a complete sample rails application that lives in the spec folder of the plugin. If your gem is supposed to work with multiple versions of Rails, you might want to use to separate apps - one for each rails version.
For best practice examples that give you full coverage with minimal repitition of code, check out our gems has_defaults and assignable_values. In particular, take a look at:
- Multiple `sp...
Fix error: Missing the mysql2 gem
So you got this error, even though your Gemfile bundles mysql2:
!!! Missing the mysql2 gem. Add it to your Gemfile: gem 'mysql2'
or
Please install the mysql adapter: `gem install activerecord-mysql-adapter` (mysql is not part of the bundle. Add it to Gemfile.)
The reason for this confusing error message is probably that your Gemfile says mysql2, but your database.yml still uses the mysql adapter. Change it to use the mysql2 adapter:
development:
adapter: mysql2
database: myproject_developm...
Fix error: Invalid gemspec / Illformed requirement
When you get an error like this:
Invalid gemspec in [/opt/www/foo-project.makandra.de/shared/bundle/ruby/1.8/specifications/carrierwave-0.6.2.gemspec]: Illformed requirement ["#<YAML::Syck::DefaultKey:0x7fda6f84d2e8> 1.1.4"]
... the machine's Rubygems needs to be updated.
If that happens on your local machine
- Manually remove the offending's gem files and specifications. The paths will be something like
/usr/lib/ruby/gems/1.8/gems/your-broken-gemand `/usr/lib/ruby/gems/1.8/specificatio...
Howto: Require a gem that is not in Gemfile
In case you want to require a gem, that is not in the Gemfile of you bundle and therefore not in your loadpath, you need to add the path manually and require the gem afterwards.
Expected error
Requiring a gem, that is not in the Gemfile or .gemspec, will cause an LoadError exception:
require 'example_gem' => LoadError: cannot load such file -- example_gem
Adding a gem to the loadpath temporary
- You need to install the
gem
gem install 'example_gem'
- Then you need to require the path where the gem was install...
Fast rubocop autocorrection alias
The rubocop binary has a few interesting flags:
-
rubocop(using the--paralleldefault ) scans the current repository for linting issues while using multiple CPU cores -
rubocop -a(or--autocorrect) safely corrects most offenses while doing a sequential scan -
rubocop -A(or--autocorrect-all) also tries to correct unsafe suggestions
Autocorrection takes significantly longer on large projects because of the sequential nature.
To speed things up, you can use the following alias. It first checks in parallel if any files...
net-ssh and openssl-3.0.0
You'll need openssl-3 or newer for servers running 22.04
Ruby version 3.1 uses by default the gem openssl-3.0.0. This can cause issues with the gem net-ssh (6.1.0). This is a known bug.
Typically this can cause an error while deploying an application with capistrano:
could not verify server signature (SSHKit::Runner::ExecuteError)
or
Ed25519::VerifyError: signature verification failed!
As temporary workaround add the following line to your Gemfile:
gem 'openssl', ...
Gherkin: Error during installation
When trying to install the gherkin gem, you might encounter an error with the following lines:
ERROR: Error installing gherkin:
ERROR: Failed to build gem native extension.
...
checking for main() in -lc... yes
creating Makefile
...
cc1: all warnings being treated as errors
Makefile:150: recipe for target 'gherkin_lexer_ar.o' failed
make: *** [gherkin_lexer_ar.o] Error 1
...
If upgrading is not an option, configure build options for gherkin:
bundle config --local build.gherkin --with-cflags=-w
Your .bundle/config fi...
Ruby: Using the pry debugger in projects with older Ruby versions
In case you want to use pry with an older version of Ruby, you can try the following configurations.
Ruby 1.8.7
Your pry version must not be greater than 0.9.10.
gem 'pry', '=0.9.10'
gem 'ruby-debug', '=0.10.4'
gem "ruby-debug-pry", :require => "ruby-debug/pry"
gem 'pry-nav'
gem 'ruby18_source_location'
Ruby 1.9.3
Your pry version must not be greater than 0.9.9.
gem 'debugger', '=1.1.4'
gem 'pry-debugger', '=0.2.0'
gem 'pry', '=0.9.9'
Known errors
No source for ruby-1...
Pre-releasing a Ruby gem
When a Ruby version gem has a letter in its version number, it is considered a pre-release:
1.0.0.rc12.3.0.alpha23.0.0.beta34.0.0.pre.rc2
Even if a pre-release gem has the highest version number, it is never installed unless the user explictily requested the version:
gem install foobar --version="=2.3.0.alpha2"
Also bundle update will never update a stable version to a pre-release version unless the user explicitly requests it in the Gemfile:
gem 'foobar', '=2.3.0.alpha2'
A note on Semanti...