annotaterb 4.13.0 → 4.15.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7adb0604dd67e60d6658add880eeee01a0367c86f9f0088f557fcb6ab42605c6
4
- data.tar.gz: faa6374c64ffb979d1690c896cc564c526a6641b2fd79adc8bc922fad2fb25c0
3
+ metadata.gz: a31463c338bd23299c7249e3c444d8c1b630157bf9905cfeb203dfafb1a4d16a
4
+ data.tar.gz: ad12fccdeeb0186d6627ba237c417c637b1b6136f354313e81f09de90cef4665
5
5
  SHA512:
6
- metadata.gz: 6250eab94f83dd0c3a40d670ad6a151532199d0183f6d13893775094e5581f6bf2513205b04f29034f0c35c8a1e0c34911a964efcb2c3104cfde0c2d6af0c1d0
7
- data.tar.gz: 39210bfcf75338adf0a0bc88b31720427ed28b2679abed39ee4aa7b2500b88a170665a330a4f709a6c08f1e9d8e628c553502a4143bf4ea5be5eb96e464ebb61
6
+ metadata.gz: af6ec6a16d36b65b00eb28f4736c46682aa0d47da4869503eaecb8a58a8ff34f783ac3986c09200f125279666a8b30658af1ba91a9ad5829d789846c1c9e82dd
7
+ data.tar.gz: ad7fbd08360072a24c2fbea2808c180806ae89da5775689d1f7cc2824fead770b771ac41667056e68da0921ae13948a6f3da48883ab2f0328506cbf7158a63c0
data/CHANGELOG.md CHANGED
@@ -1,5 +1,48 @@
1
1
  # Changelog
2
2
 
3
+ ## [v4.14.0](https://github.com/drwl/annotaterb/tree/v4.14.0) (2025-02-17)
4
+
5
+ [Full Changelog](https://github.com/drwl/annotaterb/compare/v4.13.0...v4.14.0)
6
+
7
+ **Closed issues:**
8
+
9
+ - How do I annotate models but NOT routes? [\#178](https://github.com/drwl/annotaterb/issues/178)
10
+ - Model Annotation Not Updated When Modifying Table Columns Using change\_table. [\#169](https://github.com/drwl/annotaterb/issues/169)
11
+ - annotate\_rb:install failing on Rails 8 [\#168](https://github.com/drwl/annotaterb/issues/168)
12
+ - Annotations with enums changing between db:create db:migrate and then db:migrate [\#167](https://github.com/drwl/annotaterb/issues/167)
13
+ - JSON parse error [\#155](https://github.com/drwl/annotaterb/issues/155)
14
+ - Feature: Add Support for dynamic fixtures with ERB [\#149](https://github.com/drwl/annotaterb/issues/149)
15
+
16
+ **Merged pull requests:**
17
+
18
+ - Bump version to v4.14.0 [\#190](https://github.com/drwl/annotaterb/pull/190) ([drwl](https://github.com/drwl))
19
+ - Add expected file to automatically require [\#185](https://github.com/drwl/annotaterb/pull/185) ([drwl](https://github.com/drwl))
20
+ - Fix translation foreign key exclusion bug [\#181](https://github.com/drwl/annotaterb/pull/181) ([galori](https://github.com/galori))
21
+ - Lock `concurrent-ruby` gem to fix CI [\#180](https://github.com/drwl/annotaterb/pull/180) ([tagliala](https://github.com/tagliala))
22
+ - Chore: alert when multiple conmmands were selected [\#179](https://github.com/drwl/annotaterb/pull/179) ([OdenTakashi](https://github.com/OdenTakashi))
23
+ - Updated COLUMN\_PATTERN to handle optional metadata \(e.g., constraints or descriptions\) enclosed in parentheses. [\#170](https://github.com/drwl/annotaterb/pull/170) ([hatsu38](https://github.com/hatsu38))
24
+ - Opt-in for MFA requirement [\#166](https://github.com/drwl/annotaterb/pull/166) ([tagliala](https://github.com/tagliala))
25
+ - Fix typos [\#165](https://github.com/drwl/annotaterb/pull/165) ([tagliala](https://github.com/tagliala))
26
+ - Add support for virtual columns [\#163](https://github.com/drwl/annotaterb/pull/163) ([robbevp](https://github.com/robbevp))
27
+ - Generate changelog for v4.13.0 [\#160](https://github.com/drwl/annotaterb/pull/160) ([drwl](https://github.com/drwl))
28
+
29
+ ## [v4.13.0](https://github.com/drwl/annotaterb/tree/v4.13.0) (2024-10-21)
30
+
31
+ [Full Changelog](https://github.com/drwl/annotaterb/compare/v4.12.0...v4.13.0)
32
+
33
+ **Closed issues:**
34
+
35
+ - Bug: Bigint are reported as integer [\#157](https://github.com/drwl/annotaterb/issues/157)
36
+ - Bug \(apparently\): :ignore\_columns does not work \(with any syntax I've tried\) [\#154](https://github.com/drwl/annotaterb/issues/154)
37
+
38
+ **Merged pull requests:**
39
+
40
+ - Bump version to v4.13.0 [\#159](https://github.com/drwl/annotaterb/pull/159) ([drwl](https://github.com/drwl))
41
+ - Support parsing of dynamic fixture erb yml files [\#158](https://github.com/drwl/annotaterb/pull/158) ([drwl](https://github.com/drwl))
42
+ - Fix updating of indexes containing escaped characters [\#156](https://github.com/drwl/annotaterb/pull/156) ([antonivanopoulos](https://github.com/antonivanopoulos))
43
+ - Add model with association and foreign key to dummyapp [\#153](https://github.com/drwl/annotaterb/pull/153) ([drwl](https://github.com/drwl))
44
+ - Generate changelog for v4.12.0 [\#152](https://github.com/drwl/annotaterb/pull/152) ([drwl](https://github.com/drwl))
45
+
3
46
  ## [v4.12.0](https://github.com/drwl/annotaterb/tree/v4.12.0) (2024-09-15)
4
47
 
5
48
  [Full Changelog](https://github.com/drwl/annotaterb/compare/v4.11.0...v4.12.0)
@@ -276,7 +319,7 @@
276
319
  - Fix the default behavior for model annotator [\#20](https://github.com/drwl/annotaterb/pull/20) ([drwl](https://github.com/drwl))
277
320
  - Refactor model annotator [\#19](https://github.com/drwl/annotaterb/pull/19) ([drwl](https://github.com/drwl))
278
321
  - Removed unused helper methods and `Env` class [\#18](https://github.com/drwl/annotaterb/pull/18) ([drwl](https://github.com/drwl))
279
- - Update dummy app depdencies [\#17](https://github.com/drwl/annotaterb/pull/17) ([drwl](https://github.com/drwl))
322
+ - Update dummy app dependencies [\#17](https://github.com/drwl/annotaterb/pull/17) ([drwl](https://github.com/drwl))
280
323
 
281
324
  ## [v4.0.0](https://github.com/drwl/annotaterb/tree/v4.0.0) (2023-05-03)
282
325
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 4.13.0
1
+ 4.15.0
@@ -15,10 +15,9 @@ module AnnotateRb
15
15
  klass.eager_load!
16
16
  end
17
17
  else
18
- options[:model_dir].each do |dir|
19
- ::Rake::FileList["#{dir}/**/*.rb"].each do |fname|
20
- require File.expand_path(fname)
21
- end
18
+ model_files = ModelAnnotator::ModelFilesGetter.call(options)
19
+ model_files&.each do |model_file|
20
+ require model_file
22
21
  end
23
22
  end
24
23
  end
@@ -5,7 +5,13 @@ module AnnotateRb
5
5
  # Compares the current file content and new annotation block and generates the column annotation differences
6
6
  class AnnotationDiffGenerator
7
7
  HEADER_PATTERN = /(^# Table name:.*?\n(#.*\r?\n)*\r?)/
8
- COLUMN_PATTERN = /^#[\t ]+[\w*.`\[\]():]+[\t ]+.+$/
8
+ # Example matches:
9
+ # - "# id :uuid not null, primary key"
10
+ # - "# title(length 255) :string not null"
11
+ # - "# status(a/b/c) :string not null"
12
+ # - "# created_at :datetime not null"
13
+ # - "# updated_at :datetime not null"
14
+ COLUMN_PATTERN = /^#[\t ]+[\w*.`\[\]():]+(?:\(.*?\))?[\t ]+.+$/
9
15
 
10
16
  class << self
11
17
  def call(file_content, annotation_block)
@@ -70,14 +70,26 @@ module AnnotateRb
70
70
  sorted_column_indices&.each do |index|
71
71
  indexed_columns = index.columns.reject { |i| i == @column.name }
72
72
 
73
- attrs << if indexed_columns.empty?
73
+ index_text = if index.unique
74
+ "uniquely indexed"
75
+ else
74
76
  "indexed"
77
+ end
78
+
79
+ attrs << if indexed_columns.empty?
80
+ index_text
75
81
  else
76
- "indexed => [#{indexed_columns.join(", ")}]"
82
+ "#{index_text} => [#{indexed_columns.join(", ")}]"
77
83
  end
78
84
  end
79
85
  end
80
86
 
87
+ # Check if the column is a virtual column and print the function
88
+ if @options[:show_virtual_columns] && @column.virtual?
89
+ # Any whitespace in the function gets reduced to a single space
90
+ attrs << @column.default_function.gsub(/\s+/, " ").strip
91
+ end
92
+
81
93
  attrs
82
94
  end
83
95
 
@@ -85,6 +85,14 @@ module AnnotateRb
85
85
  @column.name
86
86
  end
87
87
 
88
+ def virtual?
89
+ @column.respond_to?(:virtual?) && @column.virtual?
90
+ end
91
+
92
+ def default_function
93
+ @column.default_function
94
+ end
95
+
88
96
  private
89
97
 
90
98
  # Simple quoting for the default column value
@@ -25,6 +25,8 @@ module AnnotateRb
25
25
 
26
26
  if is_decimal_type
27
27
  formatted_column_type = "decimal(#{@column.precision}, #{@column.scale})"
28
+ elsif @options[:show_virtual_columns] && @column.virtual?
29
+ formatted_column_type = "virtual(#{column_type})"
28
30
  elsif is_special_type
29
31
  # Do nothing. Kept as a code fragment in case we need to do something here.
30
32
  elsif @column.limit && !@options[:format_yard]
@@ -13,7 +13,8 @@ module AnnotateRb
13
13
 
14
14
  return model_files if model_files.any?
15
15
 
16
- options[:model_dir].each do |dir|
16
+ model_dirs = options[:model_dir].flat_map { |model_dir| Dir[model_dir] }
17
+ model_dirs.each do |dir|
17
18
  Dir.chdir(dir) do
18
19
  list = if options[:ignore_model_sub_dir]
19
20
  Dir["*.rb"].map { |f| [dir, f] }
@@ -26,12 +27,14 @@ module AnnotateRb
26
27
  end
27
28
  end
28
29
 
29
- model_files
30
- rescue SystemCallError
31
- warn "No models found in directory '#{options[:model_dir].join("', '")}'."
32
- warn "Either specify models on the command line, or use the --model-dir option."
33
- warn "Call 'annotaterb --help' for more info."
34
- # exit 1 # TODO: Return exit code back to caller. Right now it messes up RSpec being able to run
30
+ if model_files.empty?
31
+ warn "No models found in directory '#{options[:model_dir].join("', '")}'."
32
+ warn "Either specify models on the command line, or use the --model-dir option."
33
+ warn "Call 'annotaterb --help' for more info."
34
+ # exit 1 # TODO: Return exit code back to caller. Right now it messes up RSpec being able to run
35
+ else
36
+ model_files
37
+ end
35
38
  end
36
39
 
37
40
  private
@@ -6,6 +6,8 @@ module AnnotateRb
6
6
  # Should be the wrapper for an ActiveRecord model that serves as the source of truth of the model
7
7
  # of the model that we're annotating
8
8
 
9
+ DEFAULT_TIMESTAMP_COLUMNS = %w[created_at updated_at]
10
+
9
11
  def initialize(klass, options)
10
12
  @klass = klass
11
13
  @options = options
@@ -107,6 +109,10 @@ module AnnotateRb
107
109
  end
108
110
 
109
111
  def retrieve_indexes_from_table
112
+ @indexes_from_table ||= _retrieve_indexes_from_table
113
+ end
114
+
115
+ def _retrieve_indexes_from_table
110
116
  table_name = @klass.table_name
111
117
  return [] unless table_name
112
118
 
@@ -114,7 +120,7 @@ module AnnotateRb
114
120
  return indexes if indexes.any? || !@klass.table_name_prefix
115
121
 
116
122
  # Try to search the table without prefix
117
- table_name_without_prefix = table_name.to_s.sub(@klass.table_name_prefix, "")
123
+ table_name_without_prefix = table_name.to_s.sub(@klass.table_name_prefix.to_s, "")
118
124
  begin
119
125
  @klass.connection.indexes(table_name_without_prefix)
120
126
  rescue ActiveRecord::StatementInvalid => _e
@@ -143,10 +149,13 @@ module AnnotateRb
143
149
  associations = []
144
150
  id = nil
145
151
 
152
+ # specs don't load defaults, so ensure we have defaults here
153
+ timestamp_columns = @options[:timestamp_columns] || DEFAULT_TIMESTAMP_COLUMNS
154
+
146
155
  cols.each do |c|
147
156
  if c.name.eql?("id")
148
157
  id = c
149
- elsif c.name.eql?("created_at") || c.name.eql?("updated_at")
158
+ elsif timestamp_columns.include?(c.name)
150
159
  timestamps << c
151
160
  elsif c.name[-3, 3].eql?("_id")
152
161
  associations << c
@@ -154,7 +163,10 @@ module AnnotateRb
154
163
  rest_cols << c
155
164
  end
156
165
  end
157
- [rest_cols, timestamps, associations].each { |a| a.sort_by!(&:name) }
166
+
167
+ timestamp_order = timestamp_columns.each_with_index.to_h
168
+ timestamps.sort_by! { |col| timestamp_order[col.name] }
169
+ [rest_cols, associations].each { |a| a.sort_by!(&:name) }
158
170
 
159
171
  ([id] << rest_cols << timestamps << associations).flatten.compact
160
172
  end
@@ -162,21 +174,12 @@ module AnnotateRb
162
174
  # These are the columns that the globalize gem needs to work but
163
175
  # are not necessary for the models to be displayed as annotations.
164
176
  def ignored_translation_table_columns
165
- # Construct the foreign column name in the translations table
166
- # eg. Model: Car, foreign column name: car_id
167
- foreign_column_name = [
168
- @klass.translation_class.to_s
169
- .gsub("::Translation", "").gsub("::", "_")
170
- .downcase,
171
- "_id"
172
- ].join.to_sym
173
-
174
177
  [
175
178
  :id,
176
179
  :created_at,
177
180
  :updated_at,
178
181
  :locale,
179
- foreign_column_name
182
+ @klass.name.foreign_key.to_sym
180
183
  ]
181
184
  end
182
185
  end
@@ -64,7 +64,10 @@ module AnnotateRb
64
64
  def get
65
65
  current_patterns = []
66
66
 
67
- @options[:root_dir].each do |root_directory|
67
+ root_dirs = @options[:root_dir].flat_map do |root_dir|
68
+ root_dir.empty? ? root_dir : Dir[root_dir]
69
+ end
70
+ root_dirs.each do |root_directory|
68
71
  Array(@pattern_types).each do |pattern_type|
69
72
  patterns = generate(root_directory, pattern_type)
70
73
 
@@ -34,6 +34,7 @@ module AnnotateRb
34
34
  private
35
35
 
36
36
  def build_instructions_for_file(file)
37
+ start = Time.now
37
38
  klass = ModelClassGetter.call(file, @options)
38
39
 
39
40
  instructions = []
@@ -52,6 +53,10 @@ module AnnotateRb
52
53
  end
53
54
  instructions.concat(related_file_instructions)
54
55
 
56
+ if @options[:debug]
57
+ puts "Built instructions for #{file} in #{Time.now - start}s"
58
+ end
59
+
55
60
  instructions
56
61
  end
57
62
 
@@ -48,6 +48,7 @@ module AnnotateRb
48
48
  show_check_constraints: false, # ModelAnnotator
49
49
  show_foreign_keys: true, # ModelAnnotator
50
50
  show_indexes: true, # ModelAnnotator
51
+ show_virtual_columns: false, # ModelAnnotator
51
52
  simple_indexes: false, # ModelAnnotator
52
53
  sort: false, # ModelAnnotator
53
54
  timestamp: false, # RouteAnnotator
@@ -68,6 +69,9 @@ module AnnotateRb
68
69
  # ModelAnnotator
69
70
  hide_limit_column_types: "",
70
71
 
72
+ # ModelAnnotator
73
+ timestamp_columns: ModelAnnotator::ModelWrapper::DEFAULT_TIMESTAMP_COLUMNS,
74
+
71
75
  ignore_columns: nil, # ModelAnnotator
72
76
  ignore_routes: nil, # RouteAnnotator
73
77
  ignore_unknown_models: false, # ModelAnnotator
@@ -129,6 +133,7 @@ module AnnotateRb
129
133
  :debug,
130
134
  :hide_default_column_types,
131
135
  :hide_limit_column_types,
136
+ :timestamp_columns,
132
137
  :ignore_columns,
133
138
  :ignore_routes,
134
139
  :ignore_unknown_models,
@@ -78,11 +78,12 @@ module AnnotateRb
78
78
  version: Commands::PrintVersion.new
79
79
  }
80
80
 
81
+ if @commands.size > 1
82
+ warn "Only one command can be run at a time"
83
+ end
84
+
81
85
  @options[:command] = if @commands.any?
82
86
  map[@commands.first]
83
- elsif @commands.size > 1
84
- # TODO: Should raise or alert user that multiple commands were selected but only 1 command will be ran
85
- map[@commands.first]
86
87
  else # None
87
88
  map[:help]
88
89
  end
data/lib/annotaterb.rb ADDED
@@ -0,0 +1,4 @@
1
+ # Gem names that follow naming convention work seamlessly. However, this gem is "annotaterb" where in code it is
2
+ # AnnotateRb. Because of this, we need this file so that the rest of the library automatically gets required.
3
+
4
+ require "annotate_rb"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: annotaterb
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.13.0
4
+ version: 4.15.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew W. Lee
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-10-21 00:00:00.000000000 Z
11
+ date: 2025-05-30 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Annotates Rails/ActiveRecord Models, routes, fixtures, and others based
14
14
  on the database schema.
@@ -104,6 +104,7 @@ files:
104
104
  - lib/annotate_rb/route_annotator/removal_processor.rb
105
105
  - lib/annotate_rb/runner.rb
106
106
  - lib/annotate_rb/tasks/annotate_models_migrate.rake
107
+ - lib/annotaterb.rb
107
108
  - lib/generators/annotate_rb/config/USAGE
108
109
  - lib/generators/annotate_rb/config/config_generator.rb
109
110
  - lib/generators/annotate_rb/hook/USAGE
@@ -119,8 +120,9 @@ licenses:
119
120
  metadata:
120
121
  homepage_uri: https://github.com/drwl/annotaterb
121
122
  source_code_uri: https://github.com/drwl/annotaterb
122
- changelog_uri: https://github.com/drwl/annotaterb/blob/master/CHANGELOG.md
123
+ changelog_uri: https://github.com/drwl/annotaterb/blob/main/CHANGELOG.md
123
124
  bug_tracker_uri: https://github.com/drwl/annotaterb/issues
125
+ rubygems_mfa_required: 'true'
124
126
  post_install_message:
125
127
  rdoc_options: []
126
128
  require_paths:
@@ -136,7 +138,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
136
138
  - !ruby/object:Gem::Version
137
139
  version: '0'
138
140
  requirements: []
139
- rubygems_version: 3.5.11
141
+ rubygems_version: 3.5.22
140
142
  signing_key:
141
143
  specification_version: 4
142
144
  summary: A gem for generating annotations for Rails projects.