Computer >> 컴퓨터 >  >> 프로그램 작성 >> Ruby

RuboCop을 사용한 루비 코드 린팅 및 자동 서식 지정

Linting은 프로그래밍 및 문체 오류에 대한 소스 코드의 자동 검사입니다. 이 검사는 linter라는 정적 코드 분석 도구에 의해 수행됩니다. 그러나 코드 포맷터는 미리 구성된 규칙 집합을 엄격하게 준수하도록 소스 코드의 형식을 지정하는 도구입니다. 린터는 일반적으로 위반 사항을 보고하지만 문제를 수정하는 것은 일반적으로 프로그래머에게 달려 있는 반면 코드 포맷터는 규칙을 소스 코드에 직접 적용하여 서식 오류를 자동으로 수정하는 경향이 있습니다.

프로젝트에서 보다 일관된 코드 스타일을 만드는 작업은 일반적으로 별도의 린트 및 서식 지정 도구를 도입해야 하지만 경우에 따라 단일 도구로 두 가지 문제를 모두 해결할 수 있습니다. 후자의 좋은 예는 이 기사에서 광범위하게 고려할 도구인 RuboCop입니다. Ruby 프로젝트에서 설정하고 출력이 예상과 일치하도록 구성 옵션을 조정하는 방법을 배웁니다. 로컬 개발 프로세스에 통합하는 것 외에도 지속적 통합 워크플로의 일부로 만드는 방법도 배우게 됩니다.

RuboCop 설치

RuboCop 설치는 RubyGems를 통해 간단합니다.

$ gem install rubocop

설치된 버전 확인:

$ rubocop --version
1.18.3

Bundler를 사용하려면 아래 스니펫을 Gemfile에 배치하세요. 그런 다음 bundle install를 실행합니다. . require: false 부분은 Bundler.require를 알려줍니다. 명령줄에서만 사용되므로 코드에 특정 gem을 요구하지 않습니다.

gem 'rubocop', require: false

설치된 버전 확인:

$ bundle exec rubocop --version
1.18.3

RuboCop 실행

rubocop를 입력하여 프로젝트의 기본 설정을 사용하여 RuboCop을 실행할 수 있습니다. (또는 bundle exec rubocop 번들러와 함께 설치된 경우). 명령에 인수를 전달하지 않으면 현재 디렉토리의 모든 Ruby 소스 파일과 모든 하위 디렉토리를 검사합니다. 또는 분석해야 하는 파일 및 디렉토리 목록을 전달할 수 있습니다.

$ bundle exec rubocop
$ bundle exec rubocop src/lib

구성이 없으면 RuboCop은 커뮤니티 기반 Ruby 스타일 가이드에 설명된 많은 가이드라인을 적용합니다. 명령을 실행한 후 몇 가지 오류(위반)가 발생할 수 있습니다. 보고된 각 위반 행위는 위반 사항에 대한 설명, 발생한 파일 및 줄 번호와 같이 이를 해결하는 데 필요한 모든 정보로 장식되어 있습니다.

RuboCop을 사용한 루비 코드 린팅 및 자동 서식 지정

보고서 맨 아래에 검사된 파일 수, 총 오펜스 수 및 자동으로 수정할 수 있는 오펜스 수를 설명하는 줄이 표시됩니다. -a를 추가하면 또는 --auto-correct 인수, RuboCop은 소스 파일에서 발견된 문제([Correctable] 접두사가 붙은 문제)를 자동으로 수정하려고 시도합니다. ).

$ bundle exec rubocop -a

RuboCop을 사용한 루비 코드 린팅 및 자동 서식 지정

수정된 각 위반 사항에 이제 [Corrected] 접두사가 붙는 방법을 확인하세요. . 수정된 위반 건수에 대한 요약도 보고서 하단에 표시됩니다. 위의 예에는 -a를 추가한 후에도 자동 수정되지 않은 수정 가능한 또 다른 위반이 있습니다. 깃발. 일부 자동 수정은 코드의 의미를 약간 변경할 수 있으므로 RuboCop은 코드를 안전하지 않은 것으로 간주합니다. 이러한 위반 사항도 자동 수정하려면 -A를 사용하십시오. 또는 --auto-correct-all 플래그.

$ bundle exec rubocop -A

RuboCop을 사용한 루비 코드 린팅 및 자동 서식 지정

따라야 할 좋은 경험 법칙은 자동 고침 기능을 사용한 후 테스트 스위트를 실행하여 코드 동작이 예기치 않게 변경되지 않았는지 확인하는 것입니다.

RuboCop 구성

RuboCop은 .rubocop.yml을 통해 구성할 수 있습니다. 프로젝트의 루트에 있는 파일. 모든 프로젝트에 대해 동일한 검사를 사용하려면 홈 디렉토리(~/.rubocop.yml)에 전역 구성 파일을 배치할 수 있습니다. ) 또는 XDG 구성 디렉토리(~/.config/rubocop/config.yml) ). 이 전역 구성 파일은 로컬 범위의 프로젝트 구성 파일이 현재 디렉토리 또는 연속적인 상위 디렉토리에 없는 경우 사용됩니다.

RuboCop의 기본 구성은 구성 홈 디렉토리(~/.config/rubocop/default.yml ) 및 다른 모든 구성 파일은 이 파일에서 상속합니다. 즉, 프로젝트 구성을 설정할 때 기본값과 다른 변경만 하면 됩니다. 이는 특정 검사를 활성화 또는 비활성화하거나 매개변수를 허용하는 경우 동작을 변경하는 것을 의미할 수 있습니다.

RuboCop은 각 개별 수표를 경찰이라고 하며 각 수표는 특정 범죄를 감지하는 책임이 있습니다. 사용 가능한 경찰도 다음 부서로 그룹화됩니다.

  • 스타일 경찰은 대부분 앞서 언급한 Ruby 스타일 가이드를 기반으로 하며 코드의 일관성을 확인합니다.
  • 레이아웃 경찰은 공백 사용과 같은 서식과 관련된 문제를 포착합니다.
  • 린트 경찰은 ruby -w와 유사하게 코드에서 가능한 오류를 감지합니다. , 그러나 많은 추가 검사가 필요합니다.
  • 메트릭 경찰은 클래스 길이 및 메서드 길이와 같은 소스 코드 측정과 관련된 문제를 다룹니다.
  • 네이밍 경찰은 명명 규칙에 관심이 있습니다.
  • 보안 경찰이 잠재적인 보안 문제를 포착하는 데 도움을 줍니다.
  • Bundler 경찰은 Bundler 파일(예:Gemfile)에서 잘못된 관행을 확인합니다. ).
  • Gemspec 경찰은 .gemspec에서 잘못된 관행을 확인합니다. 파일.

추가 린터 및 포맷터를 통해 RuboCop을 확장하는 것도 가능합니다. 자신의 확장을 구축하거나 프로젝트와 관련된 경우 기존 확장을 활용할 수 있습니다. 예를 들어, Rails 모범 사례 및 코딩 규칙을 시행하기 위한 목적으로 Rails 확장을 사용할 수 있습니다.

RuboCop을 사용한 루비 코드 린팅 및 자동 서식 지정

구성 파일을 처음 생성하면 추가되었지만 구성되지 않은 새 경찰이 있다는 경고 메시지가 많이 표시됩니다. 이는 RuboCop이 각 릴리스에 새 경찰을 추가하고 사용자 구성에서 명시적으로 활성화 또는 비활성화될 때까지 특수 보류 상태로 설정되기 때문입니다. 메시지에 나열된 각 경찰을 개별적으로 활성화 또는 비활성화하거나 아래 스니펫을 사용하여 모든 새 경찰을 활성화할 수 있습니다(권장). 이후에는 메시지가 표시되지 않습니다.

# .rubocop.yml
AllCops:
  NewCops: enable

구성 파일과 RuboCop에서 제공하는 다양한 옵션을 사용하고 싶지 않다면 Standard 프로젝트를 살펴보십시오. 규칙을 사용자 정의하지 않고 Ruby 프로젝트에서 일관된 스타일을 적용하는 것을 목표로 하는 RuboCop의 사전 구성된 버전입니다. 처음 발표된 라이트닝 토크에서 그 기원과 동기에 대해 자세히 설명합니다.

Gemfile에 다음 줄을 추가하여 설치할 수 있습니다. 그런 다음 bundle install를 실행합니다. .

# Gemfile
gem "standard", group: [:development, :test]

이후 다음과 같이 명령줄에서 Standard를 실행할 수 있습니다.

$ bundle exec standardrb

기존 프로젝트에 RuboCop 추가

대부분의 Rubyists는 미개발 프로젝트에서 일할 여유가 없습니다. 개발 시간의 대부분은 즉시 처리할 수 없는 엄청난 양의 린트 공격을 생성할 수 있는 레거시 코드베이스에 사용됩니다. 다행히 RuboCop에는 시간이 지남에 따라 천천히 해결할 수 있는 기존 위반의 허용 목록을 생성하는 유용한 기능이 있습니다. 이점은 앞으로 새로운 위반에 플래그를 지정하면서 관리할 수 없는 린트 오류의 폭격을 받지 않고 기존 프로젝트에 린팅을 도입할 수 있다는 것입니다.

$ bundle exec rubocop

523 files inspected, 1018 offenses detected

허용 목록 구성 파일은 아래 명령을 통해 생성할 수 있습니다.

$ bundle exec rubocop --auto-gen-config
Added inheritance from `.rubocop_todo.yml` in `.rubocop.yml`.
Created .rubocop_todo.yml.

--auto-gen-config 옵션은 모든 위반과 해당 개수를 수집하고 .rubocop_todo.yml을 생성합니다. 현재 모든 오펜스가 무시되는 현재 디렉토리의 파일입니다. 마지막으로 .rubocop.yml이 발생합니다. .rubocop_todo.yml에서 상속 코드베이스에서 RuboCop을 다시 실행해도 위법 행위가 발생하지 않도록 파일을 만드십시오.

$ bundle exec rubocop
523 files inspected, no offenses detected

허용 목록 파일을 생성하는 동안 RuboCop은 위반 수가 특정 임계값(기본적으로 15개)을 초과하면 경찰을 완전히 끕니다. 이는 기존 위반 수로 인해 해당 경찰에 대해 새 코드를 확인하는 것을 방지하기 때문에 일반적으로 원하는 것이 아닙니다. 다행히 위반 횟수가 많아도 경찰이 무력화되지 않도록 임계값을 높일 수 있습니다.

$ bundle exec rubocop --auto-gen-config --auto-gen-only-exclude --exclude-limit 10000

--auto-gen-only-exclude 옵션은 허용 목록의 각 경찰이 Exclude를 갖도록 합니다. Max 대신 위반이 발생한 모든 파일을 나열하는 블록 , 경찰에 대한 최대 제외 파일 수를 설정합니다. --exclude-limit 설정 또한 Exclude에 추가할 수 있는 최대 파일 수를 변경합니다. 각 경찰에 대한 차단. 검사 중인 총 파일 수보다 큰 임의의 수를 지정하면 경찰이 완전히 비활성화되지 않고 기존 파일이나 새 파일에 추가된 새 코드가 그에 따라 검사됩니다.

기존 위반 사항 수정

.rubocop_todo.yml 생성 후 파일에서 기존 위반을 잊지 않고 하나씩 천천히 해결하는 것이 중요합니다. Exclude에서 파일을 제거하면 됩니다. 경찰을 차단한 다음 보고된 위반 사항을 수정하고 테스트 스위트를 실행하여 버그 도입을 방지하고 커밋합니다. 경찰에서 모든 파일을 제거한 후에는 수동으로 파일에서 경찰을 삭제하거나 허용 목록 파일을 다시 생성할 수 있습니다. --auto-correct를 활용하는 것을 잊지 마십시오. 프로세스를 훨씬 빠르게 만들 수 있는 경우 옵션을 선택합니다.

스타일 가이드 채택

RuboCop은 매우 구성 가능하므로 모든 유형의 프로젝트에서 실행 가능합니다. 그러나 특히 많은 기본 규칙에 동의하지 않는 경우 요구 사항에 맞게 규칙을 구성하는 데 오랜 시간이 걸릴 수 있습니다. 이러한 상황에서는 기존 스타일 가이드를 채택하는 것이 유리할 수 있습니다. Shopify 및 Airbnb와 같은 여러 회사에서 이미 공개 소비를 위한 Ruby 스타일 가이드를 출시했습니다. RuboCop에서 선호하는 스타일 가이드를 활용하려면 Gemfile에 관련 gem을 추가하면 됩니다. :

# Gemfile
gem "rubocop-shopify", require: false

그런 다음 프로젝트 구성에 필요합니다.

# .rubocop.yml
inherit_gem:
  rubocop-shopify: rubocop.yml

린트 오류 억제

RuboCop은 훌륭한 도구이지만 때때로 오탐을 생성하거나 프로그래머의 의도에 해로운 방식으로 코드를 수정하도록 제안할 수 있습니다. 이러한 상황이 발생하면 소스 코드에 주석으로 위반 사항을 무시할 수 있습니다. 아래와 같이 비활성화할 개별 경찰 또는 부서를 언급할 수 있습니다.

# rubocop:disable Layout/LineLength, Style
[..]
# rubocop:enable Layout/LineLength, Style

또는 코드의 한 섹션에 대해 모든 경찰을 한 번에 비활성화할 수 있습니다.

# rubocop:disable all
[..]
# rubocop:enable all

줄 끝 주석을 사용하면 해당 줄에서만 지정된 경찰이 비활성화됩니다.

for x in (0..10) # rubocop:disable Style/For

편집기 통합

매번 명령줄을 통해 검사를 실행하는 대신 편집기에 코드를 입력할 때 RuboCop에서 생성된 경고 및 오류를 보는 것이 편리합니다. 고맙게도 RuboCop 통합은 대부분의 인기 있는 코드 편집기 및 IDE에서 주로 타사 플러그인을 통해 사용할 수 있습니다. Visual Studio Code에서 이 Ruby 확장을 설치하고 사용자 settings.json에 다음을 배치하기만 하면 됩니다. 파일:

{
  "ruby.lint": {
    "rubocop": true
  }
}

Vim 또는 Neovim을 사용하는 경우 coc.nvim을 통해 RuboCop의 진단을 표시할 수 있습니다. Solargraph 언어 서버를 설치해야 합니다(gem install solargraph ), coc-solargraph 확장자(:CocInstall coc-solargraph) ). 그런 다음 coc-settings.json을 구성합니다. 아래와 같은 파일:

{
  "coc.preferences.formatOnSaveFiletypes": ["ruby"],
  "solargraph.autoformat": true,
  "solargraph.diagnostics": true,
  "solargraph.formatting": true
}

RuboCop을 사용한 루비 코드 린팅 및 자동 서식 지정

사전 커밋 후크 설정

프로젝트의 모든 Ruby 코드가 소스 제어에 체크인되기 전에 적절하게 린트되고 형식이 지정되었는지 확인하는 좋은 방법은 각 준비된 파일에서 RuboCop을 실행하는 Git 사전 커밋 후크를 설정하는 것입니다. 이 기사에서는 Git 사전 커밋 후크를 관리 및 구성하기 위한 도구인 Overcommit을 사용하여 설정하는 방법을 보여주지만 이미 기존 사전 커밋 워크플로가 있는 경우 RuboCop을 다른 도구와 통합할 수도 있습니다.

먼저 RubyGems를 통해 Overcommit을 설치한 다음 프로젝트에 설치합니다.

$ gem install overcommit
$ overcommit --install # at the root of your project

위의 두 번째 명령은 리포지토리별 설정 파일(.overcommit.yml ) 현재 디렉토리에 저장하고 기존 후크를 백업합니다. 이 파일은 기본 구성을 확장하므로 기본값과 관련하여 구성을 지정하기만 하면 됩니다. 예를 들어 다음 스니펫을 통해 RuboCop 사전 커밋 후크를 활성화할 수 있습니다.

# .overcommit.yml
PreCommit:
  RuboCop:
    enabled: true
    on_warn: fail
    problem_on_unmodified_line: ignore
    command: ['bundle', 'exec', 'rubocop']

on_warn: fail 설정하면 Overcommit이 경고를 실패로 처리하는 반면 problem_on_unmodified_line: ignore 무시되도록 준비되지 않은 행에 대한 경고 및 오류를 일으킵니다. 프로젝트의 GitHub 페이지에서 사용 가능한 모든 후크 옵션과 허용 가능한 값 범위를 찾아볼 수 있습니다. overcommit --sign을 실행해야 할 수도 있습니다. 변경 사항을 적용하려면 구성 파일을 변경한 후.

RuboCop을 사용한 루비 코드 린팅 및 자동 서식 지정

경우에 따라 모든 검사(예:진행 중인 작업)를 통과하지 못한 파일을 커밋하려는 경우 사례별로 개별 검사를 건너뛸 수 있습니다.

$ SKIP=RuboCop git commit -m "WIP: Unfinished work"

CI 워크플로에 RuboCop 추가

각 pull 요청에 대해 RuboCop 검사를 실행하는 것은 잘못된 형식의 코드가 프로젝트에 병합되는 것을 방지하는 또 다른 방법입니다. 모든 CI 도구로 설정할 수 있지만 이 문서에서는 GitHub Actions를 통해 RuboCop을 실행하는 방법에 대해서만 설명합니다.

첫 번째 단계는 .github/workflows를 만드는 것입니다. 프로젝트 루트의 디렉토리 및 rubocop.yml 새 디렉토리 내의 파일. 편집기에서 파일을 열고 다음과 같이 업데이트하십시오.

# .github/workflows/rubocop.yml
name: Lint code with RuboCop

on: [push, pull_request]

jobs:
  build:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [macos-latest, ubuntu-latest, windows-latest]

    steps:
    - uses: actions/checkout@v2

    - name: Setup Ruby
      uses: ruby/setup-ruby@v1
      with:
        ruby-version: '3.0'
        bundler-cache: true

    - name: Run RuboCop
      run: bundle exec rubocop

위의 워크플로 파일은 코드가 GitHub에 푸시되거나 분기에 대해 풀 요청이 이루어질 때 실행될 단일 작업을 설명합니다. job 순차적으로 실행되는 일련의 단계입니다. 이 특정 작업은 GitHub Actions(runs-on에 정의된 대로)에서 제공하는 최신 Ubuntu, MacOS 및 Windows 버전에서 한 번 실행됩니다. 및 strategy.matrix ). 첫 번째 단계는 저장소의 코드를 확인하고 다음 단계는 Ruby 도구 체인 및 종속성을 설정하고 마지막 단계는 RuboCop을 실행합니다.

파일 편집이 완료되면 저장하고 커밋하고 GitHub에 푸시합니다. 그 후에 후속 체크인 및 풀 리퀘스트에서 보고된 문제의 인라인 디스플레이를 받게 됩니다.

RuboCop을 사용한 루비 코드 린팅 및 자동 서식 지정

대체 자동 포맷터

RuboCop은 포괄적인 자동 서식 기능을 제공하지만 요구 사항을 적절하게 충족하지 못하는 경우를 대비하여 대체 도구를 알고 있는 것도 중요합니다.

더 예뻐요

Prettier는 JavaScript용 독단적인 코드 포맷터로 시작했지만 이제는 Ruby를 비롯한 다른 많은 언어를 지원합니다. Ruby 플러그인 설치는 간단합니다. prettier를 추가하세요. Gemfile에 gem 그런 다음 bundle을 실행합니다. .

# Gemfile
gem 'prettier'

이 시점에서 다음 명령을 통해 Prettier로 Ruby 코드를 포맷할 수 있습니다.

$ bundle exec rbprettier --write '**/*.rb'

일부 Prettier의 규칙은 RuboCop의 규칙과 충돌하므로 후자의 형식 검사를 비활성화하여 Prettier를 방해하지 않도록 해야 합니다. 운 좋게도 Prettier와 충돌하거나 불필요한 RuboCop 검사를 쉽게 끌 수 있습니다. 프로젝트의 .rubocop.yml 상단에 있는 Prettier의 RuboCop 구성을 상속하기만 하면 됩니다. 파일:

# .rubocop.yml
inherit_gem:
  prettier: rubocop.yml

RuboCop을 실행할 때(bundle exec rubocop 사용) ) 앞으로는 레이아웃과 관련된 위반 사항을 보고하지 않으며 Prettier가 자체 규칙에 따라 이를 수정할 수 있는 길을 열어줍니다. 동일한 프로젝트의 JavaScript와 Ruby 코드 간에 공유할 수 있는 구성 파일을 통해 Prettier의 출력을 구성할 수도 있습니다.

RubyFmt

RubyFmt는 ​​Rust로 작성되었으며 현재 활발히 개발 중인 새로운 코드 포맷터입니다. Prettier와 마찬가지로 코드 분석 도구가 아닌 포맷터를 위한 것입니다. 아직 안정적인 릴리스가 나오지 않았으므로 지금 당장은 채택을 미루어야 하지만 확실히 지켜봐야 할 것입니다.

결론

코드 린팅 및 자동 서식 지정은 특히 개발자 팀의 맥락에서 코드 기반에 많은 이점을 제공합니다. 코드의 형식을 지정하는 방법을 듣고 싶지 않더라도 Linting이 당신만을 위한 것은 아니라는 점을 명심해야 합니다. 또한 공동 작업을 수행하는 다른 사람들을 위한 것이므로 모든 사람이 동일한 규칙을 고수할 수 있으므로 동일한 프로젝트에서 여러 코딩 스타일을 처리해야 하는 단점을 제거할 수 있습니다.

또한 linter의 출력을 복음으로 취급하지 않는 것이 중요하므로 주요 목표를 방해하지 않으면서 가장 많은 이점을 제공하는 방식으로 구성하도록 노력하십시오. RuboCop의 광범위한 구성 설정을 사용하면 문제가 되지 않습니다. 그러나 RuboCop을 구성하는 데 너무 많은 시간이 걸린다고 생각되면 앞에서 설명한 대로 미리 정의된 스타일 가이드를 사용하거나 작은 세부 사항에 대해 걱정하는 대신 모든 사람이 사용할 수 있는 구성이 없는 대안을 위해 Standard를 채택할 수 있습니다. .

읽어주셔서 감사합니다. 행복한 코딩을 하세요!