
Inhaltsverzeichnis

Reek ist ein Tool, das Ruby -Klassen, Module und Methoden untersucht und alle Codegerüche berichtet, die es findet.
Eine hervorragende Einführung in Codegerüche und Reek finden Sie diesen Blog -Beitrag oder diesen. Es gibt auch diesen Vortrag von RubyConfby (es gibt auch ein Dia -Deck, wenn Sie dies bevorzugen).
Installieren Sie es über Rubygemems:
gem install reekund laufen Sie so aus:
reek [options] [dir_or_source_file] * Stellen Sie sich eine Quelldatei demo.rb vor, die::
# Smelly class
class Smelly
# This will reek of UncommunicativeMethodName
def x
y = 10 # This will reek of UncommunicativeVariableName
end
endReek meldet die folgenden Codegerüche in dieser Datei:
$ reek --no-documentation demo.rb
Inspecting 1 file(s):
S
demo.rb -- 2 warnings:
[4]:UncommunicativeMethodName: Smelly#x has the name 'x'
[5]:UncommunicativeVariableName: Smelly#x has the variable name 'y'
Reek wird offiziell für Kruby 3.0 bis 3.3 und für Jruby 9.4 unterstützt. Andere Ruby -Implementierungen (wie Rubinius) werden nicht offiziell unterstützt, sollten aber auch funktionieren.
Beachten Sie, dass Reek auf jeder Ruby -Version den Parser für diese Version von Ruby verwendet. Sie sollten also immer Reek mit einer der Ziel -Ruby -Versionen Ihres Projekts ausführen.
Reek konzentriert sich auf hochrangige Code-Gerüche, sodass wir Ihnen nicht sagen können, wie Sie Warnungen generisch beheben können. Dies ist und wird immer vollständig von Ihrer Domain -Sprache und -geschäftslogik abhängig sein.
Trotzdem könnte ein Beispiel Ihnen helfen, loszulegen. Schauen Sie sich diese Probe eines Ruby on Rails -Modells an (Beachten Sie, dass dies abgeschnitten ist und keinen Arbeitscode):
class ShoppingCart < ActiveRecord :: Base
has_many :items
def gross_price
items . sum { | item | item . net + item . tax }
end
end
class Item < ActiveRecord :: Base
belongs_to :shopping_cart
endAusführen von Reek in dieser Datei wie dieser:
reek app/models/shopping_cart.rb
würde melden:
[5, 5]:ShoppingCart#gross_price refers to item more than self (FeatureEnvy)
Dies zu beheben ist ziemlich einfach. Fügen Sie die Bruttopreisberechnung für einen einzelnen Artikel ein, woher es hingehört. Dies wäre die Item :
class ShoppingCart < ActiveRecord :: Base
has_many :items
def gross_price
items . sum { | item | item . gross_price }
end
end
class Item < ActiveRecord :: Base
belongs_to :shopping_cart
def gross_price
net + tax
end
endDer Code riecht möglicherweise weitere Hinweise. Schauen Sie sich diese zuerst an, wenn Sie eine Warnung haben, dass Sie nicht wissen, wie Sie umgehen sollen.
Es gibt mehrere Möglichkeiten, wie Sie Reek an Quellen arbeiten können, das am häufigsten gerechte Wesen
reek lib/Wenn Sie keine Quellenargumente an die Leinwand übergeben, nimmt es nur das aktuelle Arbeitsverzeichnis als Quelle.
Also
reekist genau das Gleiche wie explizit:
reek .Zusätzlich können Sie Code so leiten, wie folgt wie folgt nachliegt:
echo " class C; def m; end; end " | reekDies würde ausdrucken:
$stdin -- 3 warnings:
[1]:C has no descriptive comment (IrresponsibleModule)
[1]:C has the name ' C ' (UncommunicativeModuleName)
[1]:C#m has the name ' m ' (UncommunicativeMethodName)Reek enthält derzeit Überprüfungen für einige Aspekte des Kontrollpaares, Datenklumpen, Feature Envy, große Klasse, lange Parameterliste, simuliertes Polymorphismus, zu viele Aussagen, unkomunikative Name, nicht verwendete Parameter und vieles mehr. Sehen Sie sich die Code an, um aktuelle Details zu genau zu erhalten, was Reek in Ihrem Code eingecheckt.
Spezielle Konfiguration für kontroverse Detektoren:
Die nicht verwendete private Methode ist standardmäßig deaktiviert, da sie umstritten ist, was bedeutet, dass Sie sie in Ihrer Konfiguration explizit aktivieren müssen
UnusedPrivateMethod :
enabled : trueDie Versorgungsfunktion ist ebenfalls ein kontroverser Detektor, der sich als wirklich unversöhnlich herausstellen kann. Infolgedessen haben wir es ermöglicht, es für nicht öffentliche Methoden wie diese zu deaktivieren:
---
UtilityFunction :
public_methods_only : true Für einen grundlegenden Überblick führen Sie aus
reek -- helpEine Zusammenfassung dieser CLI-Optionen finden Sie unter Befehlszeilenoptionen.
Das Konfigurieren von Reek über eine Konfigurationsdatei ist bei weitem die leistungsstärkste Weise. Reek erwartet, dass dieser Dateiname .reek.yml sein wird, aber Sie können dies über den CLI -c -Switch überschreiben (siehe unten).
Es gibt drei Möglichkeiten, um die Konfigurationsdatei zu übergeben:
-c -Switchs (siehe Befehlszeilenschnittstelle oben)Die Reihenfolge, in der Reek versucht, eine solche Konfigurationsdatei zu finden, ist genau die oben genannte: Zuerst überprüft es, ob wir eine Konfigurationsdatei explizit über CLI gegeben haben. Anschließend überprüft es das aktuelle Arbeitsverzeichnis auf eine Datei, und wenn es keine finden kann, durchquert es die Verzeichnisse, bis es das Stammverzeichnis trifft. Zuletzt überprüft es Ihr Heimverzeichnis.
Sobald Reek eine Konfigurationsdatei erkennt, wird sie sofort nicht mehr gesucht, was bedeutet, dass aus Sicht von Reek genau eine Konfigurationsdatei und eine Konfiguration vorhanden ist, unabhängig davon, wie viele *.reek -Dateien Sie möglicherweise in Ihrem Dateisystem haben.
Wir haben uns sehr bemüht, die Konfiguration von Reek so selbst erklärend wie möglich zu gestalten. Der beste Weg, um dies am besten zu verstehen, besteht darin, ein einfaches Beispiel zu betrachten (z .reek.yml in Ihrem Projektverzeichnis):
---
# ## Generic smell configuration
detectors :
# You can disable smells completely
IrresponsibleModule :
enabled : false
# You can use filters to silence Reek warnings.
# Either because you simply disagree with Reek (we are not the police) or
# because you want to fix this at a later point in time.
NestedIterators :
exclude :
- " MyWorker#self.class_method " # should be refactored
- " AnotherWorker#instance_method " # should be refactored as well
# A lot of smells allow fine tuning their configuration. You can look up all available options
# in the corresponding smell documentation in /docs. In most cases you probably can just go
# with the defaults as documented in defaults.reek.yml.
DataClump :
max_copies : 3
min_clump_size : 3
# ## Directory specific configuration
# You can configure smells on a per-directory base.
# E.g. the classic Rails case: controllers smell of NestedIterators (see /docs/Nested-Iterators.md) and
# helpers smell of UtilityFunction (see docs/Utility-Function.md)
#
# Note that we only allow configuration on a directory level, not a file level,
# so all paths have to point to directories.
# A Dir.glob pattern can be used.
directories :
" web_app/app/controllers " :
NestedIterators :
enabled : false
" web_app/app/helpers** " :
UtilityFunction :
enabled : false
" web_app/lib/**/test/** " :
UtilityFunction :
enabled : false
# ## Excluding directories
# Directories and files below will not be scanned at all
exclude_paths :
- lib/legacy
- lib/rake/legacy_tasks
- lib/smelly.rbWie Sie oben sehen, besteht die Konfiguration von Reek aus 3 verschiedenen Abschnitten, die mit 3 verschiedenen Schlüssel bezeichnet werden:
Was auch immer Sie zu Ihrer Konfiguration hinzufügen, sollte unter einem dieser Schlüssel abgebildet werden.
Wenn Sie eine Verzeichnisrichtlinie haben, für die eine Standardanweisung besteht, hat die spezifischere (was die Verzeichnisrichtlinie) Vorrang.
Diese Konfiguration beispielsweise:
---
detectors :
IrresponsibleModule :
enabled : false
TooManyStatements :
max_statements : 5
directories :
" app/controllers " :
TooManyStatements :
max_statements : 10übersetzt zu:
Jeder Geruchsmelder unterstützt unsere grundlegenden Geruchsoptionen. Wie Sie oben sehen können, bieten bestimmte Geruchstypen eine Konfiguration, die über die der grundlegenden Geruchsoptionen hinausgeht, beispielsweise Datenklumpen. Alle Optionen, die über die grundlegenden Geruchsoptionen hinausgehen, sind auf der entsprechenden Geruchstyp /DOCS -Seite dokumentiert (wenn Sie einen schnellen Überblick über alle möglichen Konfigurationen erhalten möchten, können Sie auch die Datei defaults.reek.yml in diesem Repository überprüfen.
Beachten Sie, dass Sie überhaupt keine Konfigurationsdatei benötigen. Wenn Sie mit all den Standardeinstellungen, die wir festlegen, in Ordnung sind, können Sie dies vollständig überspringen.
Machen Sie sich keine Sorgen, dass Sie einen Fehler in Ihrer Konfigurationsdatei einführen, der möglicherweise unbemerkt bleibt. Reek verwendet ein Schema, um Ihre Konfiguration beim Start zu validieren, und scheitert lautstark, falls Sie eine Option falsch geschrieben haben oder den falschen Datentyp für einen solchen Wert verwendet haben:
Error: We found some problems with your configuration file: [/detectors/DetectorWithTypo] key 'DetectorWithTypo:' is undefined.
Reek nimmt eine Konfigurationsdatei und eine Konfigurationsdatei nur mit .reek.yml als Standardname.
Falls Sie über eine oder mehrere Konfigurationsdateien im Verzeichnis verfügen (z. B. Sie spielen mit unterschiedlichen, gegenseitig ausschließlichen Einstellungen), müssen Sie Reek explizit mitteilen, welche Datei über reek -c config.reek verwendet werden soll.
Falls Sie eine Geruchswarnung unterdrücken müssen und aus welchen Gründen auch keine Konfigurationsdateien verwenden können oder nicht, können Sie auch spezielle Quellcode -Kommentare wie folgt verwenden:
# This method smells of :reek:NestedIterators
def smelly_method foo
foo . each { | bar | bar . each { | baz | baz . qux } }
endSie können sogar Geruchspezifische Konfigurationseinstellungen übergeben:
# :reek:NestedIterators { max_allowed_nesting: 2 }
def smelly_method foo
foo . each { | bar | bar . each { | baz | baz . qux } }
endDies ist ein unglaublich starkes Merkmal und erklärt unter Geruchsunterdrückung weiter.
Mit dem dynamischen Mechanismus des Reeks, um eine Konfigurationsdatei zu finden, können Sie eine Situation begegnen, in der Sie nicht zu 100% sicher sind, welche Konfigurationsdatei Reek verwendet. Zum Beispiel haben Sie eine projektspezifische Konfigurationsdatei in Ihrem Projektroot und eine weitere Reek -Konfiguration in Ihrem Heimverzeichnis, die Sie für alle anderen Projekte verwenden, und aus irgendeinem Gründe, aus denen Reek eine andere Konfigurationsdatei zu verwenden scheint, als die von Ihnen angenommene, dies würde dies tun.
In diesem Fall können Sie das Flag --show-configuration-path an Reek übergeben, was dazu führt, dass Reek den Pfad in die verwendete Konfigurationsdatei ausgibt.
Das Integrieren von Tools wie Reek in eine vorhandene größere Codebasis kann entmutigend sein, wenn Sie zuerst möglicherweise Hunderte oder Tausende von Geruchswarnungen beheben müssen. Sicher können Sie Geruchswarnungen manuell deaktivieren, wie oben gezeigt, aber abhängig von der Größe Ihrer Codebasis ist dies möglicherweise keine Option. Glücklicherweise bietet Reek ein Todo -Flag, mit dem Sie eine Konfiguration erstellen können, mit der alle Geruchswarnungen für die aktuelle Codebasis unterdrückt werden:
reek --todo lib/Dadurch wird die Datei '.reek.yml' in Ihrem aktuellen Arbeitsverzeichnis erstellt.
Sie können dies dann als Ihre Konfiguration verwenden. Da Ihr Arbeitsverzeichnis wahrscheinlich Ihr Projektrouch in den meisten Fällen ist, müssen Sie Reek nicht explizit sagen, dass sie verwenden sollen. Siehe das Laden der Konfiguration oben.
Wenn Sie sich aus irgendeiner Gründe entscheiden, sich zu sagen.
reek -c whatever/.reek.yml lib/ Es ist wichtig zu verstehen, dass der Uses --todo Nummer eins der Flagge zu Beginn der Einführung von Reek einmal ausgeführt werden soll, um den Übergang zu erleichtern. Wenn Sie die Reek mit der Flagge --todo Flagge erneut ausführen möchten, um viele neue Warnungen zum Schweigen zu bringen, besiegen Sie den Zweck sowohl der --todo als auch der Flagge und des Reek selbst.
Infolgedessen wird es nicht vorhanden sein, dass es nicht vorhanden ist, mit der Flagge --todo -Flagge eine vorhandene ". Außerdem wird keine andere Konfigurationsdatei in Rechnung gestellt.
Das bedeutet, dass beim Laufen
reek -c other_configuration.reek --todo lib/ other_configuration.reek wird einfach ignoriert.
Natürlich können Sie immer die vorhandene Datei .reek.yml löschen und dann mit der Flagge --todo -Flagge ausführen, aber denken Sie daran, dass dies nicht der beabsichtigte Anwendungsfall dieser Funktion ist.
Neben dem Offensichtlichen
reek [options] [dir_or_source_file] *Es gibt noch einige andere Möglichkeiten, wie Sie Reek in Ihren Projekten verwenden können:
Das erste, was Sie nach dem Überprüfen des Quellcodes tun möchten, ist, Bundler auszuführen:
bundle install
Und dann die Tests durchführen:
bundle exec rspec spec/your/file_spec.rb # Runs all tests in spec/your/file_spec.rb
bundle exec rspec spec/your/file_spec.rb:23 # Runs test in line 23
bundle exec cucumber features/your_file.feature # Runs all scenarios in your_file.feature
bundle exec cucumber features/your_file.feature:23 # Runs scenario at line 23Oder führen Sie einfach die gesamte Testsuite aus:
bundle exec rake
Dadurch werden die Tests (RSPEC und GUCUMBER), Rubocop und Lereks selbst durchgeführt.
Eine weitere nützliche Rake -Aufgabe ist die console . Dadurch wird Sie direkt in eine Umgebung einwirft, in der Sie mit Reeks -Modulen und Klassen herumspielen können:
bundle exec rake console
irb(main):001> Reek::Examiner
=> Reek::Examiner
Sie können IRB auch verwenden, während Sie die Tests ausführen, indem Sie Folgendes an dem Punkt hinzufügen, an dem Sie mit dem Debuggen beginnen möchten:
binding . irbSchauen Sie sich unsere Entwickler -API an, um mehr Inspiration zu erhalten.
Von da an sollten Sie auschecken:
Wenn Sie keine Lust haben, sich mit Code die Hände schmutzig zu machen, können Sie uns noch andere Möglichkeiten helfen:
Wenn Sie auf Code -Klimaprobleme eingehen (z. B. den Codes -Duplikationsschwellenwert), möchten Sie möglicherweise in der Lage sein, das Codeklima gegen die Reek -Codebasis lokal auszuführen. Dazu müssen Sie Folgendes tun:
gem install codeclimatecodeclimate engines:install Jetzt können Sie verschiedene Code -Klima -Motoren ausführen, z. B. codeclimate analyze -e duplication
Reek unterstützt 6 Ausgangsformate:
--format html )--format yaml , siehe auch Yaml Berichte)--format json )--format xml )--format github ) Reek "Rails" -Freunden zu machen ist ziemlich einfach, da wir Verzeichnisse spezifische Konfigurationen unterstützen ( directory directives im Reek Talk). Fügen Sie dies einfach Ihrer Konfigurationsdatei hinzu:
directories :
" app/controllers " :
IrresponsibleModule :
enabled : false
NestedIterators :
max_allowed_nesting : 2
UnusedPrivateMethod :
enabled : false
InstanceVariableAssumption :
enabled : false
" app/helpers " :
IrresponsibleModule :
enabled : false
UtilityFunction :
enabled : false
" app/mailers " :
InstanceVariableAssumption :
enabled : false
" app/models " :
InstanceVariableAssumption :
enabled : falseSeien Sie jedoch vorsichtig. Reek fügt Ihre Konfigurationseinträge nicht zusammen. Wenn Sie bereits über eine Verzeichnisanweisung für "App/Controller" oder "App/Helpers" verfügen, müssen Sie diese Direktiven aktualisieren, anstatt das obige YAML -Beispiel in Ihre Konfigurationsdatei zu kopieren.
Eine nicht exexhustive Liste anderer statischer Codeanalysatoren, in denen Sie sich vielleicht befassen möchten:
Das Reek Core -Team besteht aus:
Der ursprüngliche Autor von Reek ist Kevin Rutherford.
Der Autor von Reeks Logo ist Sonja Heinen.
Bemerkenswerte Beiträge kamen von: