Ruby Gems auf Windows verwenden - SASS und Compass

SASS, Compass, Breakpoint, SUSY, Singularity: wer mit CSS Preprocessing arbeitet, kennt diese Namen. CSS Dateien nicht mehr einfach so zu schreiben sondern über LESS oder SASS zu generieren, ist schon kein Hype mehr. Unter modernen Webdesignern hat es sich etabliert. Es gibt viele, die noch ohne CSS Preprocessing arbeiten, aber zumindest hat schon jeder davon gehört. Häufig hört man: "Oh ja, das wollte ich mir schon lange einmal angucken."

Ich arbeite schon seit ein paar Jahren mit SASS und auch SUSY. Was mir allerdings erst vor ein paar Tagen richtig bewusst wurde: All diese Plugins / Programme / Bibliotheken sind mit Ruby geschrieben. Da man sie über die Paketverwaltung Gems installiert, sind es Ruby Gems. So lange die Installation problemlos funktioniert, macht man sich keine Gedanken.

Wehe, wenn es nicht funktioniert

Doch die neueste Version von SUSY brachte mich ins Schleudern. Sie verwendet die neueste Version SASS 3.3.0+ von, das noch gar nicht released ist. Wenn man es zudem zusammen mit Compass verwenden will, braucht man auch da ein Pre-Release. Die Installation dieser Pre-Releases über CYGWIN, die ich bis jetzt immer verwendet habe, schlägt fehl. Man liest "Failed to build native extension", das klingt gar nicht gut. Willkommen in der Gem-Dependency-Hell.

Was nun? Ich mußte mich plötzlich mit der Materie auseinandersetzen. Strafverschärfend kam hinzu, daß wir für ein neues Projekt die gleichen Gems auch auf dem Mac eines Kollegen installieren wollten. Mit der Installation auf dem Mac kenne ich mich schon gar nicht aus. Und wer denkt, Ruby Gems auf dem Mac wären einfacher, sieht sich getäuscht. Mac Os X kommt mit einer vorinstallierten Version von Ruby. Dies entpuppt sich beim näheren Hinsehen als Danaergeschenk. Denn wenn die gewünschten Gems nicht mit der installierten Ruby-Version zusammenarbeiten, ist die Situation noch komplizieter als auf Windows. Auf Windows gibt es erstmal gar kein Ruby, aber dafür auch kein inkompatibles.

Zauberlehrling

Ich möchte nicht behaupten, schon wirklich durchzublicken, habe aber verschiedene Lösungsansätze probiert, die zumindest auf Windows funktionieren.
Zunächst einmal habe ich mich dafür entschieden, die Gems in Windows nativ zu betreiben, statt über CYGWIN. Cygwin stellt für Ruby eine zusätzliche Abstraktionsstufe da, da die Cygwin-Macher die Ruby-Versionen in CYGWIN einbinden. Man kann nicht einfach etwas von der Ruby-Seite herunterladen. Das gilt auch für verschiedene andere Komponenten.

Überraschenderweise geht der erwähnte native Weg viel einfacher: den Ruby Installer hernterladen, zum Zeitpunkt des Schreibens dieses Blopgosts wählte ich die Ruby-Version 1.9.3, damit funktioniert aktuell alles. Nach der Installation von Ruby gem update --system nicht vergessen. Von Gems sollte man immer die aktuelle Version haben.

Weiterhin habe ich mich vorerst dafür entschieden, den Pre-Release-Versionen von Compass etc. fernzubleiben, da das zusätzliche Probleme machen kann. Da SUSY mit seinem Wechsel der Syntax mir ohnehin Probleme bereitete, habe ich die Konkurrenz Singularity ausprobiert. Singularity macht im Prinzip das gleiche wie SUSY, allerdings beschränkt es sich auf weniger Funktionen. Man muß ein bisschen mehr mitdenken, und für Media Queries braucht man zusätzlich Breakpoint. Dafür gibt es keinen Syntax-Wechsel und soweit ich sehe keine Dependency auf Pre-Release-Versionen von SASS etc. Wer Pre-Release-Versionen verwenden will, braucht auf Windows das Ruby DevKit. In meiner Odyssee hatte ich dieses auch schon installiert, es funktioniert und lässt sich auch recht einfach einrichten.

Dependencies kontrollieren - aber richtig

Auf Tips von Kollegen und Leuten, die sich mit der Materie auskennen, stieß ich dann auf Bundler. Bundler ist irgendwas zwischen Package Manager und Dependency Manager, der zusätzlich zum eigentlichen Package Manager Gems installiert wird. Der Trick ist, dass man in einem Gemfile  definiert, welche Versionen von welcher Bibliothek installiert werden. Das wird dann in eine Datei  namens Gemfile.lock nochmal wesentlich präziser festgeschrieben.

Praktisch: das Gemfile und Gemfile.lock kann man direkt in das Theme des Projektes oder sonstwo in das Repository des Projektes legen. So können Kollegen, die mit am Projekt arbeiten, über das Gemfile die passenden Gems installieren. Auf der Singularity-Homepage und anderswo wird empfohlen, die Gems nur über Bundler zu installieren. So behält man die Kontrolle und alles wird transparenter. Es hat bei mir auch auf Anhieb geklappt.

Das aktuell empfohlene Gemfile für Singularity sieht z.B. so aus:

source 'https://rubygems.org'
gem
"sass", "~>3.2.0"
gem "compass", "~>0.12.0"
gem "singularitygs", "~>1.1.2"

Die Installationsquelle muß angegeben werden. rubygems.org empfiehlt sich, da es das zentrale Repository für alle Ruby Gems ist. Wenn wir jetzt in dem gleichen Ordner, in dem das Gemfile liegt, über das CMD Fenster - jawoll, ich verwende die Windows-Konsole - bundle install ausführen, dann werden allerhand Pakete installiert. Der eigentliche Trick ist, daß in diesem Schritt eine Gemfile.lock-Datei angelegt wird. In dieser sind die genauen Versionen aller installierten Pakete definiert:

GEM
  remote: https://rubygems.org/
  specs:
    breakpoint (2.0.7)
      compass (>= 0.12.1)
      sass (>= 3.2.0)
    chunky_png (1.3.0)
    compass (0.12.6)
      chunky_png (~> 1.2)
      fssm (>= 0.2.7)
      sass (~> 3.2.19)
    fssm (0.2.10)
    sass (3.2.19)
    singularitygs (1.1.2)
      breakpoint (>= 2.0.1)
      compass (>= 0.12.2)
      sass (>= 3.2.1)

PLATFORMS
  x86-mingw32

DEPENDENCIES
  compass (~> 0.12.0)
  sass (~> 3.2.0)
  singularitygs (~> 1.1.2)

Dieses gemfile.lock stellt sicher, daß auf dem nächsten Computer, auf dem bundle install ausgeführt wird, exakt die im gemfile.lock definierten Gem-Versionen installiert werden. Somit ist Konsistenz für das Projekt gewährleistet.

Wenn man das gemfile.lock und das gemfile vergleicht, dann sind vor allem die Versionen von Compass, Singularity, und SASS interessant, weil für diese ja im Gemfile schon grobe Versionen angegeben waren. Wir sehen, daß für SASS 3.2.x, also die neueste Version von 3.2 installiert wurde, aber eben nicht 3.3.x, da 3.3 noch nicht released ist. das ~> Zeichen bedeutet größer oder gleich. Sobald Sass 3.3 released wird, könnte mit diesem Gemfile auch SASS 3.3 installiert werden. Für unser aktuelles Projekt ist das allerdings nicht mehr relevant und auch nicht erwünscht. Dafür sorgt jedoch wie oben erwähnt unser gemfile.lock

Fortsetzung folgt

Auf dem Mac des Kollegen werden wir den nächsten Installationsversuch ebenfalls mit Bundler starten. Evtl. berichte ich dann hier von den Erfahrungen.