rubyzen-lint 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +201 -0
- data/README.md +110 -0
- data/lib/rubyzen/cache/parse_cache.rb +36 -0
- data/lib/rubyzen/collections/attributes_collection.rb +32 -0
- data/lib/rubyzen/collections/base_collection.rb +30 -0
- data/lib/rubyzen/collections/blocks_collection.rb +27 -0
- data/lib/rubyzen/collections/call_site_collection.rb +52 -0
- data/lib/rubyzen/collections/classes_collection.rb +77 -0
- data/lib/rubyzen/collections/constants_collection.rb +11 -0
- data/lib/rubyzen/collections/declaration_collection.rb +11 -0
- data/lib/rubyzen/collections/file_collection.rb +81 -0
- data/lib/rubyzen/collections/macros_collection.rb +11 -0
- data/lib/rubyzen/collections/methods_collection.rb +67 -0
- data/lib/rubyzen/collections/modules_collection.rb +36 -0
- data/lib/rubyzen/collections/parameters_collection.rb +11 -0
- data/lib/rubyzen/collections/raises_collection.rb +26 -0
- data/lib/rubyzen/collections/requires_collection.rb +32 -0
- data/lib/rubyzen/collections/rescues_collection.rb +19 -0
- data/lib/rubyzen/declarations/attribute_declaration.rb +62 -0
- data/lib/rubyzen/declarations/block_declaration.rb +49 -0
- data/lib/rubyzen/declarations/call_site_declaration.rb +98 -0
- data/lib/rubyzen/declarations/class_declaration.rb +168 -0
- data/lib/rubyzen/declarations/constant_declaration.rb +155 -0
- data/lib/rubyzen/declarations/file_declaration.rb +69 -0
- data/lib/rubyzen/declarations/if_statement_declaration.rb +44 -0
- data/lib/rubyzen/declarations/macro_declaration.rb +81 -0
- data/lib/rubyzen/declarations/method_declaration.rb +63 -0
- data/lib/rubyzen/declarations/module_declaration.rb +115 -0
- data/lib/rubyzen/declarations/parameter_declaration.rb +43 -0
- data/lib/rubyzen/declarations/raise_declaration.rb +87 -0
- data/lib/rubyzen/declarations/require_declaration.rb +61 -0
- data/lib/rubyzen/declarations/rescue_declaration.rb +54 -0
- data/lib/rubyzen/lint.rb +1 -0
- data/lib/rubyzen/matchers/matcher_helpers.rb +176 -0
- data/lib/rubyzen/matchers/zen_empty_matcher.rb +54 -0
- data/lib/rubyzen/matchers/zen_false_matcher.rb +63 -0
- data/lib/rubyzen/matchers/zen_true_matcher.rb +57 -0
- data/lib/rubyzen/parsers/a_s_t_parser.rb +33 -0
- data/lib/rubyzen/project.rb +69 -0
- data/lib/rubyzen/providers/attributes_provider.rb +19 -0
- data/lib/rubyzen/providers/blocks_provider.rb +15 -0
- data/lib/rubyzen/providers/call_site_provider.rb +15 -0
- data/lib/rubyzen/providers/class_name_provider.rb +36 -0
- data/lib/rubyzen/providers/collection_filter_provider.rb +64 -0
- data/lib/rubyzen/providers/constants_provider.rb +17 -0
- data/lib/rubyzen/providers/file_path_provider.rb +26 -0
- data/lib/rubyzen/providers/if_statements_provider.rb +11 -0
- data/lib/rubyzen/providers/line_number_provider.rb +11 -0
- data/lib/rubyzen/providers/lines_of_code_provider.rb +11 -0
- data/lib/rubyzen/providers/macros_provider.rb +17 -0
- data/lib/rubyzen/providers/raises_provider.rb +19 -0
- data/lib/rubyzen/providers/requires_provider.rb +19 -0
- data/lib/rubyzen/providers/rescues_provider.rb +17 -0
- data/lib/rubyzen/providers/source_code_provider.rb +11 -0
- data/lib/rubyzen/providers/visibility_provider.rb +49 -0
- data/lib/rubyzen/version.rb +3 -0
- data/lib/rubyzen-lint.rb +1 -0
- data/lib/rubyzen.rb +98 -0
- data/rubyzen-lint.gemspec +28 -0
- metadata +148 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
module Rubyzen
|
|
2
|
+
module Providers
|
|
3
|
+
# Provides name-based filtering methods for collections.
|
|
4
|
+
module CollectionFilterProvider
|
|
5
|
+
# @param name [String] the exact name to match
|
|
6
|
+
# @return [self] filtered collection containing only items with the given name
|
|
7
|
+
def with_name(name)
|
|
8
|
+
filter { |item| item.name == name }
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# @param suffix [String] the suffix to match against item names
|
|
12
|
+
# @return [self] filtered collection of items whose names end with the suffix
|
|
13
|
+
def with_name_ending_with(suffix)
|
|
14
|
+
filter { |item| item.name&.end_with?(suffix) }
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# @param prefix [String] the prefix to match against item names
|
|
18
|
+
# @return [self] filtered collection of items whose names start with the prefix
|
|
19
|
+
def with_name_starting_with(prefix)
|
|
20
|
+
filter { |item| item.name&.start_with?(prefix) }
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# @param substring [String] the substring to search for in item names
|
|
24
|
+
# @param case_sensitive [Boolean] whether the match is case-sensitive (default: true)
|
|
25
|
+
# @return [self] filtered collection of items whose names contain the substring
|
|
26
|
+
def with_name_including(substring, case_sensitive: true)
|
|
27
|
+
if case_sensitive
|
|
28
|
+
filter { |item| item.name&.include?(substring) }
|
|
29
|
+
else
|
|
30
|
+
filter { |item| item.name&.downcase&.include?(substring.downcase) }
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# @param names [Array<String>] names to exclude
|
|
35
|
+
# @return [self] filtered collection excluding items with any of the given names
|
|
36
|
+
def without_name(*names)
|
|
37
|
+
filter { |item| !names.include?(item.name) }
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# @param suffix [String] the suffix to exclude
|
|
41
|
+
# @return [self] filtered collection excluding items whose names end with the suffix
|
|
42
|
+
def without_name_ending_with(suffix)
|
|
43
|
+
filter { |item| !item.name&.end_with?(suffix) }
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# @param prefix [String] the prefix to exclude
|
|
47
|
+
# @return [self] filtered collection excluding items whose names start with the prefix
|
|
48
|
+
def without_name_starting_with(prefix)
|
|
49
|
+
filter { |item| !item.name&.start_with?(prefix) }
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# @param substring [String] the substring to exclude
|
|
53
|
+
# @param case_sensitive [Boolean] whether the match is case-sensitive (default: true)
|
|
54
|
+
# @return [self] filtered collection excluding items whose names contain the substring
|
|
55
|
+
def without_name_including(substring, case_sensitive: true)
|
|
56
|
+
if case_sensitive
|
|
57
|
+
filter { |item| !item.name&.include?(substring) }
|
|
58
|
+
else
|
|
59
|
+
filter { |item| !item.name&.downcase&.include?(substring.downcase) }
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module Rubyzen
|
|
2
|
+
module Providers
|
|
3
|
+
# Provides access to constant references and assignments within a declaration.
|
|
4
|
+
module ConstantsProvider
|
|
5
|
+
# @return [Rubyzen::Collections::ConstantsCollection] collection of constant declarations
|
|
6
|
+
def constants
|
|
7
|
+
constant_nodes = node.each_descendant(:casgn, :const)
|
|
8
|
+
|
|
9
|
+
Collections::ConstantsCollection.new(
|
|
10
|
+
constant_nodes.map do |const_node|
|
|
11
|
+
Declarations::ConstantDeclaration.new(const_node, self)
|
|
12
|
+
end
|
|
13
|
+
)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module Rubyzen
|
|
2
|
+
module Providers
|
|
3
|
+
# Provides access to the file path of a declaration by traversing parent declarations.
|
|
4
|
+
module FilePathProvider
|
|
5
|
+
# @return [String, nil] the file path containing this declaration
|
|
6
|
+
def file_path
|
|
7
|
+
file_path_recursive(self)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
private
|
|
11
|
+
|
|
12
|
+
def file_path_recursive(declaration)
|
|
13
|
+
return if declaration.nil?
|
|
14
|
+
return declaration.path if declaration.respond_to?(:path)
|
|
15
|
+
|
|
16
|
+
if declaration.respond_to?(:file_declaration)
|
|
17
|
+
return file_path_recursive(declaration.file_declaration)
|
|
18
|
+
elsif declaration.respond_to?(:parent)
|
|
19
|
+
return file_path_recursive(declaration.parent)
|
|
20
|
+
elsif declaration.respond_to?(:parent_class)
|
|
21
|
+
return file_path_recursive(declaration.parent_class)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
module Rubyzen
|
|
2
|
+
module Providers
|
|
3
|
+
# Provides access to if/unless conditional statements within a declaration.
|
|
4
|
+
module IfStatementsProvider
|
|
5
|
+
# @return [Rubyzen::Collections::DeclarationCollection] collection of if statement declarations
|
|
6
|
+
def if_statements
|
|
7
|
+
Rubyzen::Collections::DeclarationCollection.new(node.each_node(:if).map { |if_node| Rubyzen::Declarations::IfStatementDeclaration.new(if_node, self) })
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
module Rubyzen
|
|
2
|
+
module Providers
|
|
3
|
+
# Provides access to the starting line number of a declaration in its source file.
|
|
4
|
+
module LineNumberProvider
|
|
5
|
+
# @return [Integer] the line number where this declaration begins
|
|
6
|
+
def line
|
|
7
|
+
node.loc.expression.line
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
module Rubyzen
|
|
2
|
+
module Providers
|
|
3
|
+
# Provides the number of lines of code a declaration spans.
|
|
4
|
+
module LinesOfCodeProvider
|
|
5
|
+
# @return [Integer] the total number of source lines in this declaration
|
|
6
|
+
def lines_of_code
|
|
7
|
+
node.loc.expression.source.split("\n").size
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module Rubyzen
|
|
2
|
+
module Providers
|
|
3
|
+
# Provides access to macro-style method calls (e.g., validates, has_many) within a declaration.
|
|
4
|
+
module MacrosProvider
|
|
5
|
+
# @return [Rubyzen::Collections::MacrosCollection] collection of macro declarations
|
|
6
|
+
def macros
|
|
7
|
+
macros_nodes = node.each_descendant(:send).select(&:macro?)
|
|
8
|
+
|
|
9
|
+
macros_declarations = macros_nodes.map do |macro_node|
|
|
10
|
+
Rubyzen::Declarations::MacroDeclaration.new(macro_node, self)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
Rubyzen::Collections::MacrosCollection.new(macros_declarations)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Rubyzen
|
|
2
|
+
module Providers
|
|
3
|
+
# Provides access to raise statements within a declaration.
|
|
4
|
+
module RaisesProvider
|
|
5
|
+
# @return [Rubyzen::Collections::RaisesCollection] collection of raise declarations
|
|
6
|
+
def raises
|
|
7
|
+
raise_nodes = node.each_descendant(:send).select do |send_node|
|
|
8
|
+
send_node.method_name == :raise
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
raise_declarations = raise_nodes.map do |raise_node|
|
|
12
|
+
Rubyzen::Declarations::RaiseDeclaration.new(raise_node, self)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
Rubyzen::Collections::RaisesCollection.new(raise_declarations)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Rubyzen
|
|
2
|
+
module Providers
|
|
3
|
+
# Provides access to require, require_relative, and load statements within a declaration.
|
|
4
|
+
module RequiresProvider
|
|
5
|
+
# @return [Rubyzen::Collections::RequiresCollection] collection of require declarations
|
|
6
|
+
def requires
|
|
7
|
+
require_nodes = node.each_descendant(:send).select do |send_node|
|
|
8
|
+
%w[require require_relative load].include?(send_node.method_name.to_s)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
require_declarations = require_nodes.map do |require_node|
|
|
12
|
+
Rubyzen::Declarations::RequireDeclaration.new(require_node, self)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
Rubyzen::Collections::RequiresCollection.new(require_declarations)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module Rubyzen
|
|
2
|
+
module Providers
|
|
3
|
+
# Provides access to rescue clauses within a declaration.
|
|
4
|
+
module RescuesProvider
|
|
5
|
+
# @return [Rubyzen::Collections::RescuesCollection] collection of rescue declarations
|
|
6
|
+
def rescues
|
|
7
|
+
rescue_nodes = node.each_descendant(:resbody)
|
|
8
|
+
|
|
9
|
+
rescue_declarations = rescue_nodes.map do |rescue_node|
|
|
10
|
+
Rubyzen::Declarations::RescueDeclaration.new(rescue_node, self)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
Rubyzen::Collections::RescuesCollection.new(rescue_declarations)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
module Rubyzen
|
|
2
|
+
module Providers
|
|
3
|
+
# Provides method visibility detection (public, private, protected).
|
|
4
|
+
module VisibilityProvider
|
|
5
|
+
# @return [Symbol] the visibility of this declaration (:public, :private, or :protected)
|
|
6
|
+
def visibility
|
|
7
|
+
determine_visibility
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# @return [Boolean] true if this declaration is private
|
|
11
|
+
def private?
|
|
12
|
+
visibility == :private
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# @return [Boolean] true if this declaration is protected
|
|
16
|
+
def protected?
|
|
17
|
+
visibility == :protected
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# @return [Boolean] true if this declaration is public
|
|
21
|
+
def public?
|
|
22
|
+
visibility == :public
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
def determine_visibility
|
|
28
|
+
return :public unless parent_class
|
|
29
|
+
|
|
30
|
+
visibility_nodes = parent_class.node.each_descendant(:send).select do |send_node|
|
|
31
|
+
send_node.method_name.to_s.match?(/^(private|protected|public)$/) &&
|
|
32
|
+
send_node.arguments.empty?
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
declaration_line = node.loc.expression.line
|
|
36
|
+
|
|
37
|
+
applicable_visibility = visibility_nodes
|
|
38
|
+
.select { |v_node| v_node.loc.expression.line < declaration_line }
|
|
39
|
+
.max_by { |v_node| v_node.loc.expression.line }
|
|
40
|
+
|
|
41
|
+
if applicable_visibility
|
|
42
|
+
applicable_visibility.method_name.to_sym
|
|
43
|
+
else
|
|
44
|
+
:public
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
data/lib/rubyzen-lint.rb
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require_relative 'rubyzen'
|
data/lib/rubyzen.rb
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
require 'rubocop-ast'
|
|
2
|
+
require 'rspec'
|
|
3
|
+
require 'zeitwerk'
|
|
4
|
+
|
|
5
|
+
loader = Zeitwerk::Loader.for_gem
|
|
6
|
+
loader.ignore("#{__dir__}/rubyzen/matchers")
|
|
7
|
+
loader.ignore("#{__dir__}/rubyzen/rspec")
|
|
8
|
+
loader.ignore("#{__dir__}/rubyzen/lint.rb")
|
|
9
|
+
loader.ignore("#{__dir__}/rubyzen-lint.rb")
|
|
10
|
+
loader.setup
|
|
11
|
+
|
|
12
|
+
require_relative 'rubyzen/matchers/matcher_helpers'
|
|
13
|
+
require_relative 'rubyzen/matchers/zen_empty_matcher'
|
|
14
|
+
require_relative 'rubyzen/matchers/zen_true_matcher'
|
|
15
|
+
require_relative 'rubyzen/matchers/zen_false_matcher'
|
|
16
|
+
|
|
17
|
+
# Rubyzen is a Ruby architectural linter that lets you write lint rules as RSpec tests.
|
|
18
|
+
# It wraps RuboCop AST to provide a high-level, easy-to-use API for enforcing architectural
|
|
19
|
+
# rules across a codebase.
|
|
20
|
+
#
|
|
21
|
+
# @example Basic usage
|
|
22
|
+
# project = Rubyzen::Project.new(["/path/to/src", "/path/to/spec"])
|
|
23
|
+
# controllers = project.files.with_paths("controllers/").classes
|
|
24
|
+
#
|
|
25
|
+
# # Assert controllers don't call ActiveRecord directly
|
|
26
|
+
# expect(controllers.all_methods.call_sites.with_name("where")).to zen_empty
|
|
27
|
+
#
|
|
28
|
+
# @example Using auto-discovery (from project root)
|
|
29
|
+
# project = Rubyzen::Project.new # scans app/, lib/, src/, spec/ automatically
|
|
30
|
+
#
|
|
31
|
+
module Rubyzen
|
|
32
|
+
# Base error class for all Rubyzen errors.
|
|
33
|
+
class Error < StandardError; end
|
|
34
|
+
|
|
35
|
+
# Raised when a Ruby file cannot be parsed.
|
|
36
|
+
class ParseError < Error; end
|
|
37
|
+
|
|
38
|
+
# Yields the global configuration for customization.
|
|
39
|
+
#
|
|
40
|
+
# @example
|
|
41
|
+
# Rubyzen.configure do |config|
|
|
42
|
+
# config.paths = ['app', 'lib']
|
|
43
|
+
# end
|
|
44
|
+
def self.configure
|
|
45
|
+
yield(configuration)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Returns the global configuration instance.
|
|
49
|
+
#
|
|
50
|
+
# @return [Configuration]
|
|
51
|
+
def self.configuration
|
|
52
|
+
@configuration ||= Configuration.new
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Holds project path configuration with auto-discovery support.
|
|
56
|
+
#
|
|
57
|
+
# Resolution order:
|
|
58
|
+
# 1. Explicit paths via {#paths=} (set via +Rubyzen.configure+)
|
|
59
|
+
# 2. Auto-discovery of +app/+, +lib/+, +src/+, +spec/+ from +Dir.pwd+
|
|
60
|
+
#
|
|
61
|
+
# @example
|
|
62
|
+
# Rubyzen.configure { |c| c.paths = ['app/models', 'app/controllers'] }
|
|
63
|
+
# Rubyzen.configuration.project_paths #=> ["/full/path/app/models", "/full/path/app/controllers"]
|
|
64
|
+
#
|
|
65
|
+
class Configuration
|
|
66
|
+
# Sets explicit paths to scan.
|
|
67
|
+
# Relative paths are resolved against +Dir.pwd+.
|
|
68
|
+
#
|
|
69
|
+
# @param value [Array<String>] directories to analyze
|
|
70
|
+
attr_writer :paths
|
|
71
|
+
|
|
72
|
+
# Returns the resolved project paths.
|
|
73
|
+
#
|
|
74
|
+
# @return [Array<String>] absolute paths to directories to analyze
|
|
75
|
+
def project_paths
|
|
76
|
+
resolve_paths(@paths) || auto_discover_paths
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
private
|
|
80
|
+
|
|
81
|
+
def resolve_paths(paths)
|
|
82
|
+
return nil unless paths&.any?
|
|
83
|
+
|
|
84
|
+
root = Dir.pwd
|
|
85
|
+
paths.map do |path|
|
|
86
|
+
File.expand_path(path, root)
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def auto_discover_paths
|
|
91
|
+
root = Dir.pwd
|
|
92
|
+
candidates = %w[app lib src spec].map { |d| File.join(root, d) }
|
|
93
|
+
paths = candidates.select { |d| Dir.exist?(d) }
|
|
94
|
+
paths = [root] if paths.empty?
|
|
95
|
+
paths
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require_relative 'lib/rubyzen/version'
|
|
2
|
+
|
|
3
|
+
Gem::Specification.new do |spec|
|
|
4
|
+
spec.name = 'rubyzen-lint'
|
|
5
|
+
spec.version = Rubyzen::VERSION
|
|
6
|
+
spec.authors = ['Perry Street Software']
|
|
7
|
+
spec.summary = 'Architectural linter for Ruby — write lint rules as RSpec tests'
|
|
8
|
+
spec.description = 'Rubyzen is a modern linter for Ruby that allows you to write architectural ' \
|
|
9
|
+
'lint rules as unit tests. In the era of AI-generated code, it provides your ' \
|
|
10
|
+
'team with deterministic guardrails to keep your codebase clean, maintainable, ' \
|
|
11
|
+
'and consistent as it grows.'
|
|
12
|
+
spec.homepage = 'https://github.com/perrystreetsoftware/Rubyzen'
|
|
13
|
+
spec.license = 'Apache-2.0'
|
|
14
|
+
|
|
15
|
+
spec.required_ruby_version = '>= 3.1'
|
|
16
|
+
|
|
17
|
+
spec.files = Dir.glob(%w[lib/**/*.rb rubyzen-lint.gemspec LICENSE README.md])
|
|
18
|
+
spec.require_paths = ['lib']
|
|
19
|
+
|
|
20
|
+
spec.add_dependency 'rubocop-ast', '~> 1.26'
|
|
21
|
+
spec.add_dependency 'zeitwerk', '~> 2.6'
|
|
22
|
+
spec.add_dependency 'rspec', '~> 3.12'
|
|
23
|
+
|
|
24
|
+
spec.metadata = {
|
|
25
|
+
'source_code_uri' => 'https://github.com/perrystreetsoftware/Rubyzen',
|
|
26
|
+
'bug_tracker_uri' => 'https://github.com/perrystreetsoftware/Rubyzen/issues'
|
|
27
|
+
}
|
|
28
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: rubyzen-lint
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Perry Street Software
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2026-05-15 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: rubocop-ast
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '1.26'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '1.26'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: zeitwerk
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '2.6'
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '2.6'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: rspec
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - "~>"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '3.12'
|
|
48
|
+
type: :runtime
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - "~>"
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '3.12'
|
|
55
|
+
description: Rubyzen is a modern linter for Ruby that allows you to write architectural
|
|
56
|
+
lint rules as unit tests. In the era of AI-generated code, it provides your team
|
|
57
|
+
with deterministic guardrails to keep your codebase clean, maintainable, and consistent
|
|
58
|
+
as it grows.
|
|
59
|
+
email:
|
|
60
|
+
executables: []
|
|
61
|
+
extensions: []
|
|
62
|
+
extra_rdoc_files: []
|
|
63
|
+
files:
|
|
64
|
+
- LICENSE
|
|
65
|
+
- README.md
|
|
66
|
+
- lib/rubyzen-lint.rb
|
|
67
|
+
- lib/rubyzen.rb
|
|
68
|
+
- lib/rubyzen/cache/parse_cache.rb
|
|
69
|
+
- lib/rubyzen/collections/attributes_collection.rb
|
|
70
|
+
- lib/rubyzen/collections/base_collection.rb
|
|
71
|
+
- lib/rubyzen/collections/blocks_collection.rb
|
|
72
|
+
- lib/rubyzen/collections/call_site_collection.rb
|
|
73
|
+
- lib/rubyzen/collections/classes_collection.rb
|
|
74
|
+
- lib/rubyzen/collections/constants_collection.rb
|
|
75
|
+
- lib/rubyzen/collections/declaration_collection.rb
|
|
76
|
+
- lib/rubyzen/collections/file_collection.rb
|
|
77
|
+
- lib/rubyzen/collections/macros_collection.rb
|
|
78
|
+
- lib/rubyzen/collections/methods_collection.rb
|
|
79
|
+
- lib/rubyzen/collections/modules_collection.rb
|
|
80
|
+
- lib/rubyzen/collections/parameters_collection.rb
|
|
81
|
+
- lib/rubyzen/collections/raises_collection.rb
|
|
82
|
+
- lib/rubyzen/collections/requires_collection.rb
|
|
83
|
+
- lib/rubyzen/collections/rescues_collection.rb
|
|
84
|
+
- lib/rubyzen/declarations/attribute_declaration.rb
|
|
85
|
+
- lib/rubyzen/declarations/block_declaration.rb
|
|
86
|
+
- lib/rubyzen/declarations/call_site_declaration.rb
|
|
87
|
+
- lib/rubyzen/declarations/class_declaration.rb
|
|
88
|
+
- lib/rubyzen/declarations/constant_declaration.rb
|
|
89
|
+
- lib/rubyzen/declarations/file_declaration.rb
|
|
90
|
+
- lib/rubyzen/declarations/if_statement_declaration.rb
|
|
91
|
+
- lib/rubyzen/declarations/macro_declaration.rb
|
|
92
|
+
- lib/rubyzen/declarations/method_declaration.rb
|
|
93
|
+
- lib/rubyzen/declarations/module_declaration.rb
|
|
94
|
+
- lib/rubyzen/declarations/parameter_declaration.rb
|
|
95
|
+
- lib/rubyzen/declarations/raise_declaration.rb
|
|
96
|
+
- lib/rubyzen/declarations/require_declaration.rb
|
|
97
|
+
- lib/rubyzen/declarations/rescue_declaration.rb
|
|
98
|
+
- lib/rubyzen/lint.rb
|
|
99
|
+
- lib/rubyzen/matchers/matcher_helpers.rb
|
|
100
|
+
- lib/rubyzen/matchers/zen_empty_matcher.rb
|
|
101
|
+
- lib/rubyzen/matchers/zen_false_matcher.rb
|
|
102
|
+
- lib/rubyzen/matchers/zen_true_matcher.rb
|
|
103
|
+
- lib/rubyzen/parsers/a_s_t_parser.rb
|
|
104
|
+
- lib/rubyzen/project.rb
|
|
105
|
+
- lib/rubyzen/providers/attributes_provider.rb
|
|
106
|
+
- lib/rubyzen/providers/blocks_provider.rb
|
|
107
|
+
- lib/rubyzen/providers/call_site_provider.rb
|
|
108
|
+
- lib/rubyzen/providers/class_name_provider.rb
|
|
109
|
+
- lib/rubyzen/providers/collection_filter_provider.rb
|
|
110
|
+
- lib/rubyzen/providers/constants_provider.rb
|
|
111
|
+
- lib/rubyzen/providers/file_path_provider.rb
|
|
112
|
+
- lib/rubyzen/providers/if_statements_provider.rb
|
|
113
|
+
- lib/rubyzen/providers/line_number_provider.rb
|
|
114
|
+
- lib/rubyzen/providers/lines_of_code_provider.rb
|
|
115
|
+
- lib/rubyzen/providers/macros_provider.rb
|
|
116
|
+
- lib/rubyzen/providers/raises_provider.rb
|
|
117
|
+
- lib/rubyzen/providers/requires_provider.rb
|
|
118
|
+
- lib/rubyzen/providers/rescues_provider.rb
|
|
119
|
+
- lib/rubyzen/providers/source_code_provider.rb
|
|
120
|
+
- lib/rubyzen/providers/visibility_provider.rb
|
|
121
|
+
- lib/rubyzen/version.rb
|
|
122
|
+
- rubyzen-lint.gemspec
|
|
123
|
+
homepage: https://github.com/perrystreetsoftware/Rubyzen
|
|
124
|
+
licenses:
|
|
125
|
+
- Apache-2.0
|
|
126
|
+
metadata:
|
|
127
|
+
source_code_uri: https://github.com/perrystreetsoftware/Rubyzen
|
|
128
|
+
bug_tracker_uri: https://github.com/perrystreetsoftware/Rubyzen/issues
|
|
129
|
+
post_install_message:
|
|
130
|
+
rdoc_options: []
|
|
131
|
+
require_paths:
|
|
132
|
+
- lib
|
|
133
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
134
|
+
requirements:
|
|
135
|
+
- - ">="
|
|
136
|
+
- !ruby/object:Gem::Version
|
|
137
|
+
version: '3.1'
|
|
138
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
139
|
+
requirements:
|
|
140
|
+
- - ">="
|
|
141
|
+
- !ruby/object:Gem::Version
|
|
142
|
+
version: '0'
|
|
143
|
+
requirements: []
|
|
144
|
+
rubygems_version: 3.0.3.1
|
|
145
|
+
signing_key:
|
|
146
|
+
specification_version: 4
|
|
147
|
+
summary: Architectural linter for Ruby — write lint rules as RSpec tests
|
|
148
|
+
test_files: []
|