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.
Files changed (61) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +201 -0
  3. data/README.md +110 -0
  4. data/lib/rubyzen/cache/parse_cache.rb +36 -0
  5. data/lib/rubyzen/collections/attributes_collection.rb +32 -0
  6. data/lib/rubyzen/collections/base_collection.rb +30 -0
  7. data/lib/rubyzen/collections/blocks_collection.rb +27 -0
  8. data/lib/rubyzen/collections/call_site_collection.rb +52 -0
  9. data/lib/rubyzen/collections/classes_collection.rb +77 -0
  10. data/lib/rubyzen/collections/constants_collection.rb +11 -0
  11. data/lib/rubyzen/collections/declaration_collection.rb +11 -0
  12. data/lib/rubyzen/collections/file_collection.rb +81 -0
  13. data/lib/rubyzen/collections/macros_collection.rb +11 -0
  14. data/lib/rubyzen/collections/methods_collection.rb +67 -0
  15. data/lib/rubyzen/collections/modules_collection.rb +36 -0
  16. data/lib/rubyzen/collections/parameters_collection.rb +11 -0
  17. data/lib/rubyzen/collections/raises_collection.rb +26 -0
  18. data/lib/rubyzen/collections/requires_collection.rb +32 -0
  19. data/lib/rubyzen/collections/rescues_collection.rb +19 -0
  20. data/lib/rubyzen/declarations/attribute_declaration.rb +62 -0
  21. data/lib/rubyzen/declarations/block_declaration.rb +49 -0
  22. data/lib/rubyzen/declarations/call_site_declaration.rb +98 -0
  23. data/lib/rubyzen/declarations/class_declaration.rb +168 -0
  24. data/lib/rubyzen/declarations/constant_declaration.rb +155 -0
  25. data/lib/rubyzen/declarations/file_declaration.rb +69 -0
  26. data/lib/rubyzen/declarations/if_statement_declaration.rb +44 -0
  27. data/lib/rubyzen/declarations/macro_declaration.rb +81 -0
  28. data/lib/rubyzen/declarations/method_declaration.rb +63 -0
  29. data/lib/rubyzen/declarations/module_declaration.rb +115 -0
  30. data/lib/rubyzen/declarations/parameter_declaration.rb +43 -0
  31. data/lib/rubyzen/declarations/raise_declaration.rb +87 -0
  32. data/lib/rubyzen/declarations/require_declaration.rb +61 -0
  33. data/lib/rubyzen/declarations/rescue_declaration.rb +54 -0
  34. data/lib/rubyzen/lint.rb +1 -0
  35. data/lib/rubyzen/matchers/matcher_helpers.rb +176 -0
  36. data/lib/rubyzen/matchers/zen_empty_matcher.rb +54 -0
  37. data/lib/rubyzen/matchers/zen_false_matcher.rb +63 -0
  38. data/lib/rubyzen/matchers/zen_true_matcher.rb +57 -0
  39. data/lib/rubyzen/parsers/a_s_t_parser.rb +33 -0
  40. data/lib/rubyzen/project.rb +69 -0
  41. data/lib/rubyzen/providers/attributes_provider.rb +19 -0
  42. data/lib/rubyzen/providers/blocks_provider.rb +15 -0
  43. data/lib/rubyzen/providers/call_site_provider.rb +15 -0
  44. data/lib/rubyzen/providers/class_name_provider.rb +36 -0
  45. data/lib/rubyzen/providers/collection_filter_provider.rb +64 -0
  46. data/lib/rubyzen/providers/constants_provider.rb +17 -0
  47. data/lib/rubyzen/providers/file_path_provider.rb +26 -0
  48. data/lib/rubyzen/providers/if_statements_provider.rb +11 -0
  49. data/lib/rubyzen/providers/line_number_provider.rb +11 -0
  50. data/lib/rubyzen/providers/lines_of_code_provider.rb +11 -0
  51. data/lib/rubyzen/providers/macros_provider.rb +17 -0
  52. data/lib/rubyzen/providers/raises_provider.rb +19 -0
  53. data/lib/rubyzen/providers/requires_provider.rb +19 -0
  54. data/lib/rubyzen/providers/rescues_provider.rb +17 -0
  55. data/lib/rubyzen/providers/source_code_provider.rb +11 -0
  56. data/lib/rubyzen/providers/visibility_provider.rb +49 -0
  57. data/lib/rubyzen/version.rb +3 -0
  58. data/lib/rubyzen-lint.rb +1 -0
  59. data/lib/rubyzen.rb +98 -0
  60. data/rubyzen-lint.gemspec +28 -0
  61. 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,11 @@
1
+ module Rubyzen
2
+ module Providers
3
+ # Provides access to the raw source code text of a declaration.
4
+ module SourceCodeProvider
5
+ # @return [String] the source code of this declaration
6
+ def source_code
7
+ node.loc.expression.source
8
+ end
9
+ end
10
+ end
11
+ 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
@@ -0,0 +1,3 @@
1
+ module Rubyzen
2
+ VERSION = '0.1.0'
3
+ end
@@ -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: []