annotate 2.6.5 → 2.6.6
Sign up to get free protection for your applications and to get access to all the features.
- 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
|