2016-09-21 2 views
0

Я пишу пользовательский плагин RuboCop для принудительного использования определенных URL-адресов в Berksfile. Я, возможно, взял на себя больше, чем мои ограниченные знания Ruby будут поддерживать в это время.Пользовательский RuboCop для поиска настраиваемых URL-адресов?

Вот код pseduo. Я даже близко?

конфигурации/default.yml:

ACME/ApprovedSupermarkets: 
    Description: 'Enforce the use of only authorized Chef Supermarkets.' 
    Enabled: true 
    Include: 
    - '**/Berksfile' 
    Severity: error 
    Sources: 
    - 'https://supermarket.acme.com' 
    - 'https://supermarket.trusted.com' 

Библиотека/rubocop/коп/Acme/approved_supermarkets.rb

# encoding: utf-8 
# frozen_string_literal: true 

require 'uri' 

module RuboCop 
    module Cop 
    module ACME 
     # This cop checks that only allowed supermarkets are used within Berksfiles. 
     class ApprovedSupermarkets < Cop 

     MSG = 'Only the use of authorized Chef Supermarkets are allowed.'.freeze 

     def investigate(processed_source) 
      processed_source.lines.each_with_index do |line, index| 
      check_line(line, index) 
      end 
     end 

     def check_line(line, index) 
      return if match_uris(line) 

      add_offense(nil, index, MSG) 
     end 

     def match_uris(string) 
      matches = [] 
      string.scan(uri_regexp) do 
      matches << $LAST_MATCH_INFO if valid_uri?($LAST_MATCH_INFO[0]) 
      end 
      matches 
     end 

     def valid_uri?(uri_ish_string) 
      URI.parse(uri_ish_string) 
      true 
     rescue 
      false 
     end 

     def uri_regexp 
      @regexp ||= URI.regexp(cop_config['Sources']) 
     end 
     end 
    end 
    end 
end 

спецификации/rubocop/коп/Acme/approved_supermarkets_spec. rb:

# encoding: utf-8 

require 'spec_helper' 

describe Rubocop::Cop::ACME::ApprovedSupermarkets do 
    subject(:cop) { described_class.new } 
    let(:cop_config) { cop_config } 

    cop_config['Sources'].each do |source| 
    it 'accepts #{source} as an authorized supermarket' do 
     inspect_source(cop, "source '#{source}'") 
     expect(cop.offenses).to be_empty 
    end 
    end 
end 

Berksfile (который должен терпеть неудачу)

source 'https://supermarket.untrusted.com' 

metadata 

Мы хотели бы, чтобы написать несколько других внутренних полицейских, поэтому я решил разработать RuboCop плагин против добавления вопроса в проект RuboCop. Любая помощь приветствуется.

ответ

0

Вот решение, которое, похоже, работает пока. Надеюсь, это помогает кому-то другому.

Библиотека/rubocop/коп/Acme/allowed_supermarkets.rb

# encoding: utf-8 
# frozen_string_literal: true 

require 'uri' 

module RuboCop 
    module Cop 
    module ACME 
     # This cop checks that only allowed supermarkets are used within Berksfiles. 
     # 
     # The default regexp for an acceptable allowed supermarkets can be found in 
     # config/default.yml. The default can be changed in your .rubocop.yml as follows: 
     # 
     # ACME/AllowedSupermarkets: 
     # Sources: 
     #  - 'https://supermarket.acme.com' 
     #  - 'https://supermarket.trusted.com' 
     # 
     class AllowedSupermarkets < Cop 
     MSG = 'Only the use of authorized Chef Supermarkets are allowed.'.freeze 

     def investigate(processed_source) 
      processed_source.lines.each_with_index do |line, index| 
      next unless line.start_with?('source') 

      range = source_range(processed_source.buffer, 
           index + 1, 
           (line.rstrip.length)...(line.length)) 

      add_offense(range, range, MSG) unless match_uri(line) 
      end 
     end 

     def match_uri(string) 
      string.match(uri_regexp) { |m| true if valid_uri?(m[0]) } 
     rescue 
      false 
     end 

     def valid_uri?(uri_ish_string) 
      URI.parse(uri_ish_string) 
      true 
     rescue 
      false 
     end 

     def uri_regexp 
      @regexp = Regexp.union(cop_config['Sources']) 
     end 
     end 
    end 
    end 
end 
Смежные вопросы