【Otemachi.rb#12】Atom에서 rubocop-auto-correct를 사용할 때의 주의점

16181 단어 RuboCop루비ATOM

자기소개



호리사키 세이지
  • htps : // 코m/호리사키 s
  • htps : // 라고 해서 r. 코m/호리사키 s
  • 옛날은 C라든지 C++라든지(더 이상 쓸 수 없다..) 엑셀 그림 그리기만이라든지
  • Ruby, Rails 역사는 PG스쿨 반년과 업무 위탁 3개월


  • 일의 시작



    Otemachi.rb #10에서 보치 연산자를 알았기 때문에 사용해 보았을 때, rubocop-auto-correct가 반응하지 않게 되었다.

    rubocop-auto-correct



    Atom의 확장 기능.
    Atom상에서 rubocop을 -a옵션으로 실행해 준다.
    (파일 저장시 실행할 설정도 가능)

    예상되는 동작





    실제 동작





    무반응. .



    설정을 변경하여 정보를 늘리십시오.




    ⬇️




    Ruby 2.2에서 실행 중 (보치 연산자는 2.3부터)



    Rubocop의 Ruby 버전 확인 방법



    rubocop이 ruby ​​버전을 식별하는 우선 순위는 다음과 같습니다.

    .rubocop.yml의 TargetRubyVersion 값 >
    .ruby-version 값 >
    Gemfile.lock의 Ruby 버전 값 >
    기본값(2.2)

    당시의 환경


  • .rubocop.yml 없음
  • $ ls .rubocop.yml ~/.rubocop.yml
    ls: .rubocop.yml: No such file or directory
    ls: /Users/user/.rubocop.yml: No such file or directory
    
  • .ruby-veversion 있음
  • $ cat .ruby-version
    2.3.1
    
  • Gemfile.lock에 ruby ​​버전 지정 없음
  • $ grep -A 1 "RUBY VERSION" Gemfile.lock | wc -l
           0
    

    수동으로 실행해보기


    $ rubocop -a sample.rb
    Inspecting 1 file
    C
    
    Offenses:
    
    sample.rb:1:1: C: [Corrected] Style/FrozenStringLiteralComment: Missing magic comment # frozen_string_literal: true.
    def sample(sample_arg)
    ^
    
    1 file inspected, 1 offense detected, 1 offense corrected
    

    수동이라면 움직이기 때문에, 확장 기능으로의 실행시와의 차이를 채워 나간다



    rubocop-auto-correct 구현



    rubocop-auto-correct/lib/rubocop-auto-correct.coffee
      autoCorrectBuffer: (editor)  ->
        buffer = editor.getBuffer()
    
        tempFilePath = @makeTempFile("rubocop.rb")
        fs.writeFileSync(tempFilePath, buffer.getText())
    
        rubocopCommand = @rubocopCommand()
        command = rubocopCommand[0]
        args = rubocopCommand[1]
          .concat(['-a', tempFilePath])
          .concat(@rubocopConfigPath(buffer.getPath()))
    
        which command, (err) =>
          return @rubocopNotFoundError() if (err)
          rubocop = spawnSync(command, args, { encoding: 'utf-8', timeout: 5000 })
    



    로그를 퍼가기


        args = rubocopCommand[1]
          .concat(['-a', tempFilePath])
          .concat(@rubocopConfigPath(buffer.getPath()))
    
    //ログ埋め込み
        console.log (command + " " + args.join(" "))
    

    실행된 명령


  • rubocop.yml 없음

  • /Users/user/.anyenv/envs/rbenv/shims/rubocop --format json -a/var/folders/09/xr1wrst90lb_295d2pprm6f80000gn/T/d-118916-6808-ed0mea.2qqj
  • rubocop.yml 있음

  • /Users/user/.anyenv/envs/rbenv/versions/2.5.1/bin/rubocop --format json -a/var/folders/09/xr1wrst90lb_295d2pprm6f80000gn/T/d-1181111-42791 rb --config/Users/user/develop/work/qiita/rubocop_auto/.rubocop.yml
  • HOME 디렉토리에만.rubocop.yml 있음

  • /Users/user/.anyenv/envs/rbenv/versions/2.5.1/bin/rubocop --format json -a/var/folders/09/xr1wrst90lb_295d2pprm6f80000gn/T/d-1181111-42361rub rb --config/Users/user/.rubocop.yml

    Rubocop 구현



    rubocop/lib/rubocop/config.rb
        def target_ruby_version
          @target_ruby_version ||=
            if for_all_cops['TargetRubyVersion']
              @target_ruby_version_source = :rubocop_yml
    
    
              for_all_cops['TargetRubyVersion']
            elsif target_ruby_version_from_version_file
              @target_ruby_version_source = :ruby_version_file
    
    
              target_ruby_version_from_version_file
            elsif target_ruby_version_from_bundler_lock_file
              @target_ruby_version_source = :bundler_lock_file
    
    
              target_ruby_version_from_bundler_lock_file
            else
              DEFAULT_RUBY_VERSION
            end
        end
    



    rubocop/lib/rubocop/config.rb
        def target_ruby_version_from_version_file
          file = ruby_version_file
          return unless file && File.file?(file)
    
    
          @target_ruby_version_from_version_file ||=
            File.read(file).match(/\A(ruby-)?(?<version>\d+\.\d+)/) do |md|
              md[:version].to_f
            end
        end
    

    rubocop/lib/rubocop/config.rb
        def ruby_version_file
          @ruby_version_file ||=
            find_file_upwards(RUBY_VERSION_FILENAME, base_dir_for_path_parameters)
        end
    



    rubocop/lib/rubocop/config.rb
        def ruby_version_file
          @ruby_version_file ||=
            find_file_upwards(RUBY_VERSION_FILENAME, base_dir_for_path_parameters)
        end
    



    rubocop/lib/rubocop/config.rb
        # Paths specified in configuration files starting with .rubocop are
        # relative to the directory where that file is. Paths in other config files
        # are relative to the current directory. This is so that paths in
        # config/default.yml, for example, are not relative to RuboCop's config
        # directory since that wouldn't work.
        def base_dir_for_path_parameters
          @base_dir_for_path_parameters ||=
            if File.basename(loaded_path).start_with?('.rubocop') &&
               loaded_path != File.join(Dir.home, ConfigLoader::DOTFILE)
              File.expand_path(File.dirname(loaded_path))
            else
              Dir.pwd
            end
        end
    







    로그를 넣어보기



    rubocop/lib/rubocop/config.rb
            File.open("/Users/user/rubocop_auto.out", "a") {|f|
              f.puts "Dir.pwd: #{Dir.pwd}"
            }
    
    


    결과



    /Users/user/rubocop_auto.out
    Dir.pwd: /
    


    루트 디렉토리에서 실행 중이므로 구성 파일을 찾을 수 없습니다.



    그래?


    File.basename(loaded_path).start_with?('.rubocop')
    

    .rubocop로 시작하는 파일만 있으면 좋다.


    $ wc -l .rubocop.yml
           0 .rubocop.yml
    $ cat .ruby-version
    2.3.1
    



    움직였다!



    조사 결과





    파일
    결과

    파일
    결과


    1
    .rubocop.yml

    6
    1+3


    2
    ~/.rubocop.yml
    ×
    7
    1+4


    3
    .ruby-version
    ×
    8
    1+5


    4
    ~/.ruby-version
    ×
    9
    2+3
    ×

    5
    Gemfile.lock
    ×
    10
    2+4
    ×



    11
    2+5
    ×


    ※6~11의 .rubocop.yml는 빈 파일

    요약


  • --config 옵션을 지정하지 않으면 현재 디렉토리에서 파일을 찾습니다.
  • atom 에서 본 현재 디렉토리는 root 디렉토리.
  • 프로젝트 디렉토리에 .rubocop.yml을 배치하는 것 이외의 수단은 불가.
  • 확장자 측에서 ~/.rubocop.yml을 찾고 명령에 전달했지만 명령 측에서 허용하지 않습니다. (명령 측의 움직임이 바뀌 었습니까?)
  • rbenv 를 사용하고 있다면 touch .rubocop.yml 하는 것만으로 사용할 수 있다.
  • 하지만 디폴트 설정에서는 rubocop의 지적은 엄격하기 때문에 .rubocop.yml는 설정하는 것이 좋다.


  • 참고


  • RuboCop이 정적 분석의 Ruby 버전을 결정하는 흐름
  • 좋은 웹페이지 즐겨찾기