Due to massive procrastination, I was stuck with Ubuntu 16.04 LTS for a while, but I switched to Mint 21.2 a few days ago. There was a bit of a rush, so I didn’t think much about trying another OS before switching, and there’s no way I was going to get stuck in the world of snap packages, so I chose Mint over Ubuntu. I was using an older version of Ruby (>2.7) on my system, but since Ruby doesn’t fall under my domain of work, and everything was centered around building my website using Jekyll, I never encountered any issues. Until now.
I’m using the Parchment Theme for this site, and everything was working perfectly on the old machine. However, when I switched to Mint and started working, I faced a series of issues. I didn’t note down anything, and I’m not feeling motivated enough to reproduce the issue, so I’m going to write what I remember and what worked.
Phase Uno — Basics
$ git clone git@github.com:rhl-bthr/parchment.git
$ cd parchment
$ bundle install
el problema – Bundler could not find compatible versions for gem "bundler":
To fix –
$ gem install bundler -v '~> X.Y.Z'
$ bundle _X.Y.Z_ install
I think I faced some issues here which I don’t remember clearly; possibly, it couldn’t force RubyGems to use the version which bundle _X.Y.Z_
install specified.
I possibly deleted the Gemfile.lock
and ran bundle install
, and that might have worked. I’m not entirely sure because I do not exactly remember, so moving forward.
Phase Dos — Panic Findings
When I did
$ bundle exec jekyll serve
I got -
jekyll 3.9.0 | Error: no implicit conversion of Hash into Integer
/home/rishi/.local/share/gem/ruby/3.0.0/gems/pathutil-0.16.2/lib/pathutil.rb:502:in `read': no implicit conversion of Hash into Integer (TypeError)
from /home/rishi/.local/share/gem/ruby/3.0.0/gems/pathutil-0.16.2/lib/pathutil.rb:502:in `read'
Two things –
jekyll 3.9.0 | Error: no implicit conversion of Hash into Integer
/home/rishi/.local/share/gem/ruby/3.0.0/gems/pathutil-0.16.2/lib/pathutil.rb:502:in `read': no implicit conversion of Hash into Integer (TypeError)
After googling, here are a few things I found out:
- GitHub Pages uses
Jekyll 3.9
, which isn’t compatible with Ruby 3. Downgrading to Ruby 2.7 should avoid the problem. - Avoid using plain global
Jekyll
version 4. - Use
bundle add webrick
. - To stay with Ruby 3 or later, you can specify this Ruby 3-compatible update in your
Gemfile
:
source "https://rubygems.org"
gem "jekyll"
gem "webrick"
gem "pathutil", github: "sdogruyol/pathutil", ref: '6ab144a7706c2bc5fa0dfdfa498e94ff66e944c6'
- Apply the patch to
pathutil
because Ruby 3.0 deprecated using the last argument as keyword parameters. A double splat ** has to be added before the variable for the behavior to be supported.
Applying patch locally -
sudo sed -i.bak 's/, kwd/, **kwd/' $(gem which pathutil)
Phase Tres — Copying Pasting
A few things that I did within a couple of minutes.
-
Attempt 1 — Tried
gem add webrick
as recommended on GitHub’s docs.-
Status — It did not work. Nothing changed. I still encountered the error:
Error: no implicit conversion of Hash into Integer
.
-
Status — It did not work. Nothing changed. I still encountered the error:
-
Attempt 2 — Applied patch to
pathutil
usingsudo sed -i.bak 's/, kwd/, **kwd/' $(gem which pathutil)
-
Explanation — Search for files associated with the
pathutil
gem, create a backup, and then replace every occurrence of, kwd
with, **kwd
. -
Reason — As mentioned above, Ruby 3.0 deprecated using the last argument as keyword parameters. Adding a double splat
**
before the variable should support this behavior. - Status — It did not work, and I had no idea why. It was expected to resolve the issue.
-
Explanation — Search for files associated with the
Phase Cuatro — Forgetting
-
I forgot about one of the solutions, which was to not use the plain global Jekyll version 4. So, my
Gemfile
hadgem 'jekyll', '4.0.0'
instead ofgem "jekyll", github: "jekyll/jekyll"
. -
I also forgot to add
gem "pathutil", github: "sdogruyol/pathutil", ref: '6ab144a7706c2bc5fa0dfdfa498e94ff66e944c6'
to myGemfile
.
As of now, I can’t say whether these approaches would have fixed the problem while I was trying out various things, but the first point is part of the solution, which I implemented last after downgrading Ruby.
Phase Cinco — RVM Clashes
Downgrading Ruby turned out to be a massive pain in the ass because I first chose rvm, which brought tons of issues.
$ rvm install 2.7.2
Now, I don’t remember in what order I faced these issues, but they all arrived.
-
Problem 1 —
no command 'rvm' found, but there are 20 similar ones
-
Solution
curl -L https://get.rvm.io | bash -s stable
source ~/.rvm/scripts/rvm
rvm requirements
source /etc/profile.d/rvm.sh"
-
Solution
-
Problem 2 —
Error running '__rvm_make -j8'
-
Solution —
rvm pkg install openssl
andrvm install ruby-2.7.x --with-openssl-dir=$HOME/.rvm/usr
-
Solution —
-
Problem 3 —
mkdir: cannot create directory ‘/usr/share/rvm/log/1648619894_ruby-2.3.5’: Permission denied
-
Solution —
rvm fix-permissions system; rvm fix-permissions user
-
Solution —
The issue was that it couldn’t build the old Ruby versions because they relied on OpenSSL 1.1.1, whereas newer versions of Ubuntu come with OpenSSL 3.x. The approach to solve Problem 2 failed in my case, but many people mentioned that it worked for them.
None of the solutions worked because things were falling apart during compilation. I was tired at this point, so I purged the entire Ruby ecosystem from my machine. I removed rvm
, rbenv
, ruby-build
, asdf
, chruby
, and ran apt purge ruby
. It made me feel better, but after the purge, the urge to fix things was not over.
Phase Seis — Going For A Walk
It was already 4 am, so I decided to go for a walk. On my way back home, I stumbled upon this blog post. If only I had read the comments on this Stack Overflow post earlier, I might have found the solution sooner. But who reads everything when they’re tired and just want to fix things as soon as possible? Not me.
I installed rbenv, which seems to be the best out of all the Ruby version managers.
The setup was fairly simple -
$ git clone https://github.com/rbenv/rbenv.git ~/.rbenv
$ ~/.rbenv/bin/rbenv init
$ FPATH=~/.rbenv/completions:"$FPATH"
$ autoload -U compinit
$ compinit
Since I didn’t want to go through more frustration, especially since people still faced issues downgrading Ruby using rbenv, as mentioned here. Even though one of the maintainers commented that -
Update: newer versions of ruby-build work around the problem of the user having to manually download and install the required version of OpenSSL.
What this means when installing, for example, Ruby 2.7.5 on Ubuntu 22.04 is that ruby-build will automatically download and compile OpenSSL 1.1 and link Ruby to that instead of to the system OpenSSL.
Make sure to upgrade your ruby-build!
I decided to follow the steps mentioned in this blog post. It didn’t have any explanation, but I’ll provide details on each command for clarity:
- Download and extract the older version of OpenSSL, in this case, version 1.1.1:
$ wget https://www.openssl.org/source/openssl-1.1.1w.tar.gz
$ tar zxvf openssl-1.1.1w.tar.gz
- Set an environment variable called
OPENSSL
that points to the directory where we’ll installOpenSSL
$ export OPENSSL=$HOME/.openssl/openssl-1.1.1w
- Now that we have the OpenSSL archive unpacked and the
OPENSSL variable
set, we’ll configure the installation using the./config
command.
$ cd openssl-1.1.1w
$ ./config --prefix=$OPENSSL --openssldir=$OPENSSL
-
--prefix=$OPENSSL
— Specifies the installation directory for OpenSSL. -
--openssldir=$OPENSSL
— Specifies where OpenSSL will store its configuration files and certificates.
- With the configuration complete, we’ll build and install OpenSSL -
$ make
$ make test
$ make install
- Since we’re installing an older version of OpenSSL, it’s better to remove any existing certificates (if they exist) that could conflict with the new installation. So, we’ll remove the certificates directory:
$ rm -rf $OPENSSL/certs
- Now, we’ll
symlink
from theOPENSSL/certs
directory to the system’s default certificate directory/etc/ssl/certs
.
$ ln -s /etc/ssl/certs $OPENSSL/certs
- With OpenSSL installed, we can now install an older version of ruby using the
rbenv
$ RUBY_CONFIGURE_OPTS=--with-openssl-dir=$OPENSSL rbenv install 2.7.8
The RUBY_CONFIGURE_OPTS
variable specifies the options to pass to the ruby build process, and --with-openssl-dir=$OPENSSL
tells ruby to use the OpenSSL installation in the directory specified by the OPENSSL
variable, which we set previously.
Make sure, you’ve gem "jekyll", github: "jekyll/jekyll"
in your Gemfile
. That’s it.
Cheers