Ruby: A short summary of available hooks in Cucumber
Here is a short summary of Cucumber hooks in Ruby taken from https://github.com/cucumber/cucumber-ruby. Note that the BeforeStep
is currently not existing in the Ruby implementation of Cucumber.
Before
hooks run before the first step of each scenario.
Before do |scenario|
...
end
After
hooks run after the last step of each scenario, even when the step result is failed
, undefined
, pending
or skipped
.
...
Migrate gem tests from Travis CI to Github Actions with gemika
We currently test most of our gems on Travis CI, but want to migrate those tests to Github Actions. This is a step-by-step guide on how to do this.
Note that this guide requires the gem to use gemika.
- Go to a new "ci" branch:
git checkout -b ci
- Update gemika to version >= 0.5.0 in all your Gemfiles.
- Have gemika generate a Github Actions workflow definition by running
mkdir -p .github/workflows; bundle exec rake gemika:generate_github_actions_workflow > .github/workf...
Installing old versions of mysql2 on Ubuntu 20.04+
On some of our older projects, we use the mysql2 gem. Unfortunately, versions 0.2.x (required for Rails 2.3) and versions 0.3.x (required for Rails 3.2) can no longer be installed on Ubuntu 20.04. Trying this either leads to errors when compiling the native extension, or a segfaults when using it.
For Rails 4.2, mysql2 version 0.4.10 seems to work okay. If you still have issues, upgrade to 0.5.x, which should be compatible.
To install it, you have to switch the mysql2 gem to our fork. In your Gemfile, ...
Installing Ruby <= 2.3 on Ubuntu 20.04+
Installing old Rubies (<= 2.3) with a standard rbenv + ruby-build is no longer possible on Ubuntu 20.04. This is because those Rubies depend on OpenSSL 1.0 which is no longer shipped with current Ubuntus.
We have forked ruby-build with a workaround that makes it compile and statically link the latest OpenSSL 1.0 version. This works on Ubuntu 20.04, as well as on Ubuntu 18.04.
To switch to our fork of ruby-build, update ruby-build like this
git -C ~/.rbenv/plugins/ruby-build remote add makandra...
How to implement simple queue limiting/throttling for Sidekiq
The sidekiq-rate-limiter gem allows rate-limiting Sidekiq jobs and works like a charm. However, it needs to be integrated on a per-worker basis.
If you want to limit a whole queue instead, and if your requirements are simple enough, you can do it via a Sidekiq middleware yourself.
Here is an example that limits concurrency of the "mailers" queue to 1. It uses a database mutex via the [with_advisory_lock](https://github.com/ClosureTree/wit...
VCR and the webdrivers gem
If you're using the webdrivers gem and VCR together, depending on your configuration, VCR will yell at you regulary.
The webdrivers gem tries to update your webdrivers on your local machine. To do so, it checks the internet for newer versions, firing an HTTP-request to e.g. https://chromedriver.storage.googleapis.com
You can "fix" this in multiple ways:
-
Update your drivers on your machine with
RAILS_ENV=test rake webdrivers:chromedriver:update
-
Ignore the driver update-URL in your ...
Pagy
Pagy is a gem for pagination.
They make some bold claims:
Pagy is the ultimate pagination gem that outperforms the others in each and every benchmark and comparison.
Maybe this is worth trying out.
Ruby: How to determine the absolute path relative to a file
If you want to get the path of a file relative to another, you can use the expand_path
method with either the constant __FILE__
or the method __dir__
. Read this card for more information about __FILE__
and __dir__
.
Example
Structure:
.
├── bin
│ ├── format_changelog
├── CHANGELOG.md
bin/format_changelog
:
#!/usr/bin/env ruby
changelog_path = ? # How to get the path to ../CHANGELOG.md independent of the working dir of the caller
changelog = File.read(changelog_path)
# ... further actions...
Git: Search for text in all branches
To find a version containing the regular expression foo
in the history of any branch:
git grep foo $(git rev-list --all)
You may also limit the search to a file extension, e.g. Ruby files (.rb
) like this:
git grep foo $(git rev-list --all) -- *.rb
Ruby Jard: Just Another Ruby Debugger
Ruby Jard provides a rich Terminal UI that visualizes everything your need, navigates your program with pleasure, stops at matter places only, reduces manual and mental efforts.
Workflow: How to use a key management service to encrypt passwords in the database
This is an extract from the linked article. It shows an approach on how to implement encrypted passwords with the AWS Key Management Service (KMS).
For most applications it's enough to use a hashed password with a salt (e.g. the gem devise defaults to this).
Upon password creation
-
Generate hash as hash of password + salt.
-
Encrypt the hash with a public key from KMS (you can store the public key in your server code).
-
In your database sto...
How to fix: Rails query logs always show lib/active_record/log_subscriber.rb as source
Rails 5.2+ supports "verbose query logs" where it shows the source of a query in the application log.
Normally, it looks like this:
User Load (0.5ms) SELECT "users".* FROM "users" WHERE ...
↳ app/controllers/users_controller.rb:42:in `load_users'
However, you may encounter ActiveRecord's LogSubscriber as the source for all/most queries which is not helpful at all:
User Load (0.5ms) SELECT "users".* FROM "users" WHERE ...
↳ activerecord (6.0.3.3) lib/active_record/log_subscriber.rb:100:in `debug'
While th...
Controlling issue grouping in Sentry
When you use Sentry to monitor exceptions, an important feature is Sentry's error grouping mechanism. It will aggregate similar error "events" into one issue, so you can track and monitor it more easily. Grouping is especially important when you try to silence certain errors.
It is worth understanding how Sentry's grouping mechanism works.
The default grouping mechanism
The exact algorithm has changed over time, and Sentry will keep using the algorithm t...
Clean your Rails routes: grouping
In Ruby on Rails, all the routes of a given application can be found within the config/routes.rb file.
You add more and more routes in this file as your project grows.The problem here is that this file potentially becomes very complicated to manage over the time.
That’s why it’s important to find a way to order and maintain your routes.
See: Clean your Rails routes: grouping
Sometimes the routes.rb
grows very fast and each line adds mo...
Ruby: Appending lines to a file in sync
When writing some logs to a file, that don't use Ruby's logger utility, it is often useful to sync them. So other process can read the output just in time.
Example with enabled sync
log_path = '/tmp/some_log.log'
log_file = File.open(log_path, 'a+')
log_file.sync = true
log_file.puts('Some log message')
File.read(log_path) #=> "Some log message\n"
log_file.puts('Some other message')
File.read(log_path) #=> "Some log message\nSome other message\n"
Example ...
How to check if a file is a human readable text file
Ruby's File class has a handy method binary?
which checks whether a file is a binary file. This method might be telling the truth most of the time. But sometimes it doesn't, and that's what causes pain. The method is defined as follows:
# Returns whether or not +file+ is a binary file. Note that this is
# not guaranteed to be 100% accurate. It performs a "best guess" based
# on a simple test of the first +File.blksize+ characters.
#
# Example:
#
# File.binary?('somefile.exe') # => true
# File.binary?('somefile.txt') # => fal...
PostgreSQL: How to use with_advisory_lock to prevent race conditions
If you want to prevent that two processes run some code at the same time you can use the gem with_advisory_lock.
What happens
- The thread will wait indefinitely until the lock is acquired.
- While inside the block, you will exclusively own the advisory lock.
- The lock will be released after your block ends, even if an exception is raised in the block.
This is usually required if there is no suitable database row to lock on.
Example
You want to generate a...
Vortrag: Content Security Policy: Eine Einführung
Grundidee
CSP hat zum Ziel einen Browser-seitigen Mechanismus zu schaffen um einige Angriffe auf Webseiten zu verhindern, hauptsächlich XSS-Angriffe.
Einschub: Was ist XSS?
XSS = Cross Site Scripting. Passiert wenn ein User ungefiltertes HTML in die Webseite einfügen kann.
<div class="comment">
Danke für den interessanten Beitrag! <script>alert('you have been hacked')</script>
</div>
Rails löst das Problem weitgehend, aber
- Programmierfehler weiter möglich
- manchmal Sicherheitslücken in Gems oder Rails
Lösungsid...
The State of Ruby 3 Typing | Square Corner Blog
We're pleased to announce Ruby 3’s new language for type signatures, RBS. One of the long-stated goals for Ruby 3 has been to add type checking tooling. After much discussion with Matz and the Ruby committer team, we decided to take the incremental step of adding a foundational type signature language called “RBS,” which will ship with Ruby 3 along with signatures for the stdlib. RBS command line tooling will also ship with Ruby 3, so you can generate signatures for your own Ruby code.
Ruby 3 is coming, and it will have optional type sign...
Introducing GoodJob 1.0, a new Postgres-based, multithreaded, ActiveJob backend for Ruby on Rails
GoodJob is a new background worker gem. It's compatible with ActiveJob.
We're huge fans of Sidekiq for its stability and features. One advantage of GoodJob over Sidekiq is that GoodJob doesn't require Redis. So in cases where you don't have Redis or don't want to pay for a Redis HA quorum node, this might be an alternative worth checking out.
Fixing wall of warnings: already initialized constant Etc::PC_SYMLINK_MAX
These warnings are printed when the etc
Gem is installed, while etc
is also included in Ruby. Fix with:
gem uninstall etc
Automatically validating dependency licenses with License Finder
"Open-source software (OSS) is great. Anyone can use virtually any open-source code in their projects."
Well, it depends. Licenses can make things difficult, especially when you are developing closed-source software. Since some OSS licenses even require the employing application to be open-sourced as well (looking at you, GPL), you cannot use such software in a closed-source project.
To be sure on this, we have developed a project-level integration of Pivotal's excellent [license_finder](https:/...
How to prevent Nokogiri from fixing invalid HTML
Nokogiri is great. It will even fix invalid HTML for you, like a browser would (e.g. move block elements out of parents which are specified to not allow them).
>> Nokogiri::HTML.fragment("<h1><p>foo</p><span>bar</span></h1>").to_s
=> "<h1></h1><p>foo</p><span>bar</span>"
While this is mostly useful, browsers are actually fine with a bit of badly formatted HTML. And you don't want to be the one to blame when the SEO folks complain about an empty <h1>
.
To avoid said behavior, use Nokogiri::XML
instead of Nokogiri::HTML
whe...