Kód futtatása gem alapú Jekyll témában

A blogom Wordpressről Jekyllre konvertálása közben belefutottam abba a furcsa problémába, hogy a gem alapú témákban vajon hogyan lehet Ruby kódot futtatni. Erre azért volt szükség, mert a blog Bootstrap frameworköt használ, és azt egy az egyben lehet telepíteni a bootstrap-sass gemből. De ilyenkor jó lenne a gem útvonalát dinamikusan megtalálni.

Probléma

A problémát az adja, hogy a gem telepítésének módjától függően vagy lefut, vagy nem fut le egy adott kód a gemspec fájlból. Hogy mindezt lássuk működés közben, generáljunk egy kezdő jekyll portált, és egy gemet a bundlerrel:

jekyll new jekyll-test
bundle gem jekyll_theme_test

A jekyll-test portálban cseréljük le a minimat a jekyll-theme-testre:

jekyll-test/_config.yml
# theme: minima
theme: jekyll_theme_test

A jekyll-theme-testben pedig irassunk ki néhány dolgot, hogy lássuk mi történik:

jekyll_theme_test/jekyll_theme_test.gemspec
Gem::Specification.new do |spec|
  puts 'jekyll-theme-test: gemspec'
  spec.name          = "jekyll_theme_test"
jekyll-theme-test/lib/jekyll_theme_test.rb
require "jekyll_theme_test/version"

module JekyllThemeTest
  class Error < StandardError; end
  # Your code goes here...
  puts 'jekyll-theme-test: jekyll_theme_test.rb'
end

A változtatások után adjunk mindent a githez, és commitoljunk egyet. Ha van távoli git kiszolgálónk, akkor pusholhatunk is.

cd jekyll_theme_test
git add ./
git commit -m "Initial commit"

Ezután koncentráljunk a jekyll-test portálra. Először húzzuk be a jekyll-theme-test modult lokális git tárolóként:

jekyll-test/Gemfile
# This is the default theme for new Jekyll sites. You may change this to anything you like.
# gem "minima", "~> 2.0"
gem "jekyll_theme_test", :git => "git@localhost:jekyll_theme_test", :branch => "master"

Majd adjuk ki ezt a parancsot:

bundle config local.jekyll_theme_test /path/to/jekyll_theme_test

Ezután indíthatjuk a buildet:

bundle exec jekyll build

A kimenetben látni fogjuk, hogy a gemspec feldolgozódik a buildkor:

jekyll-theme-test: gemspec
Configuration file: /var/www/jekyll-test/_config.yml
            Source: /var/www/jekyll-test
       Destination: /var/www/jekyll-test/_site
 Incremental build: disabled. Enable with --incremental
      Generating...
       Jekyll Feed: Generating feed for posts
     Build Warning: Layout 'post' requested in _posts/2019-09-14-welcome-to-jekyll.markdown does not exist.
     Build Warning: Layout 'default' requested in 404.html does not exist.
     Build Warning: Layout 'page' requested in about.md does not exist.
     Build Warning: Layout 'home' requested in index.md does not exist.
                    done in 0.919 seconds.
 Auto-regeneration: disabled. Use --watch to enable.

Most elkezdhetnénk örülni, hiszen már csak annyi lenne a dolgunk, hogy a gemspecbe még egy require-t teszünk a fő modulra. Azonban ne örüljünk korán, hanem próbáljuk ki telepített gemként is a témánkat.

Hozzuk létre a gemet a forrásból. Ehhez először töröljük az összes TODO sort a gemspecből, különben hibát fogunk kapni.

cd jekyll_theme_test
sed -i 's/TODO//' jekyll_theme_test.gemspec
rake build

Majd a kapott gemet telepítsük:

gem install pkg/jekyll_theme_test-0.1.0.gem

Ezután menjük vissza a jekyll-test portálba, és vegyük ki a git tárolóra utaló szabályokat, hogy az előbb feltelepített gemet használjuk:

jekyll-test/Gemfile
# This is the default theme for new Jekyll sites. You may change this to anything you like.
# gem "minima", "~> 2.0"
gem "jekyll_theme_test", "~> 0.1.0"

Majd építsük újra a portált:

cd jekyll-test
bundle exec jekyll build

Ezután látni fogjuk, hogy a gemspec már nem ír ki nekünk semmit:

Configuration file: /var/www/jekyll-test/_config.yml
            Source: /var/www/jekyll-test
       Destination: /var/www/jekyll-test/_site
 Incremental build: disabled. Enable with --incremental
      Generating...
       Jekyll Feed: Generating feed for posts
     Build Warning: Layout 'post' requested in _posts/2019-09-14-welcome-to-jekyll.markdown does not exist.
     Build Warning: Layout 'default' requested in 404.html does not exist.
     Build Warning: Layout 'page' requested in about.md does not exist.
     Build Warning: Layout 'home' requested in index.md does not exist.
                    done in 0.62 seconds.
 Auto-regeneration: disabled. Use --watch to enable.

És itt a gond. Ami működik a lokális mappából, megszűnik működni, mihelyt feltelepítjük a gem fájlt. Ha a lokális mappát elhagyjuk, és egyenesen egy git kiszolgálóról szeretnénk telepíteni a dolgot, akkor sem fog működni, mert ebben az esetben a bundler lefuttat egy serializációt a gemspecre, és teljesen átírja annak a tartalmát.

Megoldás

A megoldás nagyon egyszerű. A témát nem témaként kell kezelnünk, hanem pluginként. Módosítsuk a jekyll-test portál Gemfile fájlját így:

jekyll-test/Gemfile
# This is the default theme for new Jekyll sites. You may change this to anything you like.
# gem "minima", "~> 2.0"
# gem "jekyll_theme_test", "~> 0.1.0"

# If you have any plugins, put them here!
group :jekyll_plugins do
  gem "jekyll-feed", "~> 0.6"
  gem "jekyll_theme_test", "~> 0.1.0"
end

Majd építsük újra:

cd jekyll-test
bundle exec jekyll build

És a kimeneten látni fogjuk, hogy a gemspec ugyan nem, de a jekyll_theme_test.rb lefutott:

jekyll-theme-test: jekyll_theme_test.rb
Configuration file: /var/www/jekyll-test/_config.yml
            Source: /var/www/jekyll-test
       Destination: /var/www/jekyll-test/_site
 Incremental build: disabled. Enable with --incremental
      Generating...
       Jekyll Feed: Generating feed for posts
     Build Warning: Layout 'post' requested in _posts/2019-09-14-welcome-to-jekyll.markdown does not exist.
     Build Warning: Layout 'default' requested in 404.html does not exist.
     Build Warning: Layout 'page' requested in about.md does not exist.
     Build Warning: Layout 'home' requested in index.md does not exist.
                    done in 0.583 seconds.
 Auto-regeneration: disabled. Use --watch to enable.

Ez a megoldás pedig működni fog minden telepítési módszer esetén.