rails_lens 0.5.3 → 0.10.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 +4 -4
- data/CHANGELOG.md +14 -0
- data/README.md +1 -1
- data/lib/rails_lens/analyzers/association_analyzer.rb +0 -10
- data/lib/rails_lens/analyzers/base.rb +16 -0
- data/lib/rails_lens/analyzers/best_practices_analyzer.rb +0 -14
- data/lib/rails_lens/analyzers/callbacks.rb +11 -23
- data/lib/rails_lens/analyzers/composite_keys.rb +4 -38
- data/lib/rails_lens/analyzers/delegated_types.rb +1 -1
- data/lib/rails_lens/analyzers/enums.rb +1 -1
- data/lib/rails_lens/analyzers/error_handling.rb +11 -25
- data/lib/rails_lens/analyzers/inheritance.rb +4 -4
- data/lib/rails_lens/analyzers/notes.rb +0 -10
- data/lib/rails_lens/analyzers/performance_analyzer.rb +6 -30
- data/lib/rails_lens/annotation_pipeline.rb +14 -8
- data/lib/rails_lens/cli.rb +11 -22
- data/lib/rails_lens/cli_error_handler.rb +19 -20
- data/lib/rails_lens/commands.rb +33 -41
- data/lib/rails_lens/erd/column_type_formatter.rb +6 -1
- data/lib/rails_lens/erd/visualizer.rb +57 -98
- data/lib/rails_lens/errors.rb +3 -3
- data/lib/rails_lens/extensions/base.rb +1 -1
- data/lib/rails_lens/file_insertion_helper.rb +33 -6
- data/lib/rails_lens/mailer/annotator.rb +1 -16
- data/lib/rails_lens/mailer/extractor.rb +6 -8
- data/lib/rails_lens/model_detector.rb +27 -31
- data/lib/rails_lens/parsers/class_info.rb +1 -27
- data/lib/rails_lens/parsers/module_info.rb +1 -26
- data/lib/rails_lens/parsers/node_info.rb +34 -0
- data/lib/rails_lens/providers/view_provider.rb +1 -1
- data/lib/rails_lens/route/annotator.rb +1 -0
- data/lib/rails_lens/schema/adapters/base.rb +38 -4
- data/lib/rails_lens/schema/adapters/database_info.rb +1 -1
- data/lib/rails_lens/schema/adapters/mysql.rb +26 -80
- data/lib/rails_lens/schema/adapters/postgresql.rb +3 -22
- data/lib/rails_lens/schema/adapters/sqlite3.rb +0 -31
- data/lib/rails_lens/schema/annotation_manager.rb +88 -127
- data/lib/rails_lens/schema/annotation_removal.rb +24 -0
- data/lib/rails_lens/schema/database_annotator.rb +2 -15
- data/lib/rails_lens/tasks/annotate.rake +6 -1
- data/lib/rails_lens/toml_format.rb +14 -0
- data/lib/rails_lens/version.rb +1 -1
- data/lib/rails_lens.rb +4 -0
- metadata +12 -9
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0f010a15d0d3afdf64754e866cac571fcb1c91e4bd3981c8aa9bdece8d30f85a
|
|
4
|
+
data.tar.gz: 11e8b6ad7da6461bdc846952151537d3495d67cd812cd9f7e4b3ca40dbc37fbb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 22963fce37978c1a4157d9c1ffe236a3ca41c0a97d8b492a832729b467c91923810cc70126c4717c17cbbac9596dfbcd620a34cdb482092b34a8692a37351c23
|
|
7
|
+
data.tar.gz: 4c5bd10154b4d44b4dfda08ec21ebcd3632b6a740e7a9d28ddd7d5a35289fec248fcf76b61bc19db8a53f548691a5597df326bda48f25ad0cc200c94468f94bf
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.10.0](https://github.com/seuros/rails_lens/compare/rails_lens/v0.5.4...rails_lens/v0.10.0) (2026-08-10)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* composite primary keys ([#45](https://github.com/seuros/rails_lens/issues/45)) ([8d934b5](https://github.com/seuros/rails_lens/commit/8d934b51b310252ce42f3db9aa85894161d562f3))
|
|
9
|
+
|
|
10
|
+
## [0.5.4](https://github.com/seuros/rails_lens/compare/rails_lens/v0.5.3...rails_lens/v0.5.4) (2026-06-26)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Bug Fixes
|
|
14
|
+
|
|
15
|
+
* prevent duplicate extension annotation blocks on re-annotate ([0e85197](https://github.com/seuros/rails_lens/commit/0e8519742c751eb26d225a3a9a8434a4da4053b1))
|
|
16
|
+
|
|
3
17
|
## [0.5.3](https://github.com/seuros/rails_lens/compare/rails_lens/v0.5.2...rails_lens/v0.5.3) (2026-02-17)
|
|
4
18
|
|
|
5
19
|
|
data/README.md
CHANGED
|
@@ -71,16 +71,6 @@ module RailsLens
|
|
|
71
71
|
false
|
|
72
72
|
end
|
|
73
73
|
|
|
74
|
-
def needs_explicit_inverse_of?(association)
|
|
75
|
-
# Rails can auto-infer inverse_of for vanilla associations
|
|
76
|
-
# Only require explicit inverse_of when using custom options
|
|
77
|
-
association.options[:class_name].present? ||
|
|
78
|
-
association.options[:foreign_key].present? ||
|
|
79
|
-
association.options[:as].present? ||
|
|
80
|
-
association.options[:source].present? ||
|
|
81
|
-
association.options[:through].present?
|
|
82
|
-
end
|
|
83
|
-
|
|
84
74
|
def should_have_counter_cache?(association)
|
|
85
75
|
return false unless association.macro == :belongs_to
|
|
86
76
|
|
|
@@ -30,6 +30,22 @@ module RailsLens
|
|
|
30
30
|
def adapter_name
|
|
31
31
|
@adapter_name ||= connection.adapter_name
|
|
32
32
|
end
|
|
33
|
+
|
|
34
|
+
def indexed?(column)
|
|
35
|
+
connection.indexes(table_name).any? do |index|
|
|
36
|
+
index.columns.include?(column.name)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def needs_explicit_inverse_of?(association)
|
|
41
|
+
# Rails can auto-infer inverse_of for vanilla associations
|
|
42
|
+
# Only require explicit inverse_of when using custom options
|
|
43
|
+
association.options[:class_name].present? ||
|
|
44
|
+
association.options[:foreign_key].present? ||
|
|
45
|
+
association.options[:as].present? ||
|
|
46
|
+
association.options[:source].present? ||
|
|
47
|
+
association.options[:through].present?
|
|
48
|
+
end
|
|
33
49
|
end
|
|
34
50
|
end
|
|
35
51
|
end
|
|
@@ -71,23 +71,9 @@ module RailsLens
|
|
|
71
71
|
model_class.column_names.include?(name)
|
|
72
72
|
end
|
|
73
73
|
|
|
74
|
-
def indexed?(column)
|
|
75
|
-
connection.indexes(table_name).any? do |index|
|
|
76
|
-
index.columns.include?(column.name)
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
|
-
|
|
80
74
|
def columns
|
|
81
75
|
@columns ||= model_class.columns
|
|
82
76
|
end
|
|
83
|
-
|
|
84
|
-
def connection
|
|
85
|
-
model_class.connection
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
def table_name
|
|
89
|
-
model_class.table_name
|
|
90
|
-
end
|
|
91
77
|
end
|
|
92
78
|
end
|
|
93
79
|
end
|
|
@@ -178,18 +178,13 @@ module RailsLens
|
|
|
178
178
|
def extract_options(callback)
|
|
179
179
|
options = {}
|
|
180
180
|
|
|
181
|
-
# Extract :if
|
|
182
|
-
if
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
options[:if] = formatted if formatted.any?
|
|
186
|
-
end
|
|
181
|
+
# Extract :if / :unless conditions (stored as matching instance variables)
|
|
182
|
+
%i[if unless].each do |key|
|
|
183
|
+
ivar = :"@#{key}"
|
|
184
|
+
next unless callback.instance_variable_defined?(ivar) && callback.instance_variable_get(ivar).present?
|
|
187
185
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
conditions = callback.instance_variable_get(:@unless)
|
|
191
|
-
formatted = format_conditions(conditions)
|
|
192
|
-
options[:unless] = formatted if formatted.any?
|
|
186
|
+
formatted = format_conditions(callback.instance_variable_get(ivar))
|
|
187
|
+
options[key] = formatted if formatted.any?
|
|
193
188
|
end
|
|
194
189
|
|
|
195
190
|
# Extract :on option (for validation and commit callbacks)
|
|
@@ -274,19 +269,12 @@ module RailsLens
|
|
|
274
269
|
parts = []
|
|
275
270
|
parts << "method = \"#{escape_toml(callback[:method])}\""
|
|
276
271
|
|
|
277
|
-
if
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
end
|
|
281
|
-
|
|
282
|
-
if callback[:options][:unless]&.any?
|
|
283
|
-
unless_values = callback[:options][:unless].map { |v| "\"#{escape_toml(v)}\"" }.join(', ')
|
|
284
|
-
parts << "unless = [#{unless_values}]"
|
|
285
|
-
end
|
|
272
|
+
%i[if unless on].each do |key|
|
|
273
|
+
values = callback[:options][key]
|
|
274
|
+
next unless values&.any?
|
|
286
275
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
parts << "on = [#{on_values}]"
|
|
276
|
+
escaped = values.map { |v| "\"#{escape_toml(v)}\"" }.join(', ')
|
|
277
|
+
parts << "#{key} = [#{escaped}]"
|
|
290
278
|
end
|
|
291
279
|
|
|
292
280
|
parts << 'prepend = true' if callback[:options][:prepend]
|
|
@@ -4,22 +4,10 @@ module RailsLens
|
|
|
4
4
|
module Analyzers
|
|
5
5
|
class CompositeKeys < Base
|
|
6
6
|
def analyze
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
keys = model_class.primary_keys
|
|
10
|
-
return format_composite_keys(keys) if keys.length > 1
|
|
11
|
-
end
|
|
7
|
+
pk = model_class.primary_key
|
|
8
|
+
return nil unless pk.is_a?(Array)
|
|
12
9
|
|
|
13
|
-
|
|
14
|
-
if adapter_name == 'PostgreSQL'
|
|
15
|
-
keys = detect_composite_primary_key_from_db
|
|
16
|
-
return format_composite_keys(keys) if keys && keys.length > 1
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
nil
|
|
20
|
-
rescue NoMethodError => e
|
|
21
|
-
RailsLens.logger.debug { "Failed to analyze composite keys for #{model_class.name}: #{e.message}" }
|
|
22
|
-
nil
|
|
10
|
+
format_composite_keys(pk)
|
|
23
11
|
rescue ActiveRecord::ConnectionNotEstablished => e
|
|
24
12
|
RailsLens.logger.debug { "No database connection for #{model_class.name}: #{e.message}" }
|
|
25
13
|
nil
|
|
@@ -29,31 +17,9 @@ module RailsLens
|
|
|
29
17
|
|
|
30
18
|
def format_composite_keys(keys)
|
|
31
19
|
lines = ['[composite_pk]']
|
|
32
|
-
lines << "keys =
|
|
20
|
+
lines << "keys = #{TomlFormat.quoted_array(keys)}"
|
|
33
21
|
lines.join("\n")
|
|
34
22
|
end
|
|
35
|
-
|
|
36
|
-
def detect_composite_primary_key_from_db
|
|
37
|
-
# Query PostgreSQL system catalogs to find composite primary keys
|
|
38
|
-
sql = <<~SQL.squish
|
|
39
|
-
SELECT a.attname
|
|
40
|
-
FROM pg_index i
|
|
41
|
-
JOIN pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey)
|
|
42
|
-
WHERE i.indrelid = '#{table_name}'::regclass
|
|
43
|
-
AND i.indisprimary
|
|
44
|
-
ORDER BY array_position(i.indkey, a.attnum)
|
|
45
|
-
SQL
|
|
46
|
-
|
|
47
|
-
result = connection.execute(sql)
|
|
48
|
-
keys = result.pluck('attname')
|
|
49
|
-
keys.empty? ? nil : keys
|
|
50
|
-
rescue ActiveRecord::StatementInvalid => e
|
|
51
|
-
RailsLens.logger.debug { "Failed to detect composite keys from database for #{table_name}: #{e.message}" }
|
|
52
|
-
nil
|
|
53
|
-
rescue PG::Error => e
|
|
54
|
-
RailsLens.logger.debug { "PostgreSQL error detecting composite keys: #{e.message}" }
|
|
55
|
-
nil
|
|
56
|
-
end
|
|
57
23
|
end
|
|
58
24
|
end
|
|
59
25
|
end
|
|
@@ -11,7 +11,7 @@ module RailsLens
|
|
|
11
11
|
|
|
12
12
|
model_class.defined_enums.each do |name, values|
|
|
13
13
|
# Format as TOML inline table: name = { key = "value", ... }
|
|
14
|
-
formatted_values = if values.values.all?
|
|
14
|
+
formatted_values = if values.values.all?(Integer)
|
|
15
15
|
# Integer-based enum
|
|
16
16
|
values.map { |k, v| "#{k} = #{v}" }.join(', ')
|
|
17
17
|
else
|
|
@@ -16,49 +16,35 @@ module RailsLens
|
|
|
16
16
|
|
|
17
17
|
private
|
|
18
18
|
|
|
19
|
+
# Report an analyzer error with the shared analyzer/model context plus any
|
|
20
|
+
# call-specific +context+ keys.
|
|
21
|
+
def report_analyzer_error(error, **context)
|
|
22
|
+
ErrorReporter.report(error, { analyzer: self.class.name, model: model_class.name }.merge(context))
|
|
23
|
+
end
|
|
24
|
+
|
|
19
25
|
def handle_database_error(error)
|
|
20
|
-
|
|
21
|
-
analyzer: self.class.name,
|
|
22
|
-
model: model_class.name,
|
|
23
|
-
table: model_class.table_name
|
|
24
|
-
})
|
|
26
|
+
report_analyzer_error(error, table: model_class.table_name)
|
|
25
27
|
[]
|
|
26
28
|
end
|
|
27
29
|
|
|
28
30
|
def handle_method_error(error)
|
|
29
31
|
# These are likely bugs in our code, so we should log them prominently
|
|
30
|
-
|
|
31
|
-
analyzer: self.class.name,
|
|
32
|
-
model: model_class.name,
|
|
33
|
-
method: error.name
|
|
34
|
-
})
|
|
32
|
+
report_analyzer_error(error, method: error.name)
|
|
35
33
|
[]
|
|
36
34
|
end
|
|
37
35
|
|
|
38
36
|
def handle_unexpected_error(error)
|
|
39
|
-
|
|
40
|
-
analyzer: self.class.name,
|
|
41
|
-
model: model_class.name,
|
|
42
|
-
type: 'unexpected'
|
|
43
|
-
})
|
|
37
|
+
report_analyzer_error(error, type: 'unexpected')
|
|
44
38
|
[]
|
|
45
39
|
end
|
|
46
40
|
|
|
47
41
|
def safe_call(default = nil)
|
|
48
42
|
yield
|
|
49
43
|
rescue ActiveRecord::StatementInvalid => e
|
|
50
|
-
|
|
51
|
-
analyzer: self.class.name,
|
|
52
|
-
model: model_class.name,
|
|
53
|
-
operation: 'database_query'
|
|
54
|
-
})
|
|
44
|
+
report_analyzer_error(e, operation: 'database_query')
|
|
55
45
|
default
|
|
56
46
|
rescue NoMethodError, NameError => e
|
|
57
|
-
|
|
58
|
-
analyzer: self.class.name,
|
|
59
|
-
model: model_class.name,
|
|
60
|
-
operation: 'method_call'
|
|
61
|
-
})
|
|
47
|
+
report_analyzer_error(e, operation: 'method_call')
|
|
62
48
|
default
|
|
63
49
|
end
|
|
64
50
|
end
|
|
@@ -46,7 +46,7 @@ module RailsLens
|
|
|
46
46
|
if model_class.base_class == model_class
|
|
47
47
|
# This is the base class
|
|
48
48
|
subclasses = find_sti_subclasses
|
|
49
|
-
lines << "subclasses =
|
|
49
|
+
lines << "subclasses = #{TomlFormat.quoted_array(subclasses)}" if subclasses.any?
|
|
50
50
|
lines << 'base = true'
|
|
51
51
|
else
|
|
52
52
|
# This is a subclass
|
|
@@ -55,7 +55,7 @@ module RailsLens
|
|
|
55
55
|
|
|
56
56
|
# Find siblings
|
|
57
57
|
siblings = find_sti_siblings
|
|
58
|
-
lines << "siblings =
|
|
58
|
+
lines << "siblings = #{TomlFormat.quoted_array(siblings)}" if siblings.any?
|
|
59
59
|
end
|
|
60
60
|
|
|
61
61
|
lines.join("\n")
|
|
@@ -73,7 +73,7 @@ module RailsLens
|
|
|
73
73
|
|
|
74
74
|
# Try to find known types
|
|
75
75
|
types = find_delegated_types(reflection)
|
|
76
|
-
lines << "types =
|
|
76
|
+
lines << "types = #{TomlFormat.quoted_array(types)}" if types.any?
|
|
77
77
|
|
|
78
78
|
lines.join("\n")
|
|
79
79
|
end
|
|
@@ -163,7 +163,7 @@ module RailsLens
|
|
|
163
163
|
[]
|
|
164
164
|
end
|
|
165
165
|
if types.any?
|
|
166
|
-
"{ name = \"#{reflection.name}\", type_col = \"#{reflection.foreign_type}\", id_col = \"#{reflection.foreign_key}\", types =
|
|
166
|
+
"{ name = \"#{reflection.name}\", type_col = \"#{reflection.foreign_type}\", id_col = \"#{reflection.foreign_key}\", types = #{TomlFormat.quoted_array(types)} }"
|
|
167
167
|
else
|
|
168
168
|
"{ name = \"#{reflection.name}\", type_col = \"#{reflection.foreign_type}\", id_col = \"#{reflection.foreign_key}\" }"
|
|
169
169
|
end
|
|
@@ -417,16 +417,6 @@ module RailsLens
|
|
|
417
417
|
RailsLens.logger.debug { "Error checking view existence for #{view_name}: #{e.message}" }
|
|
418
418
|
false
|
|
419
419
|
end
|
|
420
|
-
|
|
421
|
-
def needs_explicit_inverse_of?(association)
|
|
422
|
-
# Rails can auto-infer inverse_of for vanilla associations
|
|
423
|
-
# Only require explicit inverse_of when using custom options
|
|
424
|
-
association.options[:class_name].present? ||
|
|
425
|
-
association.options[:foreign_key].present? ||
|
|
426
|
-
association.options[:as].present? ||
|
|
427
|
-
association.options[:source].present? ||
|
|
428
|
-
association.options[:through].present?
|
|
429
|
-
end
|
|
430
420
|
end
|
|
431
421
|
end
|
|
432
422
|
end
|
|
@@ -27,23 +27,13 @@ module RailsLens
|
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
def analyze_query_performance
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
commonly_queried_columns.each do |column|
|
|
34
|
-
next if indexed?(column)
|
|
35
|
-
|
|
36
|
-
notes << NoteCodes.note(column.name, NoteCodes::INDEX)
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
# Check for missing indexes on scoped columns
|
|
40
|
-
scoped_columns.each do |column|
|
|
41
|
-
next if indexed?(column)
|
|
42
|
-
|
|
43
|
-
notes << NoteCodes.note(column.name, NoteCodes::INDEX)
|
|
44
|
-
end
|
|
30
|
+
# Flag commonly-queried and scoped columns that lack an index
|
|
31
|
+
index_notes_for(commonly_queried_columns) + index_notes_for(scoped_columns)
|
|
32
|
+
end
|
|
45
33
|
|
|
46
|
-
|
|
34
|
+
def index_notes_for(columns)
|
|
35
|
+
columns.reject { |column| indexed?(column) }
|
|
36
|
+
.map { |column| NoteCodes.note(column.name, NoteCodes::INDEX) }
|
|
47
37
|
end
|
|
48
38
|
|
|
49
39
|
def uuid_columns
|
|
@@ -68,20 +58,6 @@ module RailsLens
|
|
|
68
58
|
column.name.end_with?('_id')
|
|
69
59
|
end
|
|
70
60
|
end
|
|
71
|
-
|
|
72
|
-
def indexed?(column)
|
|
73
|
-
connection.indexes(table_name).any? do |index|
|
|
74
|
-
index.columns.include?(column.name)
|
|
75
|
-
end
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
def connection
|
|
79
|
-
model_class.connection
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
def table_name
|
|
83
|
-
model_class.table_name
|
|
84
|
-
end
|
|
85
61
|
end
|
|
86
62
|
end
|
|
87
63
|
end
|
|
@@ -20,6 +20,19 @@ module RailsLens
|
|
|
20
20
|
|
|
21
21
|
delegate :clear, to: :@providers
|
|
22
22
|
|
|
23
|
+
# Route a single provider's result into the accumulator hash based on the
|
|
24
|
+
# provider's declared type. Shared by the pipeline and AnnotationManager.
|
|
25
|
+
def self.accumulate_result(results, provider, result)
|
|
26
|
+
case provider.type
|
|
27
|
+
when :schema
|
|
28
|
+
results[:schema] = result
|
|
29
|
+
when :section
|
|
30
|
+
results[:sections] << result if result
|
|
31
|
+
when :notes
|
|
32
|
+
results[:notes].concat(Array(result))
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
23
36
|
def process(model_class)
|
|
24
37
|
results = {
|
|
25
38
|
schema: nil,
|
|
@@ -35,14 +48,7 @@ module RailsLens
|
|
|
35
48
|
begin
|
|
36
49
|
result = provider.process(model_class, connection)
|
|
37
50
|
|
|
38
|
-
|
|
39
|
-
when :schema
|
|
40
|
-
results[:schema] = result
|
|
41
|
-
when :section
|
|
42
|
-
results[:sections] << result if result
|
|
43
|
-
when :notes
|
|
44
|
-
results[:notes].concat(Array(result))
|
|
45
|
-
end
|
|
51
|
+
self.class.accumulate_result(results, provider, result)
|
|
46
52
|
rescue ActiveRecord::StatementInvalid => e
|
|
47
53
|
warn "Provider #{provider.class} database error for #{model_class}: #{e.message}"
|
|
48
54
|
rescue ActiveRecord::ConnectionNotDefined => e
|
data/lib/rails_lens/cli.rb
CHANGED
|
@@ -34,13 +34,13 @@ module RailsLens
|
|
|
34
34
|
commands = Commands.new(self)
|
|
35
35
|
|
|
36
36
|
# Annotate models (default behavior or when --all is specified)
|
|
37
|
-
results[:models] = commands.annotate_models(options) if
|
|
37
|
+
results[:models] = commands.annotate_models(options) if target_models?
|
|
38
38
|
|
|
39
39
|
# Annotate routes
|
|
40
|
-
results[:routes] = commands.annotate_routes(options) if
|
|
40
|
+
results[:routes] = commands.annotate_routes(options) if target_routes?
|
|
41
41
|
|
|
42
42
|
# Annotate mailers
|
|
43
|
-
results[:mailers] = commands.annotate_mailers(options) if
|
|
43
|
+
results[:mailers] = commands.annotate_mailers(options) if target_mailers?
|
|
44
44
|
|
|
45
45
|
results
|
|
46
46
|
end
|
|
@@ -58,13 +58,13 @@ module RailsLens
|
|
|
58
58
|
commands = Commands.new(self)
|
|
59
59
|
|
|
60
60
|
# Remove model annotations (default behavior or when --all is specified)
|
|
61
|
-
results[:models] = commands.remove_models(options) if
|
|
61
|
+
results[:models] = commands.remove_models(options) if target_models?
|
|
62
62
|
|
|
63
63
|
# Remove route annotations
|
|
64
|
-
results[:routes] = commands.remove_routes(options) if
|
|
64
|
+
results[:routes] = commands.remove_routes(options) if target_routes?
|
|
65
65
|
|
|
66
66
|
# Remove mailer annotations
|
|
67
|
-
results[:mailers] = commands.remove_mailers(options) if
|
|
67
|
+
results[:mailers] = commands.remove_mailers(options) if target_mailers?
|
|
68
68
|
|
|
69
69
|
results
|
|
70
70
|
end
|
|
@@ -158,28 +158,17 @@ module RailsLens
|
|
|
158
158
|
RailsLens.config.debug = options[:debug]
|
|
159
159
|
end
|
|
160
160
|
|
|
161
|
-
# Helper methods to determine what to annotate/remove
|
|
162
|
-
|
|
161
|
+
# Helper methods to determine what to annotate/remove. The same targeting
|
|
162
|
+
# rules apply to both the annotate and remove commands.
|
|
163
|
+
def target_models?
|
|
163
164
|
(!options[:routes] && !options[:mailers]) || options[:all]
|
|
164
165
|
end
|
|
165
166
|
|
|
166
|
-
def
|
|
167
|
+
def target_routes?
|
|
167
168
|
options[:routes] || options[:all]
|
|
168
169
|
end
|
|
169
170
|
|
|
170
|
-
def
|
|
171
|
-
options[:mailers] || options[:all]
|
|
172
|
-
end
|
|
173
|
-
|
|
174
|
-
def should_remove_models?
|
|
175
|
-
(!options[:routes] && !options[:mailers]) || options[:all]
|
|
176
|
-
end
|
|
177
|
-
|
|
178
|
-
def should_remove_routes?
|
|
179
|
-
options[:routes] || options[:all]
|
|
180
|
-
end
|
|
181
|
-
|
|
182
|
-
def should_remove_mailers?
|
|
171
|
+
def target_mailers?
|
|
183
172
|
options[:mailers] || options[:all]
|
|
184
173
|
end
|
|
185
174
|
end
|
|
@@ -31,32 +31,31 @@ module RailsLens
|
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
def handle_model_error(error)
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
say 'Try running: bundle exec rails_lens annotate', :yellow
|
|
38
|
-
end
|
|
39
|
-
exit 1
|
|
34
|
+
report_error('Model Error', error,
|
|
35
|
+
'Make sure your Rails application is properly loaded',
|
|
36
|
+
'Try running: bundle exec rails_lens annotate')
|
|
40
37
|
end
|
|
41
38
|
|
|
42
39
|
def handle_database_error(error)
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
say ' - Permission denied', :yellow
|
|
50
|
-
end
|
|
51
|
-
exit 1
|
|
40
|
+
report_error('Database Error', error,
|
|
41
|
+
'Possible causes:',
|
|
42
|
+
' - Database server is not running',
|
|
43
|
+
' - Invalid database credentials',
|
|
44
|
+
' - Table does not exist',
|
|
45
|
+
' - Permission denied')
|
|
52
46
|
end
|
|
53
47
|
|
|
54
48
|
def handle_annotation_error(error)
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
49
|
+
report_error('Annotation Error', error,
|
|
50
|
+
'Failed to annotate one or more files',
|
|
51
|
+
'Check file permissions and syntax')
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Print a red "<label>: <message>", optional verbose-only yellow hints,
|
|
55
|
+
# then exit non-zero.
|
|
56
|
+
def report_error(label, error, *verbose_hints)
|
|
57
|
+
say "#{label}: #{error.message}", :red
|
|
58
|
+
verbose_hints.each { |hint| say hint, :yellow } if options[:verbose]
|
|
60
59
|
exit 1
|
|
61
60
|
end
|
|
62
61
|
|