RuboCop 규칙 개발 가이드

우리의 코드베이스 스타일은 RuboCop에 의해 정의되고 강제됩니다.

bundle exec rubocop --parallel로 로컬에서 위반 사항을 확인할 수 있습니다. CI에서는 이를 static-analysis 작업에서 자동으로 확인합니다.

또한 지원되는 IDE에 RuboCop를 통합하여 Solargraph 젬을 사용할 수 있습니다.

우리가 결정을 내리지 않은 RuboCop 규칙을 위해 Ruby 스타일 가이드를 따라 직관적인 Ruby를 작성하세요.

리뷰어/유지보수자는 스타일에 대해 너그럽고 지나치게 까다롭지 않아야 합니다.

일부 RuboCop 규칙은 비활성화되어 있으며, 여기에 대해 리뷰어/유지보수자는 작성자에게 한 가지 스타일을 사용하도록 요청해서는 안 됩니다. 이상적으로는 이로 인해 bikeshedding으로 인해 여유 공간이 생깁니다. 이상적으로는 모든 RuboCop 규칙을 활성화하여 스타일 관련 토론, 지적, 또는 리뷰에서의 번복을 피해야 합니다. GitLab Ruby 스타일 가이드는 리뷰에서 자주 나오고 강제되지 않는 스타일의 비-최종 목록을 포함하고 있습니다.

추가로, 우리는 테스트별 스타일 가이드와 모범 사례를 갖고 있습니다.

규칙 인라인 비활성화

기본적으로 RuboCop 규칙은 인라인으로 비활성화되어서는 안 됩니다. 왜냐하면 이는 규칙이 코드베이스에 적용하려는 합의된 코드 표준을 무효화하기 때문입니다.

만약 인라인 비활성화를 사용해야 한다면, 비활성화된 규칙이 있는 같은 줄에 주석으로 이유를 제공해야 합니다. 이 인라인 비활성화 주석 위에 코드 주석에 더 많은 맥락이 들어갈 수 있습니다. 상세한 맥락을 제공하기 위해 리소스(이슈, 에픽, …)에 링크를 제공하면서 코드 주석의 장황함을 줄입니다.

임시 인라인 비활성화에는 rubocop:todo를 사용하고 추후 이슈를 링크합니다.

예시: ```ruby # 나쁨 module Types module Domain # rubocop:disable Graphql/AuthorizeTypes class SomeType < BaseObject if condition # rubocop:disable Style/GuardClause # 더 많은 논리… end

  object.public_send(action) # rubocop:disable GitlabSecurity/PublicSend
end
# rubocop:enable Graphql/AuthorizeTypes   end end

좋음

module Types module Domain # rubocop:disable Graphql/AuthorizeTypes – 부모 엔티티에서 이미 승인됨 class SomeType < BaseObject if condition # rubocop:todo Style/GuardClause – https://gitlab.com/gitlab-org/gitlab/-/issues/1234567890를 통해 정리 # 더 많은 논리… end

  # 이 시점에서 `action`은 `public_send`에서 안전하게 사용될 수 있습니다.
  # https://gitlab.com/gitlab-org/gitlab/-/issues/123457890을 참조하세요.
  object.public_send(action) # rubocop:disable GitlabSecurity/PublicSend -- 사용자 입력 확인됨
end
# rubocop:enable Graphql/AuthorizeTypes   end end ```

새로운 RuboCop 규칙 만들기

일반적으로 린트 규칙은 프로그램적으로 강제하는 것이 좋습니다. 이로써 이전에 언급한 bikeshedding이 줄어듭니다.

이를 위해, 우리는 코드베이스에 새로운 RuboCop 규칙을 만드는 것을 장려합니다.

특정 스타일을 적용하기 위한 새로운 규칙을 추가하기 전에 팀과 논의하는 것이 좋습니다.

우리는 여러 Ruby 코드베이스에 걸쳐 규칙을 유지하고 있으며, 그 중 일부는 GitLab 애플리케이션에만 특정된 것이 아닙니다. 여러 애플리케이션에 적용될 수 있는 새로운 규칙을 만들 때는 이를 gitlab-styles 젬에 추가하는 것을 장려합니다. 만약 규칙이 주로 GitLab 애플리케이션에 적용되는 것이라면, GitLab에 추가되어야 합니다.

규칙 유효기간

만약 YAML 구성에서 해당하는 세부사항: 유효기간이 정의된다면, 그 규칙은 _유효기간_에 있습니다.

기본 브랜치에서는 유예 기간의 규칙에서 위반 사항이 RuboCop CI 작업을 실패시키지 않습니다. 대신, 작업은 #f_rubocop Slack 채널에 알립니다. 그러나 다른 브랜치에서는 RuboCop 작업이 실패합니다.

유효기간은 1주일 동안 #f_rubocop 채널에서 경고가 없으면 안전하게 해제될 수 있습니다.

새로운 규칙 활성화

  1. 새로운 규칙을 .rubocop.yml에서 활성화합니다(이미 gitlab-styles를 통해 활성화되어 있지 않은 경우).
  2. 새로운 규칙을 위한 TODO 생성.
  3. 새로운 규칙을 유효기간으로 설정.
  4. TODO를 수정하고 커뮤니티 기여를 장려하는 이슈( ~"quick win" 또는 ~"Seeking community contributions"를 통해)를 만듭니다. 적절한 예시를 확인하세요.
  5. #f_rubocop Slack 채널에서 1주일 동안 조용하면 유효기간을 제거하기 위한 이슈를 만듭니다. 예시 확인.

음달한 위반 사항

경찰관의 유효 기간 동안 위반 사항이 음달되면 #f_rubocop Slack 채널은 2시간마다 알림 메시지를 받습니다.

이 문제를 해결하려면:

  1. 링크된 CI 작업에서 음달된 위반 사항을 가진 경찰관을 찾으세요.
  2. 이러한 경찰관을 위해 TODO 생성하세요.

RuboCop 노드 패턴

Ruby의 AST와 일치하는 노드 패턴을 생성할 때, scripts/rubocop-parse를 사용할 수 있습니다. 이는 Ruby 표현식의 AST를 보여주어 일치시키기 위해 도움이 됩니다. 또한 !97024도 참조하세요.

RuboCop 예외 해결

RuboCop 예외의 수가 기본 exclude-limit 15보다 많을 경우, 우리는 여러 커밋을 통해 예외를 해결하고 싶을 수 있습니다. 혼란을 최소화하기 위해, 우리는 예외 목록을 통해 진행 상황을 추적해야 합니다.

초기 목록이나 특정 RuboCop 규칙을 위한 목록을 생성하는 우선적인 방법rubocop:todo:generate Rake 작업을 실행하는 것입니다:

# 초기 목록
bundle exec rake rubocop:todo:generate

# 특정 RuboCop 규칙을 위한 목록
bundle exec rake 'rubocop:todo:generate[Gitlab/NamespacedClass,Lint/Syntax]'

이 Rake 작업은 .rubocop_todo/에 예외 목록을 생성하거나 업데이트합니다. 예를 들어, RuboCop 규칙 Gitlab/NamespacedClass의 구성은 .rubocop_todo/gitlab/namespaced_class.yml에 있습니다.

Rake 작업을 실행한 후 .rubocop_todo/의 모든 변경 사항을 커밋해야 합니다.

기존 RuboCop 예외 공개

.rubocop_todo.yml.rubocop_todo/**/*.yml를 통해 제외된 코드 내의 기존 RuboCop 예외를 공개하려면 환경 변수 REVEAL_RUBOCOP_TODO1로 설정하세요.

이를 통해 일상적인 작업 주기 중 기존 RuboCop 예외를 확인하고 수정할 수 있습니다.

참고: .rubocop_todo/**/*.yml 대신 .rubocop.yml에 영구적인 Exclude를 정의하세요.