我正在编写一个自定义RuboCop插件来强制执行Berksfile中的特定URL。我可能已经承担了超过我有限的Ruby知识将在此时支持。
这是一些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'
LIB / rubocop / COP / 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 / COP / 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 :(得分:0)
这是一个似乎现在有效的解决方案。希望它可以帮助别人。
<强> LIB / rubocop / COP / 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