Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .reek.yml
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ detectors:
- RubyCritic::Reporter#self.report_generator_class
- RubyCritic::SourceLocator#deduplicate_symlinks
- RubyCritic::Command::Compare#compare_branches
- RubyCritic::Attributes::ClassMethods#coerce
FeatureEnvy:
exclude:
- Parser::AST::Node#module_name
Expand Down Expand Up @@ -163,6 +164,7 @@ detectors:
- RubyCritic::Command::Compare#threshold_reached?
- RubyCritic::Command::Compare#threshold_values_set?
- RubyCritic::SourceLocator#ruby_file?
- RubyCritic::Attributes#default_for
TooManyInstanceVariables:
exclude:
- RubyCritic::Generator::Html::CodeFile
Expand All @@ -189,6 +191,13 @@ detectors:
exclude:
- RubyCritic::Config#self.method_missing
- RubyCritic::Config#self.respond_to_missing?
- RubyCritic::Attributes::ClassMethods#attributes
ModuleInitialize:
exclude:
- RubyCritic::Attributes
NilCheck:
exclude:
- RubyCritic::Attributes::ClassMethods#coerce
TooManyMethods:
exclude:
- RubyCritic::Cli::Options::File
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* [CHORE] ...
* [FEATURE] ...

* [CHANGE] Replace the unmaintained `virtus` dependency with a small internal attributes module, dropping its abandoned transitive dependencies (`axiom-types`, `coercible`, `descendants_tracker`, `ice_nine`, and the deprecated `thread_safe`). Also move `ostruct` to a development dependency since it is only used in tests. (by [@pnomolos][])
* [CHANGE] Replace all Cucumber features with Minitest/Spec specs (by [@faisal][])
* [BUGFIX] Add `lang="en"` to the report's `<html>` element, give the menu-toggle anchor an `aria-label`, and make the per-rating summary IDs unique. Fixes 17 WCAG 2.1 AA structural errors on `overview.html`. (by [@MarcusAl][])

Expand Down Expand Up @@ -506,3 +507,4 @@
[@exoego]: https://github.com/exoego
[@raff-s]: https://github.com/raff-s
[@MarcusAl]: https://github.com/MarcusAl
[@pnomolos]: https://github.com/pnomolos
4 changes: 2 additions & 2 deletions lib/rubycritic/core/analysed_module.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# frozen_string_literal: true

require 'virtus'
require 'rubycritic/core/attributes'
require 'rubycritic/core/rating'

module RubyCritic
class AnalysedModule
include Virtus.model
include Attributes

# Complexity is reduced by a factor of 25 when calculating cost
COMPLEXITY_FACTOR = 25.0
Expand Down
66 changes: 66 additions & 0 deletions lib/rubycritic/core/attributes.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# frozen_string_literal: true

module RubyCritic
# Lightweight replacement for the subset of Virtus used by RubyCritic.
# Provides an `attribute` class macro that registers attributes (with
# optional type coercion and default value), generates reader/writer
# methods, and an initializer accepting a hash of attribute values.
module Attributes
def self.included(base)
base.extend(ClassMethods)
end

# Class-level macros and attribute registry.
module ClassMethods
def attributes
@attributes ||=
if superclass.respond_to?(:attributes)
superclass.attributes.dup
else
{}
end
end

def attribute(name, type = nil, default: nil)
attributes[name] = { type: type, default: default }

define_method(name) { instance_variable_get("@#{name}") }
define_method("#{name}=") do |value|
instance_variable_set("@#{name}", self.class.coerce(type, value))
end
end

def coerce(type, value)
return value if value.nil? || type.nil?

case type.name
when 'Float' then Float(value)
when 'Integer' then Integer(value)
when 'Symbol' then value.to_sym
when 'Array' then Array(value)
else value
end
end
end

def initialize(attributes = {})
self.class.attributes.each do |name, definition|
if attributes.key?(name)
public_send("#{name}=", attributes[name])
else
instance_variable_set("@#{name}", default_for(definition))
end
end
end

private

def default_for(definition)
default = definition[:default]
case default
when Array, Hash then default.dup
else default
end
end
end
end
4 changes: 2 additions & 2 deletions lib/rubycritic/core/smell.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# frozen_string_literal: true

require 'virtus'
require 'rubycritic/core/attributes'
require 'rubycritic/core/location'

module RubyCritic
class Smell
include Virtus.model
include Attributes

attribute :context
attribute :cost
Expand Down
3 changes: 1 addition & 2 deletions rubycritic.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ Gem::Specification.new do |spec|
spec.add_dependency 'flay', '~> 2.13'
spec.add_dependency 'flog', '~> 4.7'
spec.add_dependency 'launchy', '>= 2.5.2'
spec.add_dependency 'ostruct'
spec.add_dependency 'parser', '>= 3.3.0.5'
spec.add_dependency 'prism', '>= 1.6.0'
spec.add_dependency 'rainbow', '~> 3.1.1'
Expand All @@ -43,7 +42,6 @@ Gem::Specification.new do |spec|
spec.add_dependency 'ruby_parser', '~> 3.21'
spec.add_dependency 'simplecov', '>= 0.22.0'
spec.add_dependency 'tty-which', '~> 0.5.0'
spec.add_dependency 'virtus', '~> 2.0'

spec.add_development_dependency 'aruba', '~> 2.3.1', '>= 2.3.1'
spec.add_development_dependency 'bundler', '>= 2.0.0'
Expand All @@ -60,6 +58,7 @@ Gem::Specification.new do |spec|
spec.add_development_dependency 'minitest-around', '~> 0.6.0'
spec.add_development_dependency 'minitest-mock'
spec.add_development_dependency 'mocha', '~> 3.0.0'
spec.add_development_dependency 'ostruct'
spec.add_development_dependency 'rake', '~> 13.3.0', '>= 11.0.0'
spec.add_development_dependency 'rdoc'
spec.add_development_dependency 'rexml', '>= 3.2.0'
Expand Down