Paketbaurichtlinien für Ruby

JRuby Gems: Obwohl Fedora ein voll funktionsfähiges JRuby enthält, das in die System-RubyGems integriert ist, haben wir uns entschieden, die JRuby-spezifischen Paketbaurichtlinien hier nicht aufzunehmen, da sie noch etwas Arbeit benötigen. Sie werden hier veröffentlicht, sobald wir der Meinung sind, dass alles vollständig abgedeckt ist. Bei Fragen zu den vorbereiteten JRuby-Paketierungsrichtlinien können Sie uns über die Ruby-SIG-Mailingliste kontaktieren.

Es gibt drei grundlegende Kategorien von Ruby-Paketen: RubyGems, [Nicht-Gem-Pakete (Ruby-Pakete ohne Gems)] und [Anwendungen (in Ruby geschriebene Anwendungen)]. Diese Richtlinien enthalten Abschnitte, die für alle diese Kategorien gelten, sowie Abschnitte, die jeweils für die einzelne Kategorie relevant sind. Lesen Sie unbedingt alle Richtlinien, die für den Typ des Ruby-Pakets gelten, den Sie erstellen.

Ruby-Kompatibilität

Jedes Ruby-Paket MUSS angeben, dass es von einem Ruby-Interpreter abhängt (dies gilt nicht für RubyGems). Verwenden Sie dazu das virtuelle „Provides“ ruby(release):

Requires: ruby(release)

Falls das Paket Ruby in einer oder mehreren Versionen benötigt, geben Sie die Abhängigkeit wie folgt versioniert an:

Requires: ruby(release) >= 1.9.1
Alternative Interpreter: Alternative Ruby-Interpreter (derzeit JRuby) erfordern ebenfalls Provide: ruby(release). Dies bedeutet, dass reine RubyGems-Pakete (die von allen Interpretern gemeinsam genutzt werden) NICHT Requires: ruby oder Requires: jruby enthalten sollten, damit ihre Abhängigkeiten von einem dieser Interpreter erfüllt werden.
Zu spezifische Versionsanforderungen für ruby(release): Bitte beachten Sie, dass eine zu spezifische ruby(release)-Versionsanforderung dazu führen kann, dass ein unerwarteter Interpreter verwendet wird. Beispielsweise benötigt ruby(release) = 1.8 das JRuby-Paket, da nur dieses es bereitstellt.

Kompatibilität zu verschiedenen Interpretern

Die meisten reinen Ruby-Pakete funktionieren auf allen Ruby-Interpretern. Es gibt jedoch Fälle, in denen Pakete interpreterspezifische Funktionen (wie fork()) verwenden und daher nicht auf anderen Interpretern (z.B. JRuby) laufen. In diesem Fall SOLLTE das Paket den entsprechenden Interpreter explizit angeben. Beispielsweise SOLLTE ein Paket, das fork() verwendet, explizit Requires: ruby angeben. Im Falle eines solchen Pakets SOLLTE der Paketierer einen Fehlerbericht einreichen, um die Entwickler zu bitten, Unterstützung für weitere Interpreter bereitzustellen. Dies SOLLTE in der Spec-Datei dokumentiert werden.

Shebang-Zeilen

Unter Fedora wird /usr/bin/ruby über Rubypick implementiert. Rubypick ist ein Werkzeug ähnlich wie RVM oder rbenv. Es ermöglicht die Auswahl des Interpreters zur Ausführung von Ruby-Skripten. Rubypick leitet alle über /usr/bin/ruby ausgeführten Befehle an /usr/bin/ruby-mri oder /usr/bin/jruby weiter. Standardmäßig wird MRI (Matz' Ruby-Implementation) verwendet, der Benutzer kann den Interpreter jedoch explizit mit _mri_ oder _jruby_ als erstem Parameter angeben. Zum Beispiel:

ruby _jruby_ jruby_script.rb
gem _mri_ install foo
rails _jruby_ s

Die Verwendung der Umgebungsvariablen RUBYPICK kann zum gleichen Ergebnis führen. Mit dieser Umgebungsvariablen kann ein bestimmter Interpreter als globaler Standard festgelegt werden:

export RUBYPICK=_jruby_
ruby jruby_script.rb  # verwendet jruby
gem install foo        # verwendet auch jruby

Ruby-Programme, die bekanntermaßen nur mit einer bestimmten Ruby-Implementierung laufen, SOLLTEN diese spezifische Implementierung in ihrem Shebang verwenden (#!/usr/bin/ruby-mri oder #!/usr/bin/jruby), um sicherzustellen, dass sie mit dieser Implementierung ausgeführt werden. Alle anderen Programme SOLLTEN #!/usr/bin/ruby verwenden.

Richtlinien zur Benennung

  • Pakete, die Ruby Gems enthalten, MÜSSEN nach demSchema rubygem-%{gem_name} benannt werden.

  • Der Name eines Ruby-Erweiterungs-/Bibliothekspakets MUSS mit dem Interpreter beginnen, für den es erstellt wurde (ruby, jruby usw.), gefolgt vom Namen des Upstream-Repositorys. Zum Beispiel: ruby-UPSTREAM. Enthält der Upstream-Name UPSTREAM das Präfix ruby, SOLLTE dieses aus dem Namen entfernt werden. Beispielsweise heißt der SQLite-Datenbanktreiber für Ruby sqlite3-ruby. Das entsprechende Fedora-Paket SOLLTE ruby-sqlite3 und nicht ruby-sqlite3-ruby heißen.

  • Anwendungspakete, die hauptsächlich Benutzerwerkzeuge bereitstellen, die in Ruby geschrieben sind, MÜSSEN stattdessen den allgemeinen Benennungsrichtlinien folgen.

Makros

Nicht-Gem-Ruby-Pakete und Ruby-Gem-Pakete werden an bestimmten Standardorten installiert. Die Pakete ruby-devel und rubygems-devel enthalten Makros, die für die jeweiligen Pakettypen nützlich sind. Alternative Ruby-Interpreter haben entsprechende Speicherorte (die später in diese Tabelle aufgenommen werden).

Makro Expandierter Pfad Verwendung

Aus ruby-devel; für nicht-gem-Pakete bestimmt.

%{ruby_vendorarchdir}

/usr/lib{64}/ruby/vendor_ruby

Ort für architekturspezifische Dateien (z.B. *.so).

%{ruby_vendorlibdir}

/usr/share/ruby/vendor_ruby

Ort für architekturunabhängige Dateien (z.B. *.rb).

%{ruby_sitearchdir}

/usr/local/lib{64}/ruby/site_ruby

Ort für lokale architekturspezifische Dateien (z.B. *.so).

%{ruby_sitelibdir}

/usr/local/share/ruby/site_ruby

Ort für lokale architekturunabhängige Dateien (z.B. *.rb).

Aus rubygems-devel; für gem-Pakete bestimmt.

%{gem_dir}

/usr/share/gems

Verzeichnis der obersten Ebene der Gem-Struktur.

%{gem_instdir}

%{gem_dir}/gems/%{gem_name}-%{version}

Verzeichnis mit dem eigentlichen Inhalt derGem.

%{gem_libdir}

%{gem_instdir}/lib

Der lib-Ordner der Gem.

%{gem_cache}

%{gem_dir}/cache/%{gem_name}-%{version}.gem

Die zwischengespeicherte Gem.

%{gem_spec}

%{gem_dir}/specifications/%{gem_name}-%{version}.gemspec

Die Gem-Spec-Datei.

%{gem_docdir}

%{gem_dir}/doc/%{gem_name}-%{version}

Die rdoc-Dokumentation des Gems.

%{gem_extdir_mri}

%{_libdir}/gems/ruby/%{gem_name}-%{version}

Das Verzeichnis für MRI Ruby-Gem-Erweiterungen.

Interpreter-Unabhängigkeit und Verzeichnis-Makros

Vielleicht ist Ihnen aufgefallen, dass die obige Tabelle unterschiedliche Verzeichnisse für Nicht-Gem-Bibliotheken auf verschiedenen Ruby-Interpretern enthält, aber nur einen einzigen Satz von Verzeichnissen für RubyGem-Bibliotheken. Das liegt daran, dass Code, der für einen Ruby-Interpreter geschrieben wurde, oft auf allen von Fedora mitgelieferten Ruby-Interpretern (ruby, jruby usw.) läuft. Allerdings verwendet mancher Code Methoden, die nicht auf allen Interpretern verfügbar sind (siehe [Different Interpreters Compatibility]). RubyGems bieten die Möglichkeit, verschiedene Versionen des Codes im selben Gem bereitzustellen, sodass das Gem auf allen Versionen des Interpreters ausgeführt werden kann. Daher benötigen wir nur ein gemeinsames Verzeichnis für RubyGems, das von allen Interpretern verwendet werden kann.

Die Standard-Ruby-Verzeichnisse %{vendorlib} bieten diese Möglichkeit nicht. Daher müssen Nicht-Gem-Bibliotheken in interpreterspezifischen Verzeichnissen abgelegt werden und benötigen für jeden unterstützten Interpreter ein separates Teilpaket (oder Paket, abhängig vom Upstream-Projekt).

Bibliotheken

Diese Richtlinien gelten nur für Ruby-Pakete, deren Hauptzweck die Bereitstellung einer Ruby-Bibliothek ist; Pakete, die hauptsächlich Benutzerwerkzeuge bereitstellen, die zufällig in Ruby geschrieben sind, MÜSSEN stattdessen den Ruby applications Guidelines folgen.

RubyGems

RubyGems sind Rubys eigenes Paketformat. Gems enthalten viele der gleichen Metadaten, die auch RPMs benötigen, wodurch eine reibungslose Interoperabilität zwischen RPMs und Gems ermöglicht wird. Diese Richtlinie stellt sicher, dass Gems so als RPMs verpackt werden, dass sie sich nahtlos in die übrige Distribution einfügen und es dem Endbenutzer ermöglichen, die Abhängigkeiten eines Gems durch die Installation des entsprechenden Gem-RPM-Pakets zu erfüllen.

RPMs und Gems verwenden ähnliche Terminologien; es gibt Spec-Dateien, Paketnamen, Abhängigkeiten usw. für beide. Um Verwirrung zu vermeiden, werden Begriffe im Zusammenhang mit Gem-Konzepten explizit mit dem Präfix „Gem“ bezeichnet, z.B. „Gem-Spezifikation“ (.gemspec). Ein nicht weiter qualifiziertes „Paket“ im Folgenden bezieht sich immer auf ein RPM-Paket.

  • Spec-Dateien MÜSSEN eine Definition von %{gem_name} enthalten, wobei es sich um den Namen aus der Gem-Spezifikation handelt.

  • Die Source des Pakets MUSS die vollständige URL zum veröffentlichten Gem-Archiv sein; die Version des Pakets MUSS der Version des Gems entsprechen.

  • Das Paket MUSS BuildRequires: rubygems-devel enthalten, um die für den Bauvorgang benötigten Makros einzubinden.

  • Es SOLLTEN KEINE Requires oder Provides für RubyGems aufgeführt sein, da diese automatisch generiert werden.

  • Es SOLLTE KEIN Requires: ruby(release) geben, es sei denn, Sie möchten explizit die Ruby-Versionskompatibilität angeben. Die automatisch generierte Abhängigkeit von RubyGems (Requires: ruby(rubygems)) ist ausreichend.

Filtern von „Requires“ und „Provides“

Die Laufzeitabhängigkeiten und -bereitstellungen (Requires und Provides) werden automatisch vom Abhängigkeitsgenerator von RPM generiert. Dieser kann jedoch gelegentlich zusätzliche Abhängigkeiten hinzufügen, die nicht der Realität entsprechen. Um dies zu beheben, muss der Abhängigkeitsgenerator außer Kraft gesetzt werden, damit die zusätzlichen Abhängigkeiten herausgefiltert werden können. Weitere Informationen finden Sie unter Automatisches Filtern von „Provides“ und „Requires“.

Gems erstellen

Da Gems nicht nur ein Archivformat sind, sondern sowohl ein Archiv als auch Informationen zum Erstellen der Ruby-Bibliothek enthalten, sieht das Erstellen eines RPM-Pakets aus einem Gem etwas anders aus als bei anderen RPM-Paketen.

Eine Beispiel-Spec-Datei für die Erstellung von Gems könnte folgendermaßen aussehen:

%prep
%autosetup -p1 -n  %{gem_name}-%{version}

# gemspec anpassen, falls nötig

%build
# gem erzeugen, da „gem install“ nur mit einer gem-Datei funktioniert
gem build ../%{gem_name}-%{version}.gemspec

# %%gem_install kompiliert alle C-Erweiterungen und installiert die gem in ./%%gem_dir
# per Vorgabe, so dass wir sie in %%install in buildroot verschieben können
%gem_install

%install
mkdir -p %{buildroot}%{gem_dir}
cp -a ./%{gem_dir}/* %{buildroot}%{gem_dir}/

# Falls Programme installiert wurden:
mkdir -p %{buildroot}%{_bindir}
cp -a ./%{_bindir}/* %{buildroot}%{_bindir}

# Falls C-Erweiterungen vorhanden sind, diese in extdir kopieren.
mkdir -p %{buildroot}%{gem_extdir_mri}
cp -a .%{gem_extdir_mri}/{gem.build_complete,*.so} %{buildroot}%{gem_extdir_mri}/
%prep

RPM (ab Version 4.14) kann Gem-Archive direkt entpacken. Daher können wir gem unpack aufrufen, um den Quellcode aus dem Gem zu extrahieren. Anschließend rufen wir %setup -n %{gem_name}-%{version} auf, um RPM mitzuteilen, in welches Verzeichnis das Gem entpackt wurde. Auf derselben Verzeichnisebene wird automatisch die Datei %{gem_name}-%{version}.gemspec erstellt. Diese .gemspec-Datei wird später zum Neuerstellen des Gems verwendet. Falls Änderungen an der .gemspec-Datei erforderlich sind (z. B. wenn die Version der Abhängigkeiten für Fedora nicht korrekt ist oder die .gemspec-Datei veraltete, nicht mehr unterstützte Felder verwendet), können diese hier vorgenommen werden. Auch Änderungen am Code selbst können hier vorgenommen werden.

%build

Als Nächstes erstellen wir das Gem. Da %gem_install nur mit Gem-Archiven arbeitet, erstellen wir das Gem anschließend mit gem build neu. Die so erstellte Gem-Datei wird dann von %gem_install verwendet, um den Code zu erstellen und im temporären Verzeichnis zu installieren, das standardmäßig ./%{gem_dir} ist. Dies ist notwendig, da der Befehl %gem_install den Code in einem Schritt erstellt und installiert. Daher benötigen wir ein temporäres Verzeichnis, um die erstellten Quellen vor der Installation im Abschnitt %install abzulegen.

Das Makro %gem_install akzeptiert zwei zusätzliche Optionen:

-n <gem_file>

Ermöglicht die Außerkraftsetzung des für die Installation verwendeten Gems. Dies kann für die Konvertierung älterer Spezifikationen nützlich sein, sodass Sie %{SOURCE0} als Gem für die Installation angeben können.

-d <install_dir>

Kann das Installationsziel des Gems außer Kraft setzen. Wir raten jedoch davon ab, diese Option zu verwenden.

Das Makro %gem_install DARF NICHT für die Installation in das %{buildroot}-Verzeichnis verwendet werden
%install

Hier installieren wir tatsächlich in das Verzeichnis %{buildroot}. Wir erstellen die benötigten Verzeichnisse und kopieren anschließend die installierten Dateien aus den temporären Verzeichnissen in die Verzeichnishierarchie %{buildroot}. Falls dieses Ruby-Gem gemeinsam genutzte Objekte erzeugt, werden diese schließlich in den architekturspezifischen Pfad %{gem_extdir_mri} verschoben.

Patchen erforderlicher Gem-Versionen

Ein häufiger Grund für Patches ist die Anpassung übermäßig strenger Versionsanforderungen in der Upstream-.gemspec-Datei. Dies kann daran liegen, dass die Upstream-.gemspec-Datei nur Versionen angibt, die explizit getestet wurden, wir aber wissen, dass auch andere Versionen funktionieren, oder weil wir wissen, dass die von uns ausgelieferten Pakete Korrekturen für problematisches Verhalten enthalten, ohne die Versionsnummer zu erhöhen (z.B. durch Backports). Um solche Abhängigkeiten anzupassen, können Sie die Makros %gemspec_add_dep und %gemspec_remove_dep verwenden.

Wenn Sie beispielsweise eine beliebige Version von Aruba anstelle der vom Upstream-Anbieter geforderten, sehr spezifischen Version verwenden möchten, können Sie im Abschnitt %prep die folgenden zwei Zeilen verwenden:

%gemspec_remove_dep -g aruba "~> 0.14.2"
%gemspec_add_dep -g aruba
Verwenden Sie Makros nur auf generierten .gemspec-Dateien: Die Makros %gemspec_add_dep und`%gemspec_remove_dep` funktionieren zuverlässig nur auf .gemspec-Dateien, die mit dem Befehl ruby spec generiert wurden. Bitte wenden Sie die Makros nicht auf Upstream-Dateien an.
Unbedingt testen: Ändern Sie die Version nicht einfach, ohne vorher zu testen, ob die neue Version funktioniert. Manchmal sind die Vorgaben des Upstream-Anbieters übermäßig streng, aber es gibt auch Fälle, in denen die Versionsanforderung aufgrund eines bestimmten Fehlers oder einer API-Änderung in einer Nebenversion festgelegt wurde.

Paketierung für Gem- und Nicht-Gem-Nutzung

Paketierung für die Verwendung mit Nicht-Gems nicht mehr erforderlich: Ursprünglich wurden RubyGem-Module nicht im Ruby-Bibliothekspfad abgelegt. Daher haben wir RubyGems so paketiert, dass sie sowohl mit Gems als auch mit Nicht-Gems verwendet werden können. Dies ermöglichte das Funktionieren von Code, der require('ARubyModulePackagedAsAGem'); verwendete. Das aktuelle rubygem-Modul fügt alle Gems dem Ruby-Bibliothekspfad hinzu, sobald es eingebunden wird. Daher dürfen Paketierer keine Teilpakete von RubyGems für neue Pakete erstellen, die nicht zu Gems kompatibel sind. Da die meisten Ruby-Pakete in Fedora nun als installierte Gems paketiert sind, müssen Sie möglicherweise den Code so früh wie möglich im Programm patchen, um require('rubygem') zu verwenden und so sicherzustellen, dass diese Ruby-Komponenten korrekt gefunden werden. Pakete für Ruby-Gems, die aktuell ein Nicht-Gem-Teilpaket erstellen, SOLLTEN so angepasst werden, dass dieses Teilpaket nicht mehr ausgeliefert wird (mit korrekten „Obsoletes“- und „Provides“-Einträgen im rubygem-Hauptpaket).

Nicht-Gem-Pakete

Nicht-Gem-Ruby-Pakete MÜSSEN das ruby-devel-Paket zur Bauzeit mit einem`BuildRequires: ruby-devel` einbinden und KÖNNEN die minimale Ruby-Version angeben, die sie zum Erstellen benötigen.

Bauarchitektur und Dateiplatzierung

Das Folgende betrifft nur die Dateien, die das Paket in die Verzeichnisse %{ruby_vendorarchdir} und %{ruby_vendorlibdir} (die eigentlichen Ruby-Bibliotheksdateien) installiert. Alle anderen Dateien in einem Ruby-Paket MÜSSEN den allgemeinen Fedora-Paketbaurichtlinien entsprechen.

Site versus Vendor: Bisher wurden %{ruby_sitelibdir} und`%{ruby_sitearchdir}` verwendet. Da diese jedoch nur für lokale Installationen vorgesehen sind, verwenden Sie bitte stattdessen %{ruby_vendorlibdir} und`%{ruby_vendorarchdir}`.

Reine Ruby-Pakete

Reine Ruby-Pakete müssen als architekturunabhängige Pakete („noarch“) erstellt werden.

Die Ruby-Bibliotheksdateien eines reinen Ruby-Pakets MÜSSEN in`%{ruby_vendorlibdir}` (oder dem entsprechenden Unterverzeichnis) abgelegt werden. Die Spec-Datei MUSSdieses Makro verwenden.

Ruby-Pakete mit binären Inhalten / gemeinsam genutzten Bibliotheken

Bei Paketen mit binären Inhalten, z.B. Datenbanktreibern oder anderen Ruby-Bindungen an C-Bibliotheken, muss das Paket architekturspezifisch sein.

Die Binärdateien eines Ruby-Pakets mit Binärinhalt MÜSSEN in`%{ruby_vendorarchdir}` (oder dem entsprechenden Unterverzeichnis) abgelegt werden. Die Ruby-Dateien ineinem solchen Paket SOLLTEN in %{ruby_vendorlibdir} abgelegt werden. Die Spec-DateiMUSS diese Makros verwenden.

Für Pakete, die gemeinsam genutzte C-Bibliotheken mit extconf.rb erstellen, SOLLTE

export CONFIGURE_ARGS="--with-cflags='%{optflags}'"

verwendet werden, um die CFLAGS korrekt an das Makefile zu übergeben, und um die Dateien während des Bauprozesses in die richtigen Verzeichnisse zu verschieben, muss --vendor an extconf.rb übergeben werden:

extconf.rb --vendor

Anwendungen

Anwendungen sind

  • Programme, die Werkzeuge auf Benutzerebene bereitstellen oder

  • Web-Anwendungen, die typischerweise mit Rails, Sinatra oder ähnlichen Frameworks erstellt werden.

Die RPM-Pakete MÜSSEN die FHS-Regeln einhalten. Sie SOLLTEN in`%{_datadir}` installiert werden. Das folgende Makro kann Ihnen dabei helfen:

%global app_root %{_datadir}/%{name}

Diese Pakete haben typischerweise keinen Provides-Abschnitt, da keine anderen Bibliotheken oder Anwendungen von ihnen abhängen.

Hier ein gekürztes Beispiel:

%global app_root %{_datadir}/%{name}

Summary: Deltacloud REST API
Name: deltacloud-core
Version: 0.3.0
Release: 3%{?dist}
Group: Development/Languages
License: Apache-2.0 AND MIT
URL: https://incubator.apache.org/deltacloud
Source:  https://rubygems.org/gems/%{name}-%{version}.gem
Requires: rubygem-haml
#...
Requires(post):   chkconfig
#...
BuildRequires: rubygem-haml
#...
BuildArch: noarch

%description
The Deltacloud API is built as a service-based REST API.
You do not directly link a Deltacloud library into your program to use it.
Instead, a client speaks the Deltacloud API over HTTP to a server
which implements the REST interface.

%package doc
Summary: Documentation for %{name}
Group: Documentation
Requires:%{name} = %{version}-%{release}

%description doc
Documentation for %{name}

%prep
%setup -q -n %{name}-%{version}

%build

%install
mkdir -p %{buildroot}%{app_root}
mkdir -p %{buildroot}%{_initddir}
mkdir -p %{buildroot}%{_bindir}
cp -r * %{buildroot}%{app_root}
mv %{buildroot}%{app_root}/support/fedora/%{name} %{buildroot}%{_initddir}
find %{buildroot}%{app_root}/lib -type f | xargs chmod -x
chmod 0755 %{buildroot}%{_initddir}/%{name}
chmod 0755 %{buildroot}%{app_root}/bin/deltacloudd
rm -rf %{buildroot}%{app_root}/support
rdoc --op %{buildroot}%{_defaultdocdir}/%{name}

%post
# This adds the proper /etc/rc*.d links for the script
/sbin/chkconfig --add %{name}

%files
%{_initddir}/%{name}
%{_bindir}/deltacloudd
%dir %{app_root}/
%{app_root}/bin
#...

%files doc
%{_defaultdocdir}/%{name}
%{app_root}/tests
%{app_root}/%{name}.gemspec
%{app_root}/Rakefile

%changelog
#...

Beachten Sie, dass die Dateien, obwohl es sich um ein RubyGem handelt, manuell unter %{_datadir}/%{name}, %{_bindir} usw. installiert werden müssen, um dem Dateisystemhierarchiestandard (FHS) und den allgemeinen Paketbaurichtlinien zu entsprechen. Falls zusätzliche Fedora-spezifische Dateien (systemd-.service-Dateien, Konfigurationen) benötigt werden, SOLLTEN diese

  • über weitere %SOURCE-Tags hinzugefügt werden

Source1: deltacloudd-fedora
  • während der %install-Phase an den entsprechenden Stellen platziert werden

install -m 0755 %{SOURCE1} %{buildroot}%{_bindir}/deltacloudd

Test-Suiten ausführen

Falls für das Paket eine Test-Suite verfügbar ist (auch separat, z.B. nicht im Gem enthalten, aber im Upstream-Repository), sollte diese in %check ausgeführt werden. Die Testsuite ist das einzige automatisierte Werkzeug, das die grundlegende Funktionalität des Pakets sicherstellen kann. Ihre Ausführung ist besonders hilfreich bei Massen-Rebuilds. Sie können die Ausführung der Testsuite überspringen, wenn nicht alle Bauabhängigkeiten erfüllt sind. Dies muss jedoch in der Spec-Datei dokumentiert werden. Die fehlenden Bauabhängigkeiten zur Aktivierung der Testsuite sollten so schnell wie möglich für Fedora bereitgestellt und die Testsuite wieder aktiviert werden.

Die Tests SOLLTEN NICHT mit Rake ausgeführt werden, da Rake fast immer unnötige Abhängigkeiten wie hoe oder gemcutter mit sich bringt. Aus ähnlichen Gründen SOLLTE eine Abhängigkeit von Bundler vermieden werden. Auch Code-Coverage-Frameworks wie SimpleCov und Coveralls SOLLTEN vermieden werden.

Testen mit verschiedenen Ruby-Implementierungen

Um Tests mit verschiedenen Ruby-Implementierungen wie JRuby auszuführen, fügen Sie BuildRequires: jruby hinzu. Verwenden Sie anschließend die Interpreter-Umschaltung von Rubypick:

ruby _jruby_ -Ilib -e 'Dir.glob "./test/test_*.rb", &method(:require)'

Wenn Ihr Paket Unit-Tests für ruby-mri ausführt und unter alternativen Interpretern laufen soll, müssen die Unit-Tests auch unter allen alternativen Interpretern ausgeführt werden. Dies ist die einzige Möglichkeit, die Kompatibilität des Codes zu den einzelnen Interpretern zu überprüfen. Es gelten dieselben Regeln: Sie können diesen Schritt weglassen, wenn benötigte Bibliotheken für einen bestimmten alternativen Interpreter nicht verfügbar sind. Sie MÜSSEN jedoch einen Kommentar hinzufügen, der dies erläutert.

Verwendung von Test-Frameworks

Die Ruby-Community unterstützt zahlreiche Test-Frameworks. Die folgenden Abschnitte zeigen, wie man Test-suiten mit den gängigsten Frameworks ausführt.

MiniTest / Test::UNIT

MiniTest und Test::UNIT sind Bestandteil von Ruby. Um sie zu verwenden, müssen Sie BuildRequires: rubygem-minitest bzw. BuildRequires: rubygem-testunit verwenden. Zum Ausführen der Test-Suite können Sie beispielsweise Folgendes verwenden:

%check
ruby -Ilib -e 'Dir.glob "./test/**/*_test.rb", &method(:require)'

Möglicherweise müssen Sie -Ilib in -Ilib:test ändern oder ein leicht abweichendes Suchmuster für test_*.rb verwenden. Von Paketierern wird erwartet, dass sie für jedes Gem das richtige Muster verwenden.

RSpec

Um Tests mit RSpec >= 3 auszuführen, fügen Sie BuildRequires: rubygem-rspec hinzu und verwenden Sie beispielsweise Folgendes:

%check
rspec -Ilib spec

Test-Suites, die nicht im Paket enthalten sind

Manchmal müssen die Tests separat vom Gem-Paket des Upstream-Projekts bezogen werden. Nehmen wir beispielsweise an, Sie erstellen ein Paket für rubygem-delorean, Version 1.2.0, das auf GitHub gehostet wird. Die Tests sind nicht im Gem selbst enthalten, daher müssen Sie sie separat beziehen und die Spec-Datei entsprechend anpassen:

# git clone https://github.com/bebanjo/delorean.git && cd delorean
# git checkout v1.2.0
# tar -czf rubygem-delorean-1.2.0-specs.tgz spec/
Source1: %{name}-%{version}-specs.tgz

# ...
%prep
%setup -q -n %{gem_name}-%{version} -b 1

# ...

%check
pushd ./%{gem_instdir}
# Link the test suite into the right place in source tree.
ln -s %{_builddir}/spec .

# Run tests
rspec spec
popd

# ...
  • Achten Sie darauf, die Version der Tests im Quellnamen anzugeben, damit rpmbuild beim Aktualisieren auf eine neue Version fehlschlägt, weil es das richtige %{SOURCE1} nicht findet (und dies erinnert Sie auch daran, die Tests zu aktualisieren).

  • Fügen Sie die Befehle, die Sie zum Abrufen der Tests verwendet haben, als Kommentare in die Spec-Datei ein. Dadurch wird es Ihnen beim nächsten Mal deutlich leichter fallen, sie abzurufen.

  • Führen Sie die Tests wie gewohnt durch.