Skip to content

Instantly share code, notes, and snippets.

@andreaseger
Last active August 29, 2015 14:14
Show Gist options
  • Save andreaseger/cd06dd8b0bd641cdfe31 to your computer and use it in GitHub Desktop.
Save andreaseger/cd06dd8b0bd641cdfe31 to your computer and use it in GitHub Desktop.
# This beeing a plain ruby file do whatever you what
# like requiring some organization wide baseline rubocop config
# or a todo file
PoC.configure do |config|
# I've yet to find a better solution for the namespaceing issue so I can
# directly access the Metrics module
# even with a instance_eval/instance_exec from within the PoC module I have
# to call PoC::Cop::Metrics...
include PoC::Cop
config.includes << 'Guardfile'
config.excludes = []
# disable all
Cop.all.each {|e| e.enable! }
# Later on something like this should be easily do-able
# Style.all.each {|e| e.disable! }
# change config of a cop
Metrics::Bar.configure do |cop|
cop.enable!
cop.length = 37
end
# or directly set an option of a cop
Lint::Foo.enforced_style = :first
# baisc config validation / sanity checks
Style::Baz.configure do |cop|
cop.length = 2
end
end
# Accessing general config
p PoC.configuration.includes
# looking at the config of all cops
PoC::Cop.all.each do |cop|
p [cop, cop.config]
end
# selecting all activ cops
PoC::Cop.all.select{|e| e.enabled? }
module PoC
module Cop
class Cop
@all = []
@enabled = false
class << self
def inherited(subclass)
@all << subclass
end
attr_reader :all
def enable!
@enabled = true
end
def disable!
@enabled = false
end
def enabled?
@enabled
end
# configs are stored as class instance variables on the cops
def config
instance_variables.each_with_object({}) do |e, a|
a[e] = instance_variable_get(e)
end
end
def with_config(name, default:, options: nil)
ivar_name = "@#{name}"
instance_variable_set(ivar_name, default)
self.class.send(:define_method, name) do
instance_variable_get(ivar_name)
end
define_method(name) do
self.class.send(name)
end
self.class.send(:define_method, "#{name}=") do |value|
if options.nil? || options.include?(value)
instance_variable_set(ivar_name, value)
else
puts "#{self}##{name} does not allow value: #{value}; using: #{instance_variable_get(ivar_name)}"
# fail UnknownOptionError, "#{self}##{name} does not allow value: #{value}"
end
end
end
def configure
yield(self)
end
end
def config
self.class.config
end
def enabled?
self.class.enabled?
end
def run
# this can pobably be more efficiant be delt with in the runner, but still an option
return unless enabled?
# also in here cop specific excludes can be dealt with
return if excluded?
p "using config #{self.class.instance_variables}"
# whatever happens in here...
end
end
def self.all
Cop.all
end
# each Cop knows about its own onfiguration options,
# default values are also define directly inside the cop
# even more the valid options can be defined: in this PoC it will just check
# if the set value is in a given list or range, but I recond this can easily
# be extended to support a lamda as check
module Lint
class Foo < Cop
enable!
with_config :length, default: 15
with_config :enforced_style, default: :first, options: [:first, :second, :third]
end
end
module Metrics
class Bar < Cop
disable!
with_config :length, default: 10
with_config :enforced_style, default: :second, options: [:first, :second, :third]
end
end
module Style
class Baz < Cop
enable!
with_config :length, default: 25, options: 5..50
with_config :enforced_style, default: :third, options: [:first, :second, :third]
end
end
end
end
require './cop.rb'
require 'singleton'
module PoC
class Configuration
include Singleton
def initialize
# defaults for these are set in here
@includes = []
@excludes = []
end
attr_accessor :includes, :excludes
def cop
PoC::Cop
end
end
module_function
def configuration
Configuration.instance
end
def configure(&_block)
# self.instance_exec(Configuration.instance, &block)
yield(Configuration.instance)
end
end
# the global default config could also just be loaded in here
# require './default_config'
# Finally just require the users config
# (obviously some code for finding the right file has to be added)
require './.poc'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment