annotate 2.6.5 → 2.6.6
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 +8 -8
- data/CHANGELOG.rdoc +7 -0
- data/README.rdoc +23 -15
- data/TODO.rdoc +0 -1
- data/annotate.gemspec +2 -3
- data/bin/annotate +33 -9
- data/lib/annotate.rb +13 -7
- data/lib/annotate/annotate_models.rb +89 -47
- data/lib/annotate/annotate_routes.rb +1 -1
- data/lib/annotate/version.rb +1 -1
- data/lib/tasks/annotate_models.rake +4 -1
- metadata +18 -8
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
MzQ3ZjQ5NmY5Njc0ZjZiYjIyODVjODY3NDdlZjhlODYwMDAwZjMxYw==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
ZDNlMGM0YWFmMWMxZjFjZjE1N2U4MTc3NTVhNjMwMDE3MTlhMzI1ZQ==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
ZGRhYTFjOGUwOWVlZThhNGY1MzY4OWMwZGIwYTgxMjE4ZmZmZjE0ZmFjYjE1
|
10
|
+
ZGJkOGJmZmNjODRkZTRlNTc0MDg1Nzk4Y2Q5Y2QwZTc3MTBlNzJhZGU0NDIx
|
11
|
+
ZjM0MTJlOWI2MWJhMTY3YWY4Nzc5YTkyZWEzYTlmM2U1N2E0NjE=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
YzEzMDgwNmUyMzk5ODA1ZjRlMTZkMDY3MzQ0ZmYwM2U1YTliMzcxZjU3ZGUw
|
14
|
+
NzU1NjMwNDMxNGI0OTZiMTA3NjVkNzZjNGJjMDQ2YmZhNGZlYWIzZjdmNWMx
|
15
|
+
MzE4NmE1ZGViZmM5MTJmOTNkYmFjYTRiMTAxMjRiMDE4MjFkZmM=
|
data/CHANGELOG.rdoc
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
== 2.6.6
|
2
|
+
* Makes it possible to wrap annotations, #225
|
3
|
+
* Fix single model generation, #214
|
4
|
+
* Fix default value for Rails 4.2, #212
|
5
|
+
* Don't crash on inherited models in subdirectories, #232
|
6
|
+
* Process model_dir in rake task, #197
|
7
|
+
|
1
8
|
== 2.6.4
|
2
9
|
* Skip "models/concerns", #194
|
3
10
|
* Fix #173 where annotate says "Nothing to annotate" in rails 4.2
|
data/README.rdoc
CHANGED
@@ -51,7 +51,7 @@ Also, if you pass the -r option, it'll annotate routes.rb with the output of
|
|
51
51
|
|
52
52
|
Into Gemfile from rubygems.org:
|
53
53
|
|
54
|
-
gem 'annotate',
|
54
|
+
gem 'annotate', '~> 2.6.5'
|
55
55
|
|
56
56
|
Into Gemfile from Github:
|
57
57
|
|
@@ -86,13 +86,13 @@ To annotate just your models, tests, and factories:
|
|
86
86
|
|
87
87
|
To annotate just your models:
|
88
88
|
|
89
|
-
annotate --exclude tests,fixtures,factories
|
89
|
+
annotate --exclude tests,fixtures,factories,serializers
|
90
90
|
|
91
91
|
To annotate routes.rb:
|
92
92
|
|
93
93
|
annotate --routes
|
94
94
|
|
95
|
-
To remove model/test/fixture/factory annotations:
|
95
|
+
To remove model/test/fixture/factory/serializer annotations:
|
96
96
|
|
97
97
|
annotate --delete
|
98
98
|
|
@@ -137,11 +137,11 @@ executed whenever you run +rake db:migrate+ (but only in development mode).
|
|
137
137
|
If you want to disable this behavior permanently, edit the +.rake+ file and
|
138
138
|
change:
|
139
139
|
|
140
|
-
'skip_on_db_migrate' =>
|
140
|
+
'skip_on_db_migrate' => 'false',
|
141
141
|
|
142
142
|
To:
|
143
143
|
|
144
|
-
'skip_on_db_migrate' =>
|
144
|
+
'skip_on_db_migrate' => 'true',
|
145
145
|
|
146
146
|
If you want to run +rake db:migrate+ as a one-off without running annotate,
|
147
147
|
you can do so with a simple environment variable, instead of editing the
|
@@ -154,33 +154,41 @@ you can do so with a simple environment variable, instead of editing the
|
|
154
154
|
|
155
155
|
Usage: annotate [options] [model_file]*
|
156
156
|
-d, --delete Remove annotations from all model files or the routes.rb file
|
157
|
-
-p, --position [before|after] Place the annotations at the top (before) or the bottom (after) of the model/test/fixture/factory/routes file(s)
|
158
|
-
--pc, --position-in-class [before|after]
|
157
|
+
-p, --position [before|top|after|bottom] Place the annotations at the top (before) or the bottom (after) of the model/test/fixture/factory/routes file(s)
|
158
|
+
--pc, --position-in-class [before|top|after|bottom]
|
159
159
|
Place the annotations at the top (before) or the bottom (after) of the model file
|
160
|
-
--pf, --position-in-factory [before|after]
|
160
|
+
--pf, --position-in-factory [before|top|after|bottom]
|
161
161
|
Place the annotations at the top (before) or the bottom (after) of any factory files
|
162
|
-
--px, --position-in-fixture [before|after]
|
162
|
+
--px, --position-in-fixture [before|top|after|bottom]
|
163
163
|
Place the annotations at the top (before) or the bottom (after) of any fixture files
|
164
|
-
--pt, --position-in-test [before|after]
|
164
|
+
--pt, --position-in-test [before|top|after|bottom]
|
165
165
|
Place the annotations at the top (before) or the bottom (after) of any test files
|
166
|
-
--pr, --position-in-routes [before|after]
|
166
|
+
--pr, --position-in-routes [before|top|after|bottom]
|
167
167
|
Place the annotations at the top (before) or the bottom (after) of the routes.rb file
|
168
|
+
--ps, --position-in-serializer [before|top|after|bottom]
|
169
|
+
Place the annotations at the top (before) or the bottom (after) of the serializer files
|
170
|
+
--w, --wrapper STR Wrap annotation with the text passed as parameter.
|
171
|
+
If --w option is used, the same text will be used as opening and closing
|
172
|
+
--wo, --wrapper-open STR Annotation wrapper opening.
|
173
|
+
--wc, --wrapper-close STR Annotation wrapper closing
|
168
174
|
-r, --routes Annotate routes.rb with the output of 'rake routes'
|
169
175
|
-v, --version Show the current version of this gem
|
170
176
|
-m, --show-migration Include the migration version number in the annotation
|
171
177
|
-i, --show-indexes List the table's database indexes in the annotation
|
172
178
|
-s, --simple-indexes Concat the column's related indexes in the annotation
|
173
|
-
--model-dir dir Annotate model files stored in dir rather than app/models
|
179
|
+
--model-dir dir Annotate model files stored in dir rather than app/models, separate multiple dirs with comas
|
174
180
|
--ignore-model-subdirects Ignore subdirectories of the models directory
|
175
181
|
--sort Sort columns alphabetically, rather than in creation order
|
176
182
|
-R, --require path Additional file to require before loading models, may be used multiple times
|
177
|
-
-e [tests,fixtures,factories],
|
178
|
-
--exclude
|
183
|
+
-e [tests,fixtures,factories,serializers],
|
184
|
+
--exclude Do not annotate fixtures, test files, factories, and/or serializers
|
179
185
|
-f [bare|rdoc|markdown], Render Schema Infomation as plain/RDoc/Markdown
|
180
186
|
--format
|
181
187
|
--force Force new annotations even if there are no changes.
|
188
|
+
--timestamp Include timestamp in (routes) annotation
|
182
189
|
--trace If unable to annotate a file, print the full stack trace, not just the exception message.
|
183
|
-
--
|
190
|
+
-I, --ignore-columns REGEX don't annotate columns that match a given REGEX (i.e., `annotate -I '^(id|updated_at|created_at)'`
|
191
|
+
|
184
192
|
|
185
193
|
|
186
194
|
== Sorting
|
data/TODO.rdoc
CHANGED
data/annotate.gemspec
CHANGED
@@ -8,8 +8,7 @@ Gem::Specification.new do |s|
|
|
8
8
|
s.version = Annotate.version
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
-
s.authors = ["
|
12
|
-
s.date = "2014-06-16"
|
11
|
+
s.authors = ["Alex Chaffee", "Cuong Tran", "Marcos Piccinini", "Turadg Aleahmad", "Jon Frisby"]
|
13
12
|
s.description = "Annotates Rails/ActiveRecord Models, routes, fixtures, and others based on the database schema."
|
14
13
|
s.email = ["alex@stinky.com", "cuong.tran@gmail.com", "x@nofxx.com", "turadg@aleahmad.net", "jon@cloudability.com"]
|
15
14
|
s.executables = ["annotate"]
|
@@ -26,7 +25,7 @@ Gem::Specification.new do |s|
|
|
26
25
|
s.specification_version = 4
|
27
26
|
|
28
27
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
29
|
-
s.add_runtime_dependency(%q<rake>, [">=
|
28
|
+
s.add_runtime_dependency(%q<rake>, ["~> 10.4.2", ">= 10.4.2"])
|
30
29
|
s.add_runtime_dependency(%q<activerecord>, [">= 2.3.0"])
|
31
30
|
else
|
32
31
|
s.add_dependency(%q<rake>, [">= 0.8.7"])
|
data/bin/annotate
CHANGED
@@ -32,46 +32,65 @@ OptionParser.new do |opts|
|
|
32
32
|
target[:task] = :remove_annotations
|
33
33
|
end
|
34
34
|
|
35
|
-
opts.on('-p', '--position [before|after]', ['before', 'after'],
|
35
|
+
opts.on('-p', '--position [before|top|after|bottom]', ['before', 'top', 'after', 'bottom'],
|
36
36
|
"Place the annotations at the top (before) or the bottom (after) of the model/test/fixture/factory/routes file(s)") do |p|
|
37
37
|
ENV['position'] = p
|
38
38
|
[
|
39
|
-
'position_in_class','position_in_factory','position_in_fixture','position_in_test', 'position_in_routes'
|
39
|
+
'position_in_class','position_in_factory','position_in_fixture','position_in_test', 'position_in_routes', 'position_in_serializer'
|
40
40
|
].each do |key|
|
41
41
|
ENV[key] = p unless(has_set_position[key])
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
-
opts.on('--pc', '--position-in-class [before|after]', ['before', 'after'],
|
45
|
+
opts.on('--pc', '--position-in-class [before|top|after|bottom]', ['before', 'top', 'after', 'bottom'],
|
46
46
|
"Place the annotations at the top (before) or the bottom (after) of the model file") do |p|
|
47
47
|
ENV['position_in_class'] = p
|
48
48
|
has_set_position['position_in_class'] = true
|
49
49
|
end
|
50
50
|
|
51
|
-
opts.on('--pf', '--position-in-factory [before|after]', ['before', 'after'],
|
51
|
+
opts.on('--pf', '--position-in-factory [before|top|after|bottom]', ['before', 'top', 'after', 'bottom'],
|
52
52
|
"Place the annotations at the top (before) or the bottom (after) of any factory files") do |p|
|
53
53
|
ENV['position_in_factory'] = p
|
54
54
|
has_set_position['position_in_factory'] = true
|
55
55
|
end
|
56
56
|
|
57
|
-
opts.on('--px', '--position-in-fixture [before|after]', ['before', 'after'],
|
57
|
+
opts.on('--px', '--position-in-fixture [before|top|after|bottom]', ['before', 'top', 'after', 'bottom'],
|
58
58
|
"Place the annotations at the top (before) or the bottom (after) of any fixture files") do |p|
|
59
59
|
ENV['position_in_fixture'] = p
|
60
60
|
has_set_position['position_in_fixture'] = true
|
61
61
|
end
|
62
62
|
|
63
|
-
opts.on('--pt', '--position-in-test [before|after]', ['before', 'after'],
|
63
|
+
opts.on('--pt', '--position-in-test [before|top|after|bottom]', ['before', 'top', 'after', 'bottom'],
|
64
64
|
"Place the annotations at the top (before) or the bottom (after) of any test files") do |p|
|
65
65
|
ENV['position_in_test'] = p
|
66
66
|
has_set_position['position_in_test'] = true
|
67
67
|
end
|
68
68
|
|
69
|
-
opts.on('--pr', '--position-in-routes [before|after]', ['before', 'after'],
|
69
|
+
opts.on('--pr', '--position-in-routes [before|top|after|bottom]', ['before', 'top', 'after', 'bottom'],
|
70
70
|
"Place the annotations at the top (before) or the bottom (after) of the routes.rb file") do |p|
|
71
71
|
ENV['position_in_routes'] = p
|
72
72
|
has_set_position['position_in_routes'] = true
|
73
73
|
end
|
74
74
|
|
75
|
+
opts.on('--ps', '--position-in-serializer [before|top|after|bottom]', ['before', 'top', 'after', 'bottom'],
|
76
|
+
"Place the annotations at the top (before) or the bottom (after) of the serializer files") do |p|
|
77
|
+
ENV['position_in_serializer'] = p
|
78
|
+
has_set_position['position_in_serializer'] = true
|
79
|
+
end
|
80
|
+
|
81
|
+
opts.on('--w', '--wrapper STR', 'Wrap annotation with the text passed as parameter.',
|
82
|
+
'If --w option is used, the same text will be used as opening and closing') do |p|
|
83
|
+
ENV['wrapper'] = p
|
84
|
+
end
|
85
|
+
|
86
|
+
opts.on('--wo', '--wrapper-open STR', 'Annotation wrapper opening.') do |p|
|
87
|
+
ENV['wrapper_open'] = p
|
88
|
+
end
|
89
|
+
|
90
|
+
opts.on('--wc', '--wrapper-close STR', 'Annotation wrapper closing') do |p|
|
91
|
+
ENV['wrapper_close'] = p
|
92
|
+
end
|
93
|
+
|
75
94
|
opts.on('-r', '--routes',
|
76
95
|
"Annotate routes.rb with the output of 'rake routes'") do
|
77
96
|
target = {
|
@@ -101,7 +120,7 @@ OptionParser.new do |opts|
|
|
101
120
|
end
|
102
121
|
|
103
122
|
opts.on('--model-dir dir',
|
104
|
-
"Annotate model files stored in dir rather than app/models") do |dir|
|
123
|
+
"Annotate model files stored in dir rather than app/models, separate multiple dirs with comas") do |dir|
|
105
124
|
ENV['model_dir'] = dir
|
106
125
|
end
|
107
126
|
|
@@ -115,6 +134,11 @@ OptionParser.new do |opts|
|
|
115
134
|
ENV['sort'] = "yes"
|
116
135
|
end
|
117
136
|
|
137
|
+
opts.on('--classified-sort',
|
138
|
+
"Sort columns alphabetically, but first goes id, then the rest columns, then the timestamp columns and then the association columns") do |dir|
|
139
|
+
ENV['classified_sort'] = "yes"
|
140
|
+
end
|
141
|
+
|
118
142
|
opts.on('-R', '--require path',
|
119
143
|
"Additional file to require before loading models, may be used multiple times") do |path|
|
120
144
|
if !ENV['require'].blank?
|
@@ -124,7 +148,7 @@ OptionParser.new do |opts|
|
|
124
148
|
end
|
125
149
|
end
|
126
150
|
|
127
|
-
opts.on('-e', '--exclude [tests,fixtures,factories]', Array, "Do not annotate fixtures, test files, and/or
|
151
|
+
opts.on('-e', '--exclude [tests,fixtures,factories,serializers]', Array, "Do not annotate fixtures, test files, factories, and/or serializers") do |exclusions|
|
128
152
|
exclusions ||= %w(tests fixtures factories)
|
129
153
|
exclusions.each { |exclusion| ENV["exclude_#{exclusion}"] = "yes" }
|
130
154
|
end
|
data/lib/annotate.rb
CHANGED
@@ -6,9 +6,11 @@ require 'annotate/annotate_routes'
|
|
6
6
|
begin
|
7
7
|
# ActiveSupport 3.x...
|
8
8
|
require 'active_support/hash_with_indifferent_access'
|
9
|
+
require 'active_support/core_ext/object/blank'
|
9
10
|
rescue Exception => e
|
10
11
|
# ActiveSupport 2.x...
|
11
12
|
require 'active_support/core_ext/hash/indifferent_access'
|
13
|
+
require 'active_support/core_ext/blank'
|
12
14
|
end
|
13
15
|
|
14
16
|
module Annotate
|
@@ -18,17 +20,19 @@ module Annotate
|
|
18
20
|
POSITION_OPTIONS=[
|
19
21
|
:position_in_routes, :position_in_class, :position_in_test,
|
20
22
|
:position_in_fixture, :position_in_factory, :position,
|
23
|
+
:position_in_serializer,
|
21
24
|
]
|
22
25
|
FLAG_OPTIONS=[
|
23
26
|
:show_indexes, :simple_indexes, :include_version, :exclude_tests,
|
24
27
|
:exclude_fixtures, :exclude_factories, :ignore_model_sub_dir,
|
25
|
-
:format_bare, :format_rdoc, :format_markdown, :sort, :force, :trace,
|
28
|
+
:format_bare, :format_rdoc, :format_markdown, :sort, :force, :trace,
|
29
|
+
:timestamp, :exclude_serializers, :classified_sort
|
26
30
|
]
|
27
31
|
OTHER_OPTIONS=[
|
28
|
-
:
|
32
|
+
:ignore_columns
|
29
33
|
]
|
30
34
|
PATH_OPTIONS=[
|
31
|
-
:require,
|
35
|
+
:require, :model_dir
|
32
36
|
]
|
33
37
|
|
34
38
|
|
@@ -39,7 +43,7 @@ module Annotate
|
|
39
43
|
return if(@has_set_defaults)
|
40
44
|
@has_set_defaults = true
|
41
45
|
options = HashWithIndifferentAccess.new(options)
|
42
|
-
[POSITION_OPTIONS, FLAG_OPTIONS, PATH_OPTIONS].flatten.each do |key|
|
46
|
+
[POSITION_OPTIONS, FLAG_OPTIONS, PATH_OPTIONS, OTHER_OPTIONS].flatten.each do |key|
|
43
47
|
if(options.has_key?(key))
|
44
48
|
default_value = if(options[key].is_a?(Array))
|
45
49
|
options[key].join(",")
|
@@ -68,7 +72,7 @@ module Annotate
|
|
68
72
|
end
|
69
73
|
|
70
74
|
if(!options[:model_dir])
|
71
|
-
options[:model_dir] = 'app/models'
|
75
|
+
options[:model_dir] = ['app/models']
|
72
76
|
end
|
73
77
|
|
74
78
|
return options
|
@@ -109,8 +113,10 @@ module Annotate
|
|
109
113
|
klass.eager_load!
|
110
114
|
end
|
111
115
|
else
|
112
|
-
|
113
|
-
|
116
|
+
options[:model_dir].each do |dir|
|
117
|
+
FileList["#{dir}/**/*.rb"].each do |fname|
|
118
|
+
require File.expand_path(fname)
|
119
|
+
end
|
114
120
|
end
|
115
121
|
end
|
116
122
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'bigdecimal'
|
2
|
+
|
1
3
|
module AnnotateModels
|
2
4
|
# Annotate Models plugin use this header
|
3
5
|
COMPAT_PREFIX = "== Schema Info"
|
@@ -31,6 +33,12 @@ module AnnotateModels
|
|
31
33
|
FABRICATORS_TEST_DIR = File.join("test", "fabricators")
|
32
34
|
FABRICATORS_SPEC_DIR = File.join("spec", "fabricators")
|
33
35
|
|
36
|
+
# Serializers https://github.com/rails-api/active_model_serializers
|
37
|
+
SERIALIZERS_DIR = File.join("app", "serializers")
|
38
|
+
SERIALIZERS_TEST_DIR = File.join("test", "serializers")
|
39
|
+
SERIALIZERS_SPEC_DIR = File.join("spec", "serializers")
|
40
|
+
|
41
|
+
|
34
42
|
TEST_PATTERNS = [
|
35
43
|
File.join(UNIT_TEST_DIR, "%MODEL_NAME%_test.rb"),
|
36
44
|
File.join(MODEL_TEST_DIR, "%MODEL_NAME%_test.rb"),
|
@@ -55,13 +63,19 @@ module AnnotateModels
|
|
55
63
|
File.join(FABRICATORS_SPEC_DIR, "%MODEL_NAME%_fabricator.rb"),
|
56
64
|
]
|
57
65
|
|
66
|
+
SERIALIZER_PATTERNS = [
|
67
|
+
File.join(SERIALIZERS_DIR, "%MODEL_NAME%_serializer.rb"),
|
68
|
+
File.join(SERIALIZERS_TEST_DIR, "%MODEL_NAME%_serializer_spec.rb"),
|
69
|
+
File.join(SERIALIZERS_SPEC_DIR, "%MODEL_NAME%_serializer_spec.rb")
|
70
|
+
]
|
71
|
+
|
58
72
|
# Don't show limit (#) on these column types
|
59
73
|
# Example: show "integer" instead of "integer(4)"
|
60
74
|
NO_LIMIT_COL_TYPES = ["integer", "boolean"]
|
61
75
|
|
62
76
|
class << self
|
63
77
|
def model_dir
|
64
|
-
@model_dir || "app/models"
|
78
|
+
@model_dir.is_a?(Array) ? @model_dir : [@model_dir || "app/models"]
|
65
79
|
end
|
66
80
|
|
67
81
|
def model_dir=(dir)
|
@@ -82,6 +96,10 @@ module AnnotateModels
|
|
82
96
|
end
|
83
97
|
end
|
84
98
|
|
99
|
+
def schema_default(klass, column)
|
100
|
+
quote(klass.column_defaults[column.name])
|
101
|
+
end
|
102
|
+
|
85
103
|
# Use the column information in an ActiveRecord class
|
86
104
|
# to create a comment block containing a line for
|
87
105
|
# each column. The line contains the column name,
|
@@ -113,10 +131,12 @@ module AnnotateModels
|
|
113
131
|
if options[:ignore_columns]
|
114
132
|
cols.reject! { |col| col.name.match(/#{options[:ignore_columns]}/) }
|
115
133
|
end
|
134
|
+
|
116
135
|
cols = cols.sort_by(&:name) if(options[:sort])
|
136
|
+
cols = classified_sort(cols) if(options[:classified_sort])
|
117
137
|
cols.each do |col|
|
118
138
|
attrs = []
|
119
|
-
attrs << "default(#{
|
139
|
+
attrs << "default(#{schema_default(klass, col)})" unless col.default.nil?
|
120
140
|
attrs << "not null" unless col.null
|
121
141
|
attrs << "primary key" if klass.primary_key && (klass.primary_key.is_a?(Array) ? klass.primary_key.collect{|c|c.to_sym}.include?(col.name.to_sym) : col.name.to_sym == klass.primary_key.to_sym)
|
122
142
|
|
@@ -151,7 +171,7 @@ module AnnotateModels
|
|
151
171
|
if options[:simple_indexes] && klass.table_exists?# Check out if this column is indexed
|
152
172
|
indices = klass.connection.indexes(klass.table_name)
|
153
173
|
if indices = indices.select { |ind| ind.columns.include? col.name }
|
154
|
-
indices.each do |ind|
|
174
|
+
indices.sort_by{|ind| ind.name}.each do |ind|
|
155
175
|
ind = ind.columns.reject! { |i| i == col.name }
|
156
176
|
attrs << (ind.length == 0 ? "indexed" : "indexed => [#{ind.join(", ")}]")
|
157
177
|
end
|
@@ -212,7 +232,7 @@ module AnnotateModels
|
|
212
232
|
# === Options (opts)
|
213
233
|
# :force<Symbol>:: whether to update the file even if it doesn't seem to need it.
|
214
234
|
# :position_in_*<Symbol>:: where to place the annotated section in fixture or model file,
|
215
|
-
# :before or :
|
235
|
+
# :before, :top, :after or :bottom. Default is :before.
|
216
236
|
#
|
217
237
|
def annotate_one_file(file_name, info_block, position, options={})
|
218
238
|
if File.exist?(file_name)
|
@@ -241,15 +261,18 @@ module AnnotateModels
|
|
241
261
|
new_content = old_content.sub(PATTERN, "\n" + info_block)
|
242
262
|
end
|
243
263
|
|
264
|
+
wrapper_open = options[:wrapper_open] ? "# #{options[:wrapper_open]}\n" : ""
|
265
|
+
wrapper_close = options[:wrapper_close] ? "\n# #{options[:wrapper_close]}" : ""
|
266
|
+
wrapped_info_block = "#{wrapper_open}#{info_block}#{wrapper_close}"
|
244
267
|
# if there *was* no old schema info (no substitution happened) or :force was passed,
|
245
268
|
# we simply need to insert it in correct position
|
246
269
|
if new_content == old_content || options[:force]
|
247
270
|
old_content.sub!(encoding, '')
|
248
271
|
old_content.sub!(PATTERN, '')
|
249
272
|
|
250
|
-
new_content = options[position].to_s
|
251
|
-
(encoding_header + (old_content.rstrip + "\n\n" +
|
252
|
-
(encoding_header +
|
273
|
+
new_content = %w(after bottom).include?(options[position].to_s) ?
|
274
|
+
(encoding_header + (old_content.rstrip + "\n\n" + wrapped_info_block)) :
|
275
|
+
(encoding_header + wrapped_info_block + "\n" + old_content)
|
253
276
|
end
|
254
277
|
|
255
278
|
File.open(file_name, "wb") { |f| f.puts new_content }
|
@@ -296,31 +319,23 @@ module AnnotateModels
|
|
296
319
|
did_annotate = false
|
297
320
|
model_name = klass.name.underscore
|
298
321
|
table_name = klass.table_name
|
299
|
-
model_file_name = File.join(
|
322
|
+
model_file_name = File.join(file)
|
300
323
|
|
301
324
|
if annotate_one_file(model_file_name, info, :position_in_class, options_with_position(options, :position_in_class))
|
302
325
|
did_annotate = true
|
303
326
|
end
|
304
327
|
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
detect { |result| result } || did_annotate
|
310
|
-
end
|
311
|
-
|
312
|
-
unless options[:exclude_fixtures]
|
313
|
-
did_annotate = FIXTURE_PATTERNS.
|
314
|
-
map { |file| resolve_filename(file, model_name, table_name) }.
|
315
|
-
map { |file| annotate_one_file(file, info, :position_in_fixture, options_with_position(options, :position_in_fixture)) }.
|
316
|
-
detect { |result| result } || did_annotate
|
317
|
-
end
|
328
|
+
%w(test fixture factory serializer).each do |key|
|
329
|
+
exclusion_key = "exclude_#{key.pluralize}".to_sym
|
330
|
+
patterns_constant = "#{key.upcase}_PATTERNS".to_sym
|
331
|
+
position_key = "position_in_#{key}".to_sym
|
318
332
|
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
333
|
+
unless options[exclusion_key]
|
334
|
+
did_annotate = self.const_get(patterns_constant).
|
335
|
+
map { |file| resolve_filename(file, model_name, table_name) }.
|
336
|
+
map { |file| annotate_one_file(file, info, position_key, options_with_position(options, position_key)) }.
|
337
|
+
detect { |result| result } || did_annotate
|
338
|
+
end
|
324
339
|
end
|
325
340
|
|
326
341
|
return did_annotate
|
@@ -335,35 +350,37 @@ module AnnotateModels
|
|
335
350
|
options.merge(:position=>(options[position_in] || options[:position]))
|
336
351
|
end
|
337
352
|
|
338
|
-
# Return a list of the model files to annotate.
|
339
|
-
# command line arguments, they're assumed to
|
340
|
-
#
|
341
|
-
#
|
342
|
-
# model_dir directory.
|
353
|
+
# Return a list of the model files to annotate.
|
354
|
+
# If we have command line arguments, they're assumed to the path
|
355
|
+
# of model files from root dir. Otherwise we take all the model files
|
356
|
+
# in the model_dir directory.
|
343
357
|
def get_model_files(options)
|
358
|
+
models = []
|
344
359
|
if(!options[:is_rake])
|
345
|
-
models = ARGV.dup
|
346
|
-
models.shift
|
347
|
-
else
|
348
|
-
models = []
|
360
|
+
models = ARGV.dup.reject{|m| m.match(/^(.*)=/)}
|
349
361
|
end
|
350
|
-
|
362
|
+
|
351
363
|
if models.empty?
|
352
364
|
begin
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
365
|
+
model_dir.each do |dir|
|
366
|
+
Dir.chdir(dir) do
|
367
|
+
lst =
|
368
|
+
if options[:ignore_model_sub_dir]
|
369
|
+
Dir["*.rb"].map{ |f| [dir, f] }
|
370
|
+
else
|
371
|
+
Dir["**/*.rb"].reject{ |f| f["concerns/"] }.map{ |f| [dir, f] }
|
372
|
+
end
|
373
|
+
models.concat(lst)
|
358
374
|
end
|
359
375
|
end
|
360
376
|
rescue SystemCallError
|
361
|
-
puts "No models found in directory '#{model_dir}'."
|
377
|
+
puts "No models found in directory '#{model_dir.join("', '")}'."
|
362
378
|
puts "Either specify models on the command line, or use the --model-dir option."
|
363
379
|
puts "Call 'annotate --help' for more info."
|
364
380
|
exit 1
|
365
381
|
end
|
366
382
|
end
|
383
|
+
|
367
384
|
models
|
368
385
|
end
|
369
386
|
|
@@ -372,11 +389,13 @@ module AnnotateModels
|
|
372
389
|
# in subdirectories without namespacing.
|
373
390
|
def get_model_class(file)
|
374
391
|
model_path = file.gsub(/\.rb$/, '')
|
392
|
+
model_dir.each { |dir| model_path = model_path.gsub(/^#{dir}/, '').gsub(/^\//, '') }
|
375
393
|
begin
|
376
394
|
get_loaded_model(model_path) or raise LoadError.new("cannot load a model from #{file}")
|
377
395
|
rescue LoadError
|
378
396
|
# this is for non-rails projects, which don't get Rails auto-require magic
|
379
|
-
|
397
|
+
file_path = File.expand_path(file)
|
398
|
+
if File.file?(file_path) && Kernel.require(file_path)
|
380
399
|
retry
|
381
400
|
elsif model_path.match(/\//)
|
382
401
|
model_path = model_path.split('/')[1..-1].join('/').to_s
|
@@ -421,10 +440,10 @@ module AnnotateModels
|
|
421
440
|
|
422
441
|
annotated = []
|
423
442
|
get_model_files(options).each do |file|
|
424
|
-
annotate_model_file(annotated, file, header, options)
|
443
|
+
annotate_model_file(annotated, File.join(file), header, options)
|
425
444
|
end
|
426
445
|
if annotated.empty?
|
427
|
-
puts "Nothing
|
446
|
+
puts "Nothing to annotate."
|
428
447
|
else
|
429
448
|
puts "Annotated (#{annotated.length}): #{annotated.join(', ')}"
|
430
449
|
end
|
@@ -449,12 +468,13 @@ module AnnotateModels
|
|
449
468
|
deannotated = []
|
450
469
|
deannotated_klass = false
|
451
470
|
get_model_files(options).each do |file|
|
471
|
+
file = File.join(file)
|
452
472
|
begin
|
453
473
|
klass = get_model_class(file)
|
454
474
|
if klass < ActiveRecord::Base && !klass.abstract_class?
|
455
475
|
model_name = klass.name.underscore
|
456
476
|
table_name = klass.table_name
|
457
|
-
model_file_name =
|
477
|
+
model_file_name = file
|
458
478
|
deannotated_klass = true if(remove_annotation_of_file(model_file_name))
|
459
479
|
|
460
480
|
(TEST_PATTERNS + FIXTURE_PATTERNS + FACTORY_PATTERNS).
|
@@ -468,7 +488,7 @@ module AnnotateModels
|
|
468
488
|
end
|
469
489
|
deannotated << klass if(deannotated_klass)
|
470
490
|
rescue Exception => e
|
471
|
-
puts "Unable to deannotate #{file}: #{e.message}"
|
491
|
+
puts "Unable to deannotate #{File.join(file)}: #{e.message}"
|
472
492
|
puts "\t" + e.backtrace.join("\n\t") if options[:trace]
|
473
493
|
end
|
474
494
|
end
|
@@ -480,5 +500,27 @@ module AnnotateModels
|
|
480
500
|
gsub('%MODEL_NAME%', model_name).
|
481
501
|
gsub('%TABLE_NAME%', table_name || model_name.pluralize)
|
482
502
|
end
|
503
|
+
|
504
|
+
def classified_sort(cols)
|
505
|
+
rest_cols = []
|
506
|
+
timestamps = []
|
507
|
+
associations = []
|
508
|
+
id = nil
|
509
|
+
|
510
|
+
cols = cols.each do |c|
|
511
|
+
if c.name.eql?("id")
|
512
|
+
id = c
|
513
|
+
elsif (c.name.eql?("created_at") || c.name.eql?("updated_at"))
|
514
|
+
timestamps << c
|
515
|
+
elsif c.name[-3,3].eql?("_id")
|
516
|
+
associations << c
|
517
|
+
else
|
518
|
+
rest_cols << c
|
519
|
+
end
|
520
|
+
end
|
521
|
+
[rest_cols, timestamps, associations].each {|a| a.sort_by!(&:name) }
|
522
|
+
|
523
|
+
return ([id] << rest_cols << timestamps << associations).flatten
|
524
|
+
end
|
483
525
|
end
|
484
526
|
end
|
@@ -23,7 +23,7 @@ module AnnotateRoutes
|
|
23
23
|
def self.do_annotations(options={})
|
24
24
|
return unless(routes_exists?)
|
25
25
|
|
26
|
-
position_after = options[:position_in_routes]
|
26
|
+
position_after = ! %w(before top).include?(options[:position_in_routes])
|
27
27
|
|
28
28
|
routes_map = `rake routes`.split(/\n/, -1)
|
29
29
|
|
data/lib/annotate/version.rb
CHANGED
@@ -18,7 +18,7 @@ task :annotate_models => :environment do
|
|
18
18
|
options[:position_in_test] = Annotate.fallback(ENV['position_in_test'], ENV['position'])
|
19
19
|
options[:show_indexes] = Annotate.true?(ENV['show_indexes'])
|
20
20
|
options[:simple_indexes] = Annotate.true?(ENV['simple_indexes'])
|
21
|
-
options[:model_dir] = ENV['model_dir']
|
21
|
+
options[:model_dir] = ENV['model_dir'] ? ENV['model_dir'].split(',') : []
|
22
22
|
options[:include_version] = Annotate.true?(ENV['include_version'])
|
23
23
|
options[:require] = ENV['require'] ? ENV['require'].split(',') : []
|
24
24
|
options[:exclude_tests] = Annotate.true?(ENV['exclude_tests'])
|
@@ -30,7 +30,10 @@ task :annotate_models => :environment do
|
|
30
30
|
options[:format_markdown] = Annotate.true?(ENV['format_markdown'])
|
31
31
|
options[:sort] = Annotate.true?(ENV['sort'])
|
32
32
|
options[:force] = Annotate.true?(ENV['force'])
|
33
|
+
options[:classified_sort] = Annotate.true?(ENV['classified_sort'])
|
33
34
|
options[:trace] = Annotate.true?(ENV['trace'])
|
35
|
+
options[:wrapper_open] = Annotate.fallback(ENV['wrapper_open'], ENV['wrapper'])
|
36
|
+
options[:wrapper_close] = Annotate.fallback(ENV['wrapper_close'], ENV['wrapper'])
|
34
37
|
AnnotateModels.do_annotations(options)
|
35
38
|
end
|
36
39
|
|
metadata
CHANGED
@@ -1,49 +1,59 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: annotate
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.6.
|
4
|
+
version: 2.6.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
- Cuong Tran
|
8
7
|
- Alex Chaffee
|
8
|
+
- Cuong Tran
|
9
9
|
- Marcos Piccinini
|
10
10
|
- Turadg Aleahmad
|
11
11
|
- Jon Frisby
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date:
|
15
|
+
date: 2015-03-08 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: rake
|
19
19
|
requirement: !ruby/object:Gem::Requirement
|
20
20
|
requirements:
|
21
|
+
- - ~>
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: !binary |-
|
24
|
+
MTAuNC4y
|
21
25
|
- - ! '>='
|
22
26
|
- !ruby/object:Gem::Version
|
23
27
|
version: !binary |-
|
24
|
-
|
28
|
+
MTAuNC4y
|
25
29
|
type: :runtime
|
26
30
|
prerelease: false
|
27
31
|
version_requirements: !ruby/object:Gem::Requirement
|
28
32
|
requirements:
|
33
|
+
- - ~>
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: !binary |-
|
36
|
+
MTAuNC4y
|
29
37
|
- - ! '>='
|
30
38
|
- !ruby/object:Gem::Version
|
31
39
|
version: !binary |-
|
32
|
-
|
40
|
+
MTAuNC4y
|
33
41
|
- !ruby/object:Gem::Dependency
|
34
42
|
name: activerecord
|
35
43
|
requirement: !ruby/object:Gem::Requirement
|
36
44
|
requirements:
|
37
45
|
- - ! '>='
|
38
46
|
- !ruby/object:Gem::Version
|
39
|
-
version:
|
47
|
+
version: !binary |-
|
48
|
+
Mi4zLjA=
|
40
49
|
type: :runtime
|
41
50
|
prerelease: false
|
42
51
|
version_requirements: !ruby/object:Gem::Requirement
|
43
52
|
requirements:
|
44
53
|
- - ! '>='
|
45
54
|
- !ruby/object:Gem::Version
|
46
|
-
version:
|
55
|
+
version: !binary |-
|
56
|
+
Mi4zLjA=
|
47
57
|
description: Annotates Rails/ActiveRecord Models, routes, fixtures, and others based
|
48
58
|
on the database schema.
|
49
59
|
email:
|
@@ -99,7 +109,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
99
109
|
version: '0'
|
100
110
|
requirements: []
|
101
111
|
rubyforge_project: annotate
|
102
|
-
rubygems_version: 2.
|
112
|
+
rubygems_version: 2.4.1
|
103
113
|
signing_key:
|
104
114
|
specification_version: 4
|
105
115
|
summary: Annotates Rails Models, routes, fixtures, and others based on the database
|