class-metrix 0.1.2 → 1.0.1

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 +4 -4
  2. data/.editorconfig +48 -0
  3. data/.vscode/README.md +128 -0
  4. data/.vscode/extensions.json +31 -0
  5. data/.vscode/keybindings.json +26 -0
  6. data/.vscode/launch.json +32 -0
  7. data/.vscode/rbs.code-snippets +61 -0
  8. data/.vscode/settings.json +112 -0
  9. data/.vscode/tasks.json +240 -0
  10. data/CHANGELOG.md +73 -4
  11. data/README.md +86 -22
  12. data/Steepfile +26 -0
  13. data/docs/ARCHITECTURE.md +501 -0
  14. data/docs/CHANGELOG_EVOLUTION_EXAMPLE.md +95 -0
  15. data/examples/README.md +161 -114
  16. data/examples/basic_usage.rb +88 -0
  17. data/examples/debug_levels_demo.rb +65 -0
  18. data/examples/debug_mode_demo.rb +75 -0
  19. data/examples/inheritance_and_modules.rb +155 -0
  20. data/lib/class_metrix/extractor.rb +106 -11
  21. data/lib/class_metrix/extractors/constants_extractor.rb +155 -21
  22. data/lib/class_metrix/extractors/methods_extractor.rb +186 -21
  23. data/lib/class_metrix/extractors/multi_type_extractor.rb +8 -7
  24. data/lib/class_metrix/formatters/base/base_formatter.rb +3 -3
  25. data/lib/class_metrix/formatters/components/footer_component.rb +4 -4
  26. data/lib/class_metrix/formatters/components/generic_header_component.rb +2 -2
  27. data/lib/class_metrix/formatters/components/header_component.rb +4 -4
  28. data/lib/class_metrix/formatters/components/missing_behaviors_component.rb +7 -7
  29. data/lib/class_metrix/formatters/components/table_component/column_width_calculator.rb +56 -0
  30. data/lib/class_metrix/formatters/components/table_component/row_processor.rb +141 -0
  31. data/lib/class_metrix/formatters/components/table_component/table_data_extractor.rb +57 -0
  32. data/lib/class_metrix/formatters/components/table_component/table_renderer.rb +55 -0
  33. data/lib/class_metrix/formatters/components/table_component.rb +32 -245
  34. data/lib/class_metrix/formatters/csv_formatter.rb +3 -3
  35. data/lib/class_metrix/formatters/markdown_formatter.rb +3 -4
  36. data/lib/class_metrix/formatters/shared/markdown_table_builder.rb +12 -7
  37. data/lib/class_metrix/formatters/shared/table_builder.rb +92 -27
  38. data/lib/class_metrix/formatters/shared/value_processor.rb +72 -16
  39. data/lib/class_metrix/utils/debug_logger.rb +159 -0
  40. data/lib/class_metrix/version.rb +1 -1
  41. data/sig/class_metrix.rbs +8 -0
  42. data/sig/extractor.rbs +54 -0
  43. data/sig/extractors.rbs +84 -0
  44. data/sig/formatters_base.rbs +59 -0
  45. data/sig/formatters_components.rbs +133 -0
  46. data/sig/formatters_main.rbs +20 -0
  47. data/sig/formatters_shared.rbs +102 -0
  48. data/sig/manifest.yaml +32 -0
  49. data/sig/utils.rbs +57 -0
  50. data/sig/value_processor.rbs +11 -0
  51. data/sig/version.rbs +4 -0
  52. metadata +60 -10
  53. data/examples/advanced/error_handling.rb +0 -199
  54. data/examples/advanced/hash_expansion.rb +0 -180
  55. data/examples/basic/01_simple_constants.rb +0 -56
  56. data/examples/basic/02_simple_methods.rb +0 -99
  57. data/examples/basic/03_multi_type_extraction.rb +0 -116
  58. data/examples/components/configurable_reports.rb +0 -201
  59. data/examples/csv_output_demo.rb +0 -237
  60. data/examples/real_world/microservices_audit.rb +0 -312
  61. data/sig/class/metrix.rbs +0 -6
@@ -1,199 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- require_relative "../../lib/class_metrix"
5
-
6
- puts "=== Advanced Example: Error Handling ==="
7
- puts
8
-
9
- # Classes that demonstrate various error scenarios
10
- class WorkingService
11
- # Working constants
12
- SERVICE_NAME = "working"
13
- VERSION = "1.0.0"
14
- ENABLED = true
15
-
16
- # Working methods
17
- def self.status
18
- "healthy"
19
- end
20
-
21
- def self.version
22
- "1.0.0"
23
- end
24
-
25
- def self.health_check
26
- { status: "ok", uptime: 12_345 }
27
- end
28
-
29
- def self.enabled?
30
- true
31
- end
32
- end
33
-
34
- class PartiallyBrokenService
35
- # Working constants
36
- SERVICE_NAME = "partially_broken"
37
- VERSION = "0.9.0"
38
- # Missing ENABLED constant
39
-
40
- # Working methods
41
- def self.status
42
- "degraded"
43
- end
44
-
45
- def self.version
46
- "0.9.0"
47
- end
48
-
49
- # Broken method that raises an error
50
- def self.health_check
51
- raise StandardError, "Health check failed!"
52
- end
53
-
54
- def self.enabled?
55
- false
56
- end
57
-
58
- # Method that returns nil
59
- def self.uptime
60
- nil
61
- end
62
-
63
- # Method with complex error
64
- def self.database_connection
65
- raise ActiveRecord::ConnectionNotEstablished, "Database unavailable"
66
- rescue NameError
67
- # If ActiveRecord is not available, raise a different error
68
- raise "Connection library not available"
69
- end
70
- end
71
-
72
- class CompletelyBrokenService
73
- # Has some constants
74
- SERVICE_NAME = "broken"
75
- # Missing VERSION and ENABLED
76
-
77
- # Has working method
78
- def self.status
79
- "down"
80
- end
81
-
82
- # Missing version method
83
-
84
- # Broken health_check
85
- def self.health_check
86
- raise NoMethodError, "Health monitoring not implemented"
87
- end
88
-
89
- # Method that raises during execution
90
- def self.enabled?
91
- some_undefined_variable.call
92
- end
93
-
94
- # Method that returns false
95
- def self.deprecated?
96
- true
97
- end
98
- end
99
-
100
- puts "=== Service Classes Defined ==="
101
- puts "WorkingService: All methods work"
102
- puts "PartiallyBrokenService: Some methods fail"
103
- puts "CompletelyBrokenService: Most methods fail"
104
- puts
105
-
106
- # 1. Extract without error handling (will raise errors)
107
- puts "💥 1. WITHOUT ERROR HANDLING (This will show errors)"
108
- puts "-" * 60
109
-
110
- begin
111
- result = ClassMetrix.extract(:class_methods)
112
- .from([WorkingService, PartiallyBrokenService])
113
- .filter(/health_check/)
114
- .to_markdown
115
- puts result
116
- rescue StandardError => e
117
- puts "❌ Error occurred: #{e.class.name}: #{e.message}"
118
- end
119
- puts
120
-
121
- # 2. Extract with error handling
122
- puts "🛡️ 2. WITH ERROR HANDLING (Graceful failure)"
123
- puts "-" * 60
124
- result = ClassMetrix.extract(:class_methods)
125
- .from([WorkingService, PartiallyBrokenService, CompletelyBrokenService])
126
- .handle_errors
127
- .to_markdown
128
-
129
- puts result
130
- puts
131
-
132
- # 3. Constants with missing values
133
- puts "📋 3. CONSTANTS WITH MISSING VALUES"
134
- puts "-" * 60
135
- result = ClassMetrix.extract(:constants)
136
- .from([WorkingService, PartiallyBrokenService, CompletelyBrokenService])
137
- .handle_errors
138
- .to_markdown
139
-
140
- puts result
141
- puts
142
-
143
- # 4. Multi-type extraction with errors
144
- puts "📊 4. MULTI-TYPE WITH ERROR HANDLING"
145
- puts "-" * 60
146
- result = ClassMetrix.extract(:constants, :class_methods)
147
- .from([WorkingService, PartiallyBrokenService, CompletelyBrokenService])
148
- .filter(/SERVICE_NAME|status|enabled/)
149
- .handle_errors
150
- .to_markdown
151
-
152
- puts result
153
- puts
154
-
155
- # 5. Focus on problematic methods
156
- puts "🔍 5. PROBLEMATIC METHODS ANALYSIS"
157
- puts "-" * 60
158
- result = ClassMetrix.extract(:class_methods)
159
- .from([WorkingService, PartiallyBrokenService, CompletelyBrokenService])
160
- .filter(/health_check|database|uptime/)
161
- .handle_errors
162
- .to_markdown
163
-
164
- puts result
165
- puts
166
-
167
- # 6. Boolean and nil value handling
168
- puts "✅ 6. BOOLEAN AND NIL VALUE HANDLING"
169
- puts "-" * 60
170
- result = ClassMetrix.extract(:class_methods)
171
- .from([WorkingService, PartiallyBrokenService, CompletelyBrokenService])
172
- .filter(/enabled\?|deprecated\?|uptime/)
173
- .handle_errors
174
- .to_markdown
175
-
176
- puts result
177
- puts
178
-
179
- # 7. Save comprehensive error analysis report
180
- puts "💾 7. SAVING COMPREHENSIVE ERROR ANALYSIS REPORT"
181
- puts "-" * 60
182
- report = ClassMetrix.extract(:constants, :class_methods)
183
- .from([WorkingService, PartiallyBrokenService, CompletelyBrokenService])
184
- .handle_errors
185
- .to_markdown("error_analysis_report.md", title: "Service Health Analysis Report")
186
-
187
- puts "✅ Comprehensive error analysis saved to: error_analysis_report.md"
188
- puts "📊 Report contains #{report.lines.count} lines with rich metadata"
189
- puts
190
-
191
- puts "🛡️ Enhanced Error Handling Features Demonstrated:"
192
- puts "• 🚫 Missing constants: '🚫 Not defined'"
193
- puts "• 🚫 Missing methods: '🚫 No method'"
194
- puts "• ⚠️ Runtime errors: '⚠️ Error: [descriptive message]'"
195
- puts "• ❌ Boolean false and nil values: '❌'"
196
- puts "• ✅ Boolean true values: '✅'"
197
- puts "• 📊 Rich markdown reports with titles and metadata"
198
- puts "• 📋 Missing behaviors summary per class"
199
- puts "• 🛡️ handle_errors flag enables graceful degradation"
@@ -1,180 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- require_relative "../../lib/class_metrix"
5
-
6
- puts "=== Advanced Example: Hash Expansion ==="
7
- puts
8
-
9
- # Configuration classes with complex hash structures
10
- class DatabaseConfig
11
- # Hash constants
12
- DEFAULT_CONFIG = {
13
- host: "localhost",
14
- port: 5432,
15
- ssl: true,
16
- pool_size: 5
17
- }.freeze
18
-
19
- CONNECTION_POOLS = {
20
- read: { size: 10, timeout: 30 },
21
- write: { size: 5, timeout: 15 },
22
- admin: { size: 2, timeout: 60 }
23
- }.freeze
24
-
25
- # Hash methods
26
- def self.production_config
27
- {
28
- host: "db.production.com",
29
- port: 5432,
30
- database: "myapp_production",
31
- ssl: true,
32
- pool_size: 20,
33
- timeout: 30,
34
- backup_enabled: true
35
- }
36
- end
37
-
38
- def self.development_config
39
- {
40
- host: "localhost",
41
- port: 5432,
42
- database: "myapp_development",
43
- ssl: false,
44
- pool_size: 5,
45
- timeout: 10
46
- }
47
- end
48
-
49
- def self.simple_value
50
- "not a hash"
51
- end
52
- end
53
-
54
- class RedisConfig
55
- # Hash constants
56
- DEFAULT_CONFIG = {
57
- host: "localhost",
58
- port: 6379,
59
- ssl: false,
60
- timeout: 5
61
- }.freeze
62
-
63
- CLUSTER_CONFIG = {
64
- nodes: 3,
65
- replication: true,
66
- failover: "auto"
67
- }.freeze
68
-
69
- # Hash methods
70
- def self.production_config
71
- {
72
- host: "redis.internal",
73
- port: 6379,
74
- database: 0,
75
- ssl: false,
76
- max_connections: 100,
77
- cluster_enabled: true
78
- }
79
- end
80
-
81
- def self.development_config
82
- {
83
- host: "localhost",
84
- port: 6379,
85
- database: 1,
86
- ssl: false,
87
- max_connections: 10
88
- }
89
- end
90
-
91
- def self.simple_value
92
- 42
93
- end
94
- end
95
-
96
- puts "=== Configuration Classes Defined ==="
97
- puts "DatabaseConfig and RedisConfig with hash constants and methods"
98
- puts
99
-
100
- # 1. Normal output (without expansion)
101
- puts "📋 1. NORMAL OUTPUT (Hashes as inspect strings)"
102
- puts "-" * 60
103
- result = ClassMetrix.extract(:class_methods)
104
- .from([DatabaseConfig, RedisConfig])
105
- .filter(/config$/)
106
- .to_markdown
107
-
108
- puts result
109
- puts
110
-
111
- # 2. Expanded output
112
- puts "🔍 2. EXPANDED OUTPUT (Hash keys as sub-rows)"
113
- puts "-" * 60
114
- result = ClassMetrix.extract(:class_methods)
115
- .from([DatabaseConfig, RedisConfig])
116
- .filter(/config$/)
117
- .expand_hashes
118
- .to_markdown
119
-
120
- puts result
121
- puts
122
-
123
- # 3. Constants with expansion
124
- puts "📊 3. CONSTANTS WITH HASH EXPANSION"
125
- puts "-" * 60
126
- result = ClassMetrix.extract(:constants)
127
- .from([DatabaseConfig, RedisConfig])
128
- .filter(/CONFIG/)
129
- .expand_hashes
130
- .handle_errors
131
- .to_markdown
132
-
133
- puts result
134
- puts
135
-
136
- # 4. Mixed data types with expansion
137
- puts "🔧 4. MIXED DATA TYPES WITH EXPANSION"
138
- puts "-" * 60
139
- result = ClassMetrix.extract(:class_methods)
140
- .from([DatabaseConfig, RedisConfig])
141
- .expand_hashes
142
- .to_markdown
143
-
144
- puts result
145
- puts
146
-
147
- # 5. Multi-type extraction with expansion
148
- puts "🚀 5. MULTI-TYPE WITH HASH EXPANSION"
149
- puts "-" * 60
150
- result = ClassMetrix.extract(:constants, :class_methods)
151
- .from([DatabaseConfig, RedisConfig])
152
- .filter(/DEFAULT_CONFIG|production_config/)
153
- .expand_hashes
154
- .handle_errors
155
- .to_markdown
156
-
157
- puts result
158
- puts
159
-
160
- # 6. Save expanded report
161
- puts "💾 6. SAVING EXPANDED REPORT"
162
- puts "-" * 60
163
- report = ClassMetrix.extract(:constants, :class_methods)
164
- .from([DatabaseConfig, RedisConfig])
165
- .expand_hashes
166
- .handle_errors
167
- .to_markdown("config_analysis_expanded.md")
168
-
169
- puts "✅ Expanded report saved to: config_analysis_expanded.md"
170
- puts "📊 Report contains #{report.lines.count} lines"
171
- puts
172
-
173
- puts "✨ Hash Expansion Features Demonstrated:"
174
- puts "• 📋 Hash indicators show number of keys"
175
- puts "• └─ Sub-rows show individual key-value pairs"
176
- puts "• ❌ Missing keys shown clearly"
177
- puts "• — Non-hash values shown with dash"
178
- puts "• Mixed data types handled properly"
179
- puts "• Works with both constants and methods"
180
- puts "• Compatible with multi-type extraction"
@@ -1,56 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- require_relative "../../lib/class_metrix"
5
-
6
- puts "=== Basic Example 1: Simple Constants ==="
7
- puts
8
-
9
- # Define some simple classes with constants
10
- class User
11
- ROLE_NAME = "user"
12
- MAX_LOGIN_ATTEMPTS = 3
13
- ACCOUNT_TYPE = "standard"
14
- end
15
-
16
- class Admin
17
- ROLE_NAME = "admin"
18
- MAX_LOGIN_ATTEMPTS = 5
19
- ACCOUNT_TYPE = "premium"
20
- ADMIN_LEVEL = 10
21
- end
22
-
23
- class Guest
24
- ROLE_NAME = "guest"
25
- MAX_LOGIN_ATTEMPTS = 1
26
- ACCOUNT_TYPE = "basic"
27
- end
28
-
29
- puts "Classes defined: User, Admin, Guest"
30
- puts "Constants: ROLE_NAME, MAX_LOGIN_ATTEMPTS, ACCOUNT_TYPE, ADMIN_LEVEL"
31
- puts
32
-
33
- # Extract all constants
34
- puts "📋 All Constants:"
35
- puts ClassMetrix.extract(:constants)
36
- .from([User, Admin, Guest])
37
- .to_markdown
38
- puts
39
-
40
- # Extract filtered constants
41
- puts "🔍 Filtered Constants (ROLE and MAX):"
42
- puts ClassMetrix.extract(:constants)
43
- .from([User, Admin, Guest])
44
- .filter(/ROLE|MAX/)
45
- .to_markdown
46
- puts
47
-
48
- # Extract with regex filter
49
- puts "🎯 Regex Filter (starting with ACCOUNT):"
50
- puts ClassMetrix.extract(:constants)
51
- .from([User, Admin, Guest])
52
- .filter(/^ACCOUNT/)
53
- .to_markdown
54
- puts
55
-
56
- puts "✨ This example shows basic constant extraction and filtering!"
@@ -1,99 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- require_relative "../../lib/class_metrix"
5
-
6
- puts "=== Basic Example 2: Simple Class Methods ==="
7
- puts
8
-
9
- # Define some simple classes with class methods
10
- class PaymentProcessor
11
- def self.supported_currencies
12
- %w[USD EUR GBP]
13
- end
14
-
15
- def self.max_amount
16
- 10_000
17
- end
18
-
19
- def self.requires_verification?
20
- false
21
- end
22
-
23
- def self.processing_fee
24
- 2.5
25
- end
26
- end
27
-
28
- class StripeProcessor
29
- def self.supported_currencies
30
- %w[USD EUR GBP CAD AUD]
31
- end
32
-
33
- def self.max_amount
34
- 50_000
35
- end
36
-
37
- def self.requires_verification?
38
- true
39
- end
40
-
41
- def self.processing_fee
42
- 2.9
43
- end
44
-
45
- def self.supports_recurring?
46
- true
47
- end
48
- end
49
-
50
- class PayPalProcessor
51
- def self.supported_currencies
52
- %w[USD EUR]
53
- end
54
-
55
- def self.max_amount
56
- 25_000
57
- end
58
-
59
- def self.requires_verification?
60
- true
61
- end
62
-
63
- def self.processing_fee
64
- 3.4
65
- end
66
-
67
- def self.instant_transfer?
68
- false
69
- end
70
- end
71
-
72
- puts "Classes defined: PaymentProcessor, StripeProcessor, PayPalProcessor"
73
- puts "Methods: supported_currencies, max_amount, requires_verification?, processing_fee, etc."
74
- puts
75
-
76
- # Extract all class methods
77
- puts "📋 All Class Methods:"
78
- puts ClassMetrix.extract(:class_methods)
79
- .from([PaymentProcessor, StripeProcessor, PayPalProcessor])
80
- .to_markdown
81
- puts
82
-
83
- # Extract boolean methods only
84
- puts "✅ Boolean Methods (ending with ?):"
85
- puts ClassMetrix.extract(:class_methods)
86
- .from([PaymentProcessor, StripeProcessor, PayPalProcessor])
87
- .filter(/\?$/)
88
- .to_markdown
89
- puts
90
-
91
- # Extract configuration methods
92
- puts "⚙️ Configuration Methods (max, fee, supported):"
93
- puts ClassMetrix.extract(:class_methods)
94
- .from([PaymentProcessor, StripeProcessor, PayPalProcessor])
95
- .filter(/max|fee|supported/)
96
- .to_markdown
97
- puts
98
-
99
- puts "✨ This example shows class method extraction with different return types!"
@@ -1,116 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- require_relative "../../lib/class_metrix"
5
-
6
- puts "=== Basic Example 3: Multi-Type Extraction ==="
7
- puts
8
-
9
- # Define classes with both constants and methods
10
- class EmailService
11
- # Constants
12
- PROVIDER_NAME = "smtp"
13
- DEFAULT_PORT = 587
14
- ENCRYPTION_ENABLED = true
15
-
16
- # Class methods
17
- def self.provider_name
18
- "SMTP Service"
19
- end
20
-
21
- def self.default_port
22
- 587
23
- end
24
-
25
- def self.encryption_enabled?
26
- true
27
- end
28
-
29
- def self.rate_limit
30
- 100
31
- end
32
- end
33
-
34
- class SendGridService
35
- # Constants
36
- PROVIDER_NAME = "sendgrid"
37
- DEFAULT_PORT = 443
38
- ENCRYPTION_ENABLED = true
39
- API_VERSION = "v3"
40
-
41
- # Class methods
42
- def self.provider_name
43
- "SendGrid API"
44
- end
45
-
46
- def self.default_port
47
- 443
48
- end
49
-
50
- def self.encryption_enabled?
51
- true
52
- end
53
-
54
- def self.rate_limit
55
- 1000
56
- end
57
-
58
- def self.api_version
59
- "v3"
60
- end
61
- end
62
-
63
- class MailgunService
64
- # Constants
65
- PROVIDER_NAME = "mailgun"
66
- DEFAULT_PORT = 443
67
- ENCRYPTION_ENABLED = true
68
-
69
- # Class methods
70
- def self.provider_name
71
- "Mailgun API"
72
- end
73
-
74
- def self.default_port
75
- 443
76
- end
77
-
78
- def self.encryption_enabled?
79
- true
80
- end
81
-
82
- def self.rate_limit
83
- 500
84
- end
85
- end
86
-
87
- puts "Classes defined: EmailService, SendGridService, MailgunService"
88
- puts "Each has constants AND class methods with similar names"
89
- puts
90
-
91
- # Compare constants vs methods
92
- puts "📊 Multi-Type Extraction (Constants + Methods):"
93
- puts ClassMetrix.extract(:constants, :class_methods)
94
- .from([EmailService, SendGridService, MailgunService])
95
- .filter(/provider_name|default_port|encryption/)
96
- .to_markdown
97
- puts
98
-
99
- # Compare specific behaviors
100
- puts "🎯 Rate Limiting Comparison:"
101
- puts ClassMetrix.extract(:constants, :class_methods)
102
- .from([EmailService, SendGridService, MailgunService])
103
- .filter(/rate_limit/)
104
- .to_markdown
105
- puts
106
-
107
- # API-specific features
108
- puts "🔌 API Features:"
109
- puts ClassMetrix.extract(:constants, :class_methods)
110
- .from([EmailService, SendGridService, MailgunService])
111
- .filter(/API|version/)
112
- .to_markdown
113
- puts
114
-
115
- puts "✨ This example shows how to compare both constants and methods in one table!"
116
- puts "Notice how the 'Type' column distinguishes between constants and methods."