
목차

Reek은 Ruby 클래스, 모듈 및 방법을 검사하고 코드 냄새가 발견되는 도구입니다.
코드 냄새에 대한 훌륭한 소개 및 Reek 은이 블로그 게시물 또는 해당 블로그 게시물을 확인하십시오. Rubyconfby 의이 대화도 있습니다 (원하는 경우 슬라이드 데크도 있습니다).
Rubygems를 통해 설치하십시오.
gem install reek다음과 같이 실행하십시오.
reek [options] [dir_or_source_file] * 소스 파일 demo.rb 가 포함 된 것을 상상해보십시오.
# Smelly class
class Smelly
# This will reek of UncommunicativeMethodName
def x
y = 10 # This will reek of UncommunicativeVariableName
end
endReek 은이 파일에서 다음 코드 냄새를보고합니다.
$ 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은 Cruby 3.0에서 3.3에서 3.3을 공식적으로 지원합니다. Rubinius와 같은 다른 Ruby 구현은 공식적으로 지원되지 않지만 작동해야합니다.
각 Ruby 버전에서 Reek은 해당 버전의 Ruby의 구문 분석기를 사용합니다. 따라서 프로젝트의 대상 루비 버전 중 하나를 사용하여 항상 Reek을 실행해야합니다.
Reek은 높은 수준의 코드 냄새에 중점을 두므로 경고를 일반적인 방식으로 고치는 방법을 알려주는 것입니다. 이것은 항상 도메인 언어 및 비즈니스 논리에 완전히 의존합니다.
즉, 그 예는 당신이가는 데 도움이 될 수 있습니다. Ruby on Rails 모델 의이 샘플을 살펴보십시오.
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
end이 파일에서 다음과 같이 reek를 실행합니다.
reek app/models/shopping_cart.rb
보고 할 것 :
[5, 5]:ShoppingCart#gross_price refers to item more than self (FeatureEnvy)
이것을 고치는 것은 매우 간단합니다. 속한 단일 품목에 대한 총 가격 계산을 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
end코드 냄새는 문서 냄새가 더 추가 힌트를 줄 수 있습니다. 처리 방법을 모르는 경고가있을 때 먼저 확인하십시오.
소스에서 Reek 작업을 수행 할 수있는 여러 가지 방법이 있습니다.
reek lib/소스 인수를 전달하지 않으면 현재 작업 디렉토리를 소스로 사용합니다.
그래서
reek명시적인 것과 똑같은 것입니다.
reek .또한 다음과 같이 코드를 파이프로 파이프 할 수 있습니다.
echo " class C; def m; end; end " | reek이것은 인쇄됩니다 :
$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에는 현재 제어 커플, 데이터 덩어리, 기능 부러움, 대규모 클래스, 긴 매개 변수 목록, 시뮬레이션 다형성, 너무 많은 진술, 비 통신 이름, 사용하지 않은 매개 변수 등의 일부 측면에 대한 검사가 포함되어 있습니다. REEK가 코드에서 확인할 내용에 대한 최신 세부 사항에 대한 코드 냄새를 참조하십시오.
논쟁의 여지가있는 탐지기를위한 특별 구성 :
사용하지 않는 개인 방법은 논란의 여지가 있기 때문에 기본적으로 비활성화되어 있습니다. 따라서 구성에서 명시 적으로 활성화해야합니다.
UnusedPrivateMethod :
enabled : true유틸리티 기능은 논란의 여지가있는 탐지기이기도하여 실제로 용서할 수없는 것으로 판명 될 수 있습니다. 결과적으로, 우리는 다음과 같은 비공개 방법에 대해 비활성화 할 수있게했습니다.
---
UtilityFunction :
public_methods_only : true 기본 개요의 경우 실행하십시오
reek -- help해당 CLI 옵션을 요약하려면 명령 줄 옵션을 참조하십시오.
구성 파일을 통해 REEK를 구성하는 것이 가장 강력한 방법입니다. Reek 은이 파일 이름이 .reek.yml 일 것으로 기대하지만 CLI -c 스위치를 통해이를 재정의 할 수 있습니다 (아래 참조).
구성 파일을 다시 전달하는 세 가지 방법이 있습니다.
-c 스위치 사용 (위의 명령 줄 인터페이스 참조)Reek이 그러한 구성 파일을 찾으려고 시도하는 순서는 위의 것입니다. 먼저 CLI를 통해 명시 적으로 구성 파일을 주었는지 확인합니다. 그런 다음 파일의 현재 작업 디렉토리를 확인하고 파일을 찾을 수없는 경우 루트 디렉토리에 도달 할 때까지 디렉토리를 통과합니다. 마지막으로 홈 디렉토리를 확인합니다.
Reek이 구성 파일을 감지하자마자 즉시 검색이 중지됩니다. 즉, Reek의 관점에서 파일 시스템에 가질 수있는 *.reek 파일 수에 관계없이 정확히 하나의 구성 파일과 하나의 구성이 존재 함을 의미합니다.
우리는 Reek의 구성을 가능한 한 자기 설명으로 만들기 위해 많은 노력을 기울여서 이해하는 가장 좋은 방법은 간단한 예를 보는 것입니다 (예 : 프로젝트 디렉토리의 .reek.yml ) :
---
# ## 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.rb위에서 볼 수 있듯이 Reek의 구성은 3 개의 다른 키로 표시되는 3 가지 다른 섹션으로 구성됩니다.
구성에 추가하든 해당 키 중 하나 아래에 스코핑되어야합니다.
기본 지침이 존재하는 디렉토리 지침이있는 경우 더 구체적인 디렉토리 (디렉토리 지침)가 우선합니다.
예를 들어이 구성 :
---
detectors :
IrresponsibleModule :
enabled : false
TooManyStatements :
max_statements : 5
directories :
" app/controllers " :
TooManyStatements :
max_statements : 10변환 :
모든 냄새 감지기는 기본 냄새 옵션을 지원합니다. 위에서 볼 수 있듯이 특정 냄새 유형은 기본 냄새 옵션을 넘어서는 구성을 제공합니다 (예 : 데이터 덩어리). 기본 냄새 옵션을 넘어선 모든 옵션은 해당 냄새 유형 /문서 페이지에 문서화되어 있습니다 (가능한 모든 구성에 대한 빠른 개요를 얻으려면이 저장소에서 defaults.reek.yml 파일을 확인할 수도 있습니다.
구성 파일이 필요하지 않습니다. 우리가 설정 한 모든 기본값으로 괜찮다면 완전히 건너 뛸 수 있습니다.
눈에 띄지 않을 수있는 구성 파일에 실수를 도입하는 것에 대해 걱정하지 마십시오. Reek은 스키마를 사용하여 시작시 구성을 검증하고 옵션을 틀거나 값에 대해 잘못된 데이터 유형을 사용한 경우 다음과 같은 경우 크게 실패합니다.
Error: We found some problems with your configuration file: [/detectors/DetectorWithTypo] key 'DetectorWithTypo:' is undefined.
REEK는 하나의 구성 파일과 하나의 구성 파일 만 가져와 .reek.yml 이 기본 이름입니다.
디렉토리에 하나 이상의 구성 파일이 있어야하는 경우 (예 : 다른 상호 배타적 인 설정으로 주변에 연주하고 있음) reek -c config.reek 통해 사용할 파일을 명시 적으로 명시 적으로 알려야합니다.
냄새 경고를 억제 해야하는 경우 어떤 이유로 든 구성 파일을 사용할 수 없거나 사용하지 않으려면 다음과 같은 특수 소스 코드 주석을 사용할 수 있습니다.
# This method smells of :reek:NestedIterators
def smelly_method foo
foo . each { | bar | bar . each { | baz | baz . qux } }
end냄새 특정 구성 설정을 전달할 수도 있습니다.
# :reek:NestedIterators { max_allowed_nesting: 2 }
def smelly_method foo
foo . each { | bar | bar . each { | baz | baz . qux } }
end이것은 엄청나게 강력한 특징이며 냄새 억제로 더 설명합니다.
구성 파일을 찾는 REEKS 동적 메커니즘을 사용하면 REEK가 어떤 구성 파일을 사용하고 있는지 100% 확신하지 못하는 상황이 발생할 수 있습니다. 예를 들어 프로젝트 루트에 프로젝트 별 구성 파일과 다른 모든 프로젝트에 사용하는 홈 디렉토리에 다른 REEK 구성 파일이 있으며 REEK가 가정 한 것보다 다른 구성 파일을 사용하는 것 같습니다.
이 경우 플래그 --show-configuration-path Reek에게 전달할 수있어 Reek가 사용중인 구성 파일의 경로를 출력하게됩니다.
Reek와 같은 도구를 기존의 더 큰 코드베이스에 통합하는 것은 먼저 수백 또는 수천 개의 냄새 경고를 해결해야 할 때 어려울 수 있습니다. 위에서 볼 수있는 냄새 경고를 수동으로 비활성화 할 수 있지만 코드베이스의 크기에 따라 옵션이 아닐 수도 있습니다. 다행스럽게도 Reek은 현재 코드베이스에 대한 모든 냄새 경고를 억제하는 구성을 생성하는 데 사용할 수있는 'Todo'플래그를 제공합니다.
reek --todo lib/현재 작업 디렉토리에 파일 '.reek.yml'이 생성됩니다.
그런 다음이를 구성으로 사용할 수 있습니다. 작업 디렉토리가 아마도 프로젝트 루트 일 수 있으므로 대부분의 경우 REEK를 명시 적으로 사용하여 '.reek.yml'을 명시 적으로 말할 필요가 없기 때문입니다. 위의 구성로드를 참조하십시오.
어떤 이유로든지 '.reek.yml'을 '.reek.yml'에 넣기로 결정한 경우 Reek가 자동으로 픽업하지 않는 곳에 다른 곳에있는 곳은 다음을 통해 Reek에게 명시 적으로 말해야합니다.
reek -c whatever/.reek.yml lib/ --todo 플래그의 가장 많이 사용 된 사례는 전환을 완화하기 위해 Reek의 도입을 시작할 때 한 번 실행해야한다는 것을 이해하는 것이 중요합니다. 당신이 자신이 --todo 플래그로 Reek를 다시 실행하고 싶어한다면, 많은 새로운 경고를 침묵시키기 위해 --todo 플래그와 Reek 자체의 목적을 물리 치고 있습니다.
결과적으로 --todo 플래그로 Reek을 실행하면 기존 '.reek.yml'을 덮어 쓰지 않고 실행을 중단합니다. 또한 고려할 수있는 다른 구성 파일도 가져 가지 않습니다.
이것은 당신이 달릴 때를 의미합니다
reek -c other_configuration.reek --todo lib/ other_configuration.reek 단순히 무시됩니다.
물론 항상 기존 .reek.yml 파일을 삭제 한 다음 --todo 플래그로 Reek를 실행할 수 있지만이 기능의 의도 된 사용 사례가 아니라는 점을 명심하십시오.
명백한 것 외에
reek [options] [dir_or_source_file] *프로젝트에서 Reek을 사용하는 방법은 몇 가지 있습니다.
소스 코드를 확인한 후 가장 먼저해야 할 일은 Bundler를 실행하는 것입니다.
bundle install
그런 다음 테스트를 실행합니다.
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 23또는 전체 테스트 스위트를 실행하십시오.
bundle exec rake
이것은 테스트 (RSPEC 및 오이), Rubocop 및 Reek 자체를 실행합니다.
또 다른 유용한 레이크 작업은 console 작업입니다. 이렇게하면 Reeks 모듈 및 클래스로 놀 수있는 환경으로 바로 들어갑니다.
bundle exec rake console
irb(main):001> Reek::Examiner
=> Reek::Examiner
디버깅을 시작하려는 시점에서 다음을 추가하여 테스트를 실행하는 동안 IRB를 사용할 수도 있습니다.
binding . irb더 많은 영감을 얻으려면 개발자 API를 살펴보십시오.
그때부터 당신은 다음을 확인해야합니다.
코드로 손을 더럽 히고 싶지 않다면 우리를 도울 수있는 다른 방법이 여전히 있습니다.
코드 기후 문제 (예 : 코드 복제 임계 값을 넘어서서)가 발생하면 Reek 코드베이스에 대해 코드 기후를 로컬로 실행할 수 있습니다. 이렇게하려면 다음을 수행해야합니다.
gem install codeclimatecodeclimate engines:install 이제 다양한 코드 기후 엔진 (예 : codeclimate analyze -e duplication 실행할 수 있습니다.
Reek은 6 개의 출력 형식을 지원합니다.
--format html )--format yaml , Yaml 보고서 참조)--format json )--format xml )--format github ) 디렉토리 별 구성 (Reek Talk의 directory directives )을 지원하기 때문에 Reek "Rails"-친선 경기를 만드는 것은 상당히 간단합니다. 구성 파일에 추가하기 만하면됩니다.
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 : false그러나 Reek는 구성 항목을 병합하지 않으므로 "App/Controllers"또는 "App/Helpers"에 대한 디렉토리 지침이 이미있는 경우 위의 YAML 샘플을 구성 파일에 복사하는 대신 해당 지시문을 업데이트해야합니다.
조사 할 수있는 다른 정적 코드 분석기의 비 실험 목록.
Reek Core 팀은 다음으로 구성됩니다.
Reek의 원래 저자는 Kevin Rutherford입니다.
Reek의 로고의 저자는 Sonja Heinen입니다.
주목할만한 기여는 다음과 같습니다.