annotator 0.0.4 → 0.0.5
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.
- data/MIT-LICENSE +1 -1
- data/README.rdoc +3 -4
- data/lib/annotator.rb +6 -180
- data/lib/annotator/attributes.rb +92 -0
- data/lib/annotator/initial_description.rb +23 -0
- data/lib/annotator/initial_description/base.rb +21 -0
- data/lib/annotator/initial_description/belongs_to.rb +29 -0
- data/lib/annotator/initial_description/devise.rb +39 -0
- data/lib/annotator/initial_description/paperclip.rb +26 -0
- data/lib/annotator/initial_description/rails.rb +23 -0
- data/lib/annotator/model.rb +57 -0
- data/lib/annotator/version.rb +1 -1
- data/test/annotator_test.rb +18 -8
- data/test/assets/boo_annotated.rb +4 -1
- data/test/assets/foo_require_first.rb +11 -0
- data/test/assets/moo_hoo_annotated.rb +13 -0
- data/test/dummy/app/models/boo.rb +1 -0
- data/test/dummy/app/models/moo/hoo.rb +6 -0
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/db/migrate/20120527025142_create_boos.rb +2 -0
- data/test/dummy/db/schema.rb +18 -1
- data/test/dummy/log/development.log +97 -0
- data/test/support/test_app.rb +19 -0
- data/test/test_helper.rb +5 -9
- metadata +19 -3
data/MIT-LICENSE
CHANGED
data/README.rdoc
CHANGED
@@ -62,15 +62,14 @@ Of course similar thing happens when you remove column or change it's type.
|
|
62
62
|
* for some fields like title above you can just skip description including dash sometimes name is just obvious enough
|
63
63
|
* multiline comments are ok
|
64
64
|
* generating initial descriptions it understands things like
|
65
|
-
|
66
|
-
|
67
|
-
|
65
|
+
* belongs_to association columns
|
66
|
+
* devise columns
|
67
|
+
* paperclip colums
|
68
68
|
|
69
69
|
Contributions are very much welcome.
|
70
70
|
|
71
71
|
== Todos
|
72
72
|
|
73
|
-
* it could be written a bit cleaner
|
74
73
|
* since name does not have "model" in it, we could possibly use "rake routes" to annotate controller actions, not sure if it's worth it
|
75
74
|
|
76
75
|
== Authors
|
data/lib/annotator.rb
CHANGED
@@ -1,189 +1,15 @@
|
|
1
1
|
require 'annotator/railtie'
|
2
|
+
require 'annotator/model'
|
3
|
+
require 'annotator/attributes'
|
4
|
+
require 'annotator/initial_description'
|
2
5
|
|
3
6
|
module Annotator
|
4
|
-
def self.run
|
5
|
-
models = Dir.glob("#{Rails.root}/app/models/*.rb").map do |filename|
|
6
|
-
klass = filename.split('/').last.split(/\.rb$/).first.camelize.constantize
|
7
|
-
[filename, klass]
|
8
|
-
end.sort_by {|x| x.last.to_s}
|
9
|
-
|
10
|
-
|
11
|
-
models.each do |filename, model|
|
12
|
-
next unless model.ancestors.include? ActiveRecord::Base
|
13
|
-
begin
|
14
|
-
file = File.read(filename)
|
15
|
-
lines = file.split("\n")
|
16
|
-
out = ''
|
17
|
-
ia = false # inside attributes block
|
18
|
-
after_block = false # we are already after comments block
|
19
|
-
changed = false
|
20
|
-
skip_file = false
|
21
|
-
attrs_arr = []
|
22
|
-
lines.each do |line|
|
23
|
-
break if skip_file
|
24
|
-
out << "#{line}\n" && next if after_block
|
25
|
-
|
26
|
-
if ia && !line.match(/^# \*/) && !line.match(/^# \S/)
|
27
|
-
out << stringify_attrs_arr(update_attrs_arr(attrs_arr, model))
|
28
|
-
ia = false
|
29
|
-
changed = true
|
30
|
-
end
|
31
|
-
|
32
|
-
# check if we are still in the comments part of the file
|
33
|
-
unless line.strip.empty? || line.match(/^\s*#/)
|
34
|
-
after_block = true
|
35
|
-
unless changed
|
36
|
-
out << "# Attributes:\n"
|
37
|
-
out << stringify_attrs_arr(update_attrs_arr(attrs_arr, model))
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
if ia
|
42
|
-
if line.match(/^# \*/)
|
43
|
-
m = line.match(/^# \* (\w+) \[(.*?)\]( \- )?(.*)/)
|
44
|
-
if m
|
45
|
-
attrs_arr << [m[1], m[2], m[4]].map(&:strip)
|
46
|
-
else
|
47
|
-
puts "!! Unrecognized line format on attributes list in #{model}:"
|
48
|
-
puts line
|
49
|
-
end
|
50
|
-
else
|
51
|
-
attrs_arr[-1][2] << " #{line[4..-1]}"
|
52
|
-
end
|
53
|
-
else
|
54
|
-
out << "#{line}\n"
|
55
|
-
end
|
56
|
-
|
57
|
-
ia = true if line.match(/^# Attributes:/i)
|
58
|
-
skip_file = true if line.match(/^# Attributes\(nodoc\):/i)
|
59
|
-
end
|
60
|
-
|
61
|
-
File.open(filename,'w') { |f| f.write(out) } if out.strip != file.strip && !skip_file
|
62
|
-
|
63
|
-
rescue Exception => e
|
64
|
-
puts "FAILURE while trying to update model #{model}:\n #{e}"
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
|
69
|
-
end
|
70
|
-
|
71
|
-
protected
|
72
|
-
|
73
|
-
def self.update_attrs_arr(arr, model)
|
74
|
-
arr = arr.dup
|
75
|
-
model.columns.each do |column|
|
76
|
-
attrs_str = column_attrs(column)
|
77
|
-
if row = arr.find {|x| x[0] == column.name}
|
78
|
-
if row[1] != attrs_str
|
79
|
-
puts " M #{model}##{column.name} [#{row[1]} -> #{attrs_str}]"
|
80
|
-
row[1] = attrs_str
|
81
|
-
end
|
82
|
-
else
|
83
|
-
puts " A #{model}##{column.name} [#{attrs_str}]"
|
84
|
-
desc = initial_description model, column
|
85
|
-
arr << [column.name, attrs_str, desc]
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
# find columns that no more exist in db
|
90
|
-
orphans = arr.map(&:first) - model.columns.map(&:name)
|
91
|
-
unless orphans.empty?
|
92
|
-
orphans.each do |orphan|
|
93
|
-
puts " D #{model}#{orphan}"
|
94
|
-
arr = arr.select {|x| x[0] != orphan}
|
95
|
-
end
|
96
|
-
end
|
97
|
-
arr
|
98
|
-
end
|
99
7
|
|
100
|
-
def self.
|
101
|
-
|
102
|
-
|
103
|
-
when 'created_at' then return 'creation time'
|
104
|
-
when 'updated_at' then return 'last update time'
|
105
|
-
end
|
106
|
-
|
107
|
-
# TODO stop writing like it's functional lang and make class for Description ;)
|
108
|
-
|
109
|
-
# Belongs to association
|
110
|
-
model.reflect_on_all_associations.each do |reflect|
|
111
|
-
if reflect.foreign_key == column.name && reflect.macro == :belongs_to
|
112
|
-
return "belongs to #{reflect.klass}"
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
# Devise column names
|
117
|
-
if model.respond_to? :devise_modules
|
118
|
-
devise_columns = {
|
119
|
-
:reset_password_token => "Devise Recoverable module",
|
120
|
-
:reset_password_sent_at => "Devise Recoverable module",
|
121
|
-
:remember_created_at => "Devise Rememberable module",
|
122
|
-
:sign_in_count => "Devise Trackable module",
|
123
|
-
:current_sign_in_at => "Devise Trackable module",
|
124
|
-
:last_sign_in_at => "Devise Trackable module",
|
125
|
-
:current_sign_in_ip => "Devise Trackable module",
|
126
|
-
:last_sign_in_ip => "Devise Trackable module",
|
127
|
-
:password_salt => "Devise Encriptable module",
|
128
|
-
:confirmation_token => "Devise Confirmable module",
|
129
|
-
:confirmed_at => "Devise Confirmable module",
|
130
|
-
:confiramtion_sent_at => "Devise Confirmable module",
|
131
|
-
:unconfirmed_email => "Devise Confirmable module",
|
132
|
-
:failed_attempts => "Devise Lockable module",
|
133
|
-
:unlock_token => "Devise Locakble module",
|
134
|
-
:locked_at => "Devise Lockable module",
|
135
|
-
:authentication_token => "Devise Token authenticable module"
|
136
|
-
}
|
137
|
-
guess = devise_columns[column.name.to_sym]
|
138
|
-
return guess if guess
|
139
|
-
end
|
140
|
-
|
141
|
-
# Paperclip column names
|
142
|
-
if model.respond_to? :attachments_definitions
|
143
|
-
model.attachments_definitions.keys.each do |att|
|
144
|
-
cols = ["#{att}_file_name", "#{att}_content_type", "#{att}_file_size", "#{att}_updated_at"]
|
145
|
-
return "Paperclip for #{att}" if cols.include? column.name
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
|
-
# let's not add "document me" note for these obvious ones:
|
150
|
-
return '' if %w{email name title body}.include? column.name
|
151
|
-
|
152
|
-
return 'TODO: document me'
|
153
|
-
end
|
154
|
-
|
155
|
-
def self.column_attrs(c)
|
156
|
-
ret = c.type.to_s
|
157
|
-
ret << ", primary" if c.primary
|
158
|
-
ret << ", default=#{c.default}" if c.default
|
159
|
-
ret << ", not null" unless c.null
|
160
|
-
ret << ", limit=#{c.limit}" if c.limit && (c.limit != 255 && c.type != :string)
|
161
|
-
ret
|
162
|
-
end
|
163
|
-
|
164
|
-
def self.stringify_attrs_arr(arr)
|
165
|
-
ret = ''
|
166
|
-
arr.sort_by{|x| x[0] == 'id' ? '_' : x[0]}.each do |name, attrs, desc|
|
167
|
-
# split into lines that don't exceed 80 chars
|
168
|
-
desc = " - #{desc}" unless desc.empty?
|
169
|
-
line = "# * #{name} [#{attrs}]#{desc}"
|
170
|
-
lt = wrap_text(line, opts[:max_chars_per_line]-3).split("\n")
|
171
|
-
line = ([lt[0]] + lt[1..-1].map{|x| "# #{x}"}).join("\n")
|
172
|
-
ret << "#{line}\n"
|
8
|
+
def self.run
|
9
|
+
Dir.glob("#{Rails.root}/app/models/**/*.rb").sort.map do |filename|
|
10
|
+
Model.new(filename).update!
|
173
11
|
end
|
174
|
-
ret
|
175
12
|
end
|
176
13
|
|
177
|
-
def self.wrap_text(txt, col)
|
178
|
-
txt.gsub(/(.{1,#{col}})( +|$)\n?|(.{#{col}})/,"\\1\\3\n")
|
179
|
-
end
|
180
|
-
|
181
|
-
def self.opts
|
182
|
-
{
|
183
|
-
:max_chars_per_line => 120
|
184
|
-
}
|
185
|
-
end
|
186
|
-
|
187
|
-
|
188
14
|
end
|
189
15
|
|
@@ -0,0 +1,92 @@
|
|
1
|
+
module Annotator
|
2
|
+
|
3
|
+
# Attributes within given model file
|
4
|
+
class Attributes
|
5
|
+
R_ATTRIBUTE = /^# \* (\w+) \[(.*?)\]( \- )?(.*)$/
|
6
|
+
R_ATTRIBUTE_NEXT_LINE = /^# (.*?)$/
|
7
|
+
R_ATTRIBUTE_LINE = /(#{R_ATTRIBUTE})|(#{R_ATTRIBUTE_NEXT_LINE})/
|
8
|
+
HEADER = "# Attributes:"
|
9
|
+
MAX_CHARS_PER_LINE = 120
|
10
|
+
|
11
|
+
def initialize(model, lines)
|
12
|
+
@model = model
|
13
|
+
@lines = lines
|
14
|
+
@attrs = []
|
15
|
+
@changes = []
|
16
|
+
parse
|
17
|
+
end
|
18
|
+
|
19
|
+
# Convert attributes array back to attributes lines representation to be put into file
|
20
|
+
def lines
|
21
|
+
ret = [Attributes::HEADER]
|
22
|
+
# Sort by name, but id goes first
|
23
|
+
@attrs.sort_by{|x| x[:name] == 'id' ? '_' : x[:name]}.each do |row|
|
24
|
+
line = "# * #{row[:name]} [#{row[:type]}]#{row[:desc].to_s.empty? ? "" : " - #{row[:desc]}"}"
|
25
|
+
# split into lines that don't exceed 80 chars
|
26
|
+
lt = wrap_text(line, MAX_CHARS_PER_LINE-3).split("\n")
|
27
|
+
line = ([lt[0]] + lt[1..-1].map{|x| "# #{x}"}).join("\n")
|
28
|
+
ret << line
|
29
|
+
end
|
30
|
+
ret
|
31
|
+
end
|
32
|
+
|
33
|
+
# Update attribudes array to the current database state
|
34
|
+
def update!
|
35
|
+
@model.columns.each do |column|
|
36
|
+
if row = @attrs.find {|x| x[:name] == column.name}
|
37
|
+
if row[:type] != type_str(column)
|
38
|
+
puts " M #{@model}##{column.name} [#{row[:type]} -> #{type_str(column)}]"
|
39
|
+
row[:type] = type_str(column)
|
40
|
+
end
|
41
|
+
else
|
42
|
+
puts " A #{@model}##{column.name} [#{type_str(column)}]"
|
43
|
+
@attrs << {
|
44
|
+
:name => column.name,
|
45
|
+
:type => type_str(column),
|
46
|
+
:desc => InitialDescription.for(@model, column.name)
|
47
|
+
}
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# find columns that no more exist in db
|
52
|
+
orphans = @attrs.map{|x| x[:name]} - @model.columns.map(&:name)
|
53
|
+
unless orphans.empty?
|
54
|
+
orphans.each do |orphan|
|
55
|
+
puts " D #{@model}#{orphan}"
|
56
|
+
@attrs = @attrs.select {|x| x[0] != orphan}
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
@attrs
|
61
|
+
end
|
62
|
+
|
63
|
+
protected
|
64
|
+
|
65
|
+
# Convert attributes lines into meaniningful array
|
66
|
+
def parse
|
67
|
+
@lines.each do |line|
|
68
|
+
if m = line.match(R_ATTRIBUTE)
|
69
|
+
@attrs << {:name => m[1].strip, :type => m[2].strip, :desc => m[4].strip}
|
70
|
+
elsif m = line.match(R_ATTRIBUTE_NEXT_LINE)
|
71
|
+
@attrs[-1][:desc] += " #{m[1].strip}"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# Human readable description of given column type
|
77
|
+
def type_str(c)
|
78
|
+
ret = c.type.to_s
|
79
|
+
ret << ", primary" if c.primary
|
80
|
+
ret << ", default=#{c.default}" if c.default
|
81
|
+
ret << ", not null" unless c.null
|
82
|
+
ret << ", limit=#{c.limit}" if c.limit && (c.limit != 255 && c.type != :string)
|
83
|
+
ret
|
84
|
+
end
|
85
|
+
|
86
|
+
# Wraps text nicely, not breaking in the middle of the word
|
87
|
+
def wrap_text(txt, col)
|
88
|
+
txt.gsub(/(.{1,#{col}})( +|$)\n?|(.{#{col}})/,"\\1\\3\n")
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'annotator/initial_description/base'
|
2
|
+
Dir[File.dirname(__FILE__) + '/initial_description/*.rb'].each {|file| require file }
|
3
|
+
|
4
|
+
module Annotator
|
5
|
+
module InitialDescription
|
6
|
+
|
7
|
+
NO_DESCRIPTION_COLUMNS = %w{email name title body}
|
8
|
+
|
9
|
+
# Get initial description for given model & column
|
10
|
+
def self.for(model, column)
|
11
|
+
# Check if any module provides such description
|
12
|
+
Base.providers.each do |klass|
|
13
|
+
provider = klass.new model, column
|
14
|
+
return provider.text if provider.check
|
15
|
+
end
|
16
|
+
# Some columns are just too obvious
|
17
|
+
return "" if NO_DESCRIPTION_COLUMNS.include? column
|
18
|
+
# Let user do the work
|
19
|
+
return "TODO: document me"
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Annotator
|
2
|
+
module InitialDescription
|
3
|
+
|
4
|
+
# Base class from which all other description providers inherit
|
5
|
+
class Base
|
6
|
+
def initialize(model, column)
|
7
|
+
@model = model
|
8
|
+
@column = column
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.inherited(klass)
|
12
|
+
@providers ||= []
|
13
|
+
@providers << klass
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.providers
|
17
|
+
@providers
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Annotator
|
2
|
+
module InitialDescription
|
3
|
+
|
4
|
+
# Initial descriptions for columns associated with belongs_to
|
5
|
+
class BelongsTo < Base
|
6
|
+
|
7
|
+
def check
|
8
|
+
# check if there is belongs to association where this column is a foreign key
|
9
|
+
@model.reflect_on_all_associations.each do |reflection|
|
10
|
+
if reflection.foreign_key == @column && reflection.macro == :belongs_to
|
11
|
+
@reflection = reflection
|
12
|
+
return true
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# Polymorphic association type column
|
17
|
+
if @column.ends_with? '_type'
|
18
|
+
return true if @reflection = @model.reflect_on_association(@column.match(/(.*?)_type$/)[1].to_sym)
|
19
|
+
end
|
20
|
+
|
21
|
+
return false
|
22
|
+
end
|
23
|
+
|
24
|
+
def text
|
25
|
+
"belongs to :#{@reflection.name}#{@reflection.options[:polymorphic] ? ' (polymorphic)' : ''}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Annotator
|
2
|
+
module InitialDescription
|
3
|
+
|
4
|
+
# Initila descriptions for devise specific columns
|
5
|
+
class Devise < Base
|
6
|
+
|
7
|
+
def check
|
8
|
+
@model.respond_to?(:devise_modules) && columns.keys.include?(@column.to_sym)
|
9
|
+
end
|
10
|
+
|
11
|
+
def columns
|
12
|
+
{
|
13
|
+
:reset_password_token => "Devise Recoverable module",
|
14
|
+
:reset_password_sent_at => "Devise Recoverable module",
|
15
|
+
:remember_created_at => "Devise Rememberable module",
|
16
|
+
:sign_in_count => "Devise Trackable module",
|
17
|
+
:current_sign_in_at => "Devise Trackable module",
|
18
|
+
:last_sign_in_at => "Devise Trackable module",
|
19
|
+
:current_sign_in_ip => "Devise Trackable module",
|
20
|
+
:last_sign_in_ip => "Devise Trackable module",
|
21
|
+
:password_salt => "Devise Encriptable module",
|
22
|
+
:confirmation_token => "Devise Confirmable module",
|
23
|
+
:confirmed_at => "Devise Confirmable module",
|
24
|
+
:confiramtion_sent_at => "Devise Confirmable module",
|
25
|
+
:unconfirmed_email => "Devise Confirmable module",
|
26
|
+
:failed_attempts => "Devise Lockable module",
|
27
|
+
:unlock_token => "Devise Locakble module",
|
28
|
+
:locked_at => "Devise Lockable module",
|
29
|
+
:authentication_token => "Devise Token authenticable module"
|
30
|
+
}
|
31
|
+
end
|
32
|
+
|
33
|
+
def text
|
34
|
+
columns[@column.to_sym]
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Annotator
|
2
|
+
module InitialDescription
|
3
|
+
|
4
|
+
# Initial descriptinos for paperclip attachments columns
|
5
|
+
class Paperclip < Base
|
6
|
+
|
7
|
+
def check
|
8
|
+
if @model.respond_to? :attachments_definitions
|
9
|
+
@model.attachments_definitions.keys.each do |att|
|
10
|
+
cols = ["#{att}_file_name", "#{att}_content_type", "#{att}_file_size", "#{att}_updated_at"]
|
11
|
+
if cols.include? @column
|
12
|
+
@attachment = att
|
13
|
+
return true
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
return false
|
18
|
+
end
|
19
|
+
|
20
|
+
def text
|
21
|
+
"Paperclip for #{@attachment}"
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Annotator
|
2
|
+
module InitialDescription
|
3
|
+
|
4
|
+
# Initial descriptions for rails specific columns
|
5
|
+
class Rails < Base
|
6
|
+
def check
|
7
|
+
columns.keys.include? @column.to_sym
|
8
|
+
end
|
9
|
+
|
10
|
+
def columns
|
11
|
+
{
|
12
|
+
:id => "primary key", # TODO check if it actually is a primary key, find primary keys with other names
|
13
|
+
:created_at => "creation time",
|
14
|
+
:updated_at => "last update time"
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
def text
|
19
|
+
columns[@column.to_sym]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Annotator
|
2
|
+
|
3
|
+
# Represents a single model file and associated class
|
4
|
+
class Model
|
5
|
+
|
6
|
+
def initialize(filename)
|
7
|
+
@filename = filename
|
8
|
+
@blocks = Hash.new {[]}
|
9
|
+
end
|
10
|
+
|
11
|
+
# Model class
|
12
|
+
def klass
|
13
|
+
@filename.split('app/models/').last.split(/\.rb$/).first.camelize.constantize rescue nil
|
14
|
+
end
|
15
|
+
|
16
|
+
# Split file into 3 blocks: before attributes, attributes block, and after
|
17
|
+
# If there's no attributes block, content will be in :after part (for easier insertion)
|
18
|
+
def parse
|
19
|
+
@file = File.read(@filename).strip
|
20
|
+
current_block = :before
|
21
|
+
return @nodoc = true if @file.match(/^# Attributes\(nodoc\):$/i)
|
22
|
+
@file.split("\n").each do |line|
|
23
|
+
if line.match(/^#{Regexp.escape Attributes::HEADER} *$/)
|
24
|
+
current_block = :attributes
|
25
|
+
next
|
26
|
+
end
|
27
|
+
current_block = :after if current_block == :attributes && !line.match(Attributes::R_ATTRIBUTE_LINE)
|
28
|
+
@blocks[current_block] += [line]
|
29
|
+
end
|
30
|
+
|
31
|
+
@blocks[:after], @blocks[:before] = @blocks[:before], [] if @blocks[:after].empty?
|
32
|
+
end
|
33
|
+
|
34
|
+
# If this file does not have associated AR class it should be skipped
|
35
|
+
def skipped?
|
36
|
+
!klass || !klass.ancestors.include?(ActiveRecord::Base) || @nodoc
|
37
|
+
end
|
38
|
+
|
39
|
+
# Save changes to file if there were any
|
40
|
+
def update_file
|
41
|
+
output = (@blocks[:before] + @blocks[:attributes] + @blocks[:after]).join("\n").strip + "\n"
|
42
|
+
File.open(@filename,'w') { |f| f.write(output) } if output != @file
|
43
|
+
end
|
44
|
+
|
45
|
+
# Update file with new database information
|
46
|
+
def update!
|
47
|
+
parse
|
48
|
+
return true if skipped?
|
49
|
+
attributes = Attributes.new klass, @blocks[:attributes]
|
50
|
+
attributes.update!
|
51
|
+
@blocks[:attributes] = attributes.lines
|
52
|
+
update_file
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
|
data/lib/annotator/version.rb
CHANGED
data/test/annotator_test.rb
CHANGED
@@ -3,7 +3,7 @@ require 'tempfile'
|
|
3
3
|
|
4
4
|
class AnnotatorTest < ActiveSupport::TestCase
|
5
5
|
def setup
|
6
|
-
@output = execute("
|
6
|
+
@output = execute("rake annotate")
|
7
7
|
end
|
8
8
|
|
9
9
|
test "annotating foo" do
|
@@ -12,13 +12,13 @@ class AnnotatorTest < ActiveSupport::TestCase
|
|
12
12
|
|
13
13
|
test "leaving existing comments" do
|
14
14
|
FileUtils.cp asset_file('foo_annotated_with_comments.rb'), app_file('foo.rb')
|
15
|
-
|
15
|
+
execute "rake annotate"
|
16
16
|
assert_equal File.read(asset_file 'foo_annotated_with_comments.rb' ), File.read(app_file 'foo.rb' )
|
17
17
|
end
|
18
18
|
|
19
19
|
test "updating column type" do
|
20
20
|
FileUtils.cp asset_file('foo_annotated_bad_column.rb'), app_file('foo.rb')
|
21
|
-
output = execute
|
21
|
+
output = execute "rake annotate"
|
22
22
|
assert_equal File.read(asset_file 'foo_annotated_column_fixed.rb' ), File.read(app_file 'foo.rb' )
|
23
23
|
assert output.include?('M Foo#title [octopus -> string]')
|
24
24
|
assert output.include?('M Foo#created_at [foobar -> datetime, not null]')
|
@@ -26,34 +26,44 @@ class AnnotatorTest < ActiveSupport::TestCase
|
|
26
26
|
|
27
27
|
test "skipping when nodoc is preesnt" do
|
28
28
|
FileUtils.cp asset_file('foo_annotated_bad_column_nodoc.rb'), app_file('foo.rb')
|
29
|
-
execute
|
29
|
+
execute "rake annotate"
|
30
30
|
assert_equal File.read(asset_file 'foo_annotated_bad_column_nodoc.rb' ), File.read(app_file 'foo.rb' )
|
31
31
|
end
|
32
32
|
|
33
33
|
test "annotating devise columns" do
|
34
34
|
assert_equal File.read(asset_file 'user_annotated.rb' ), File.read(app_file 'user.rb' )
|
35
|
-
end
|
35
|
+
end
|
36
36
|
|
37
37
|
test "annotating paperclip columns" do
|
38
38
|
assert_equal File.read(asset_file 'paper_annotated.rb' ), File.read(app_file 'paper.rb' )
|
39
39
|
end
|
40
40
|
|
41
|
-
test "annotating belongs_to associations" do
|
41
|
+
test "annotating belongs_to and polymorphic associations" do
|
42
42
|
assert_equal File.read(asset_file 'boo_annotated.rb' ), File.read(app_file 'boo.rb' )
|
43
43
|
end
|
44
44
|
|
45
|
+
test "handling some code before annotitions block" do
|
46
|
+
FileUtils.cp asset_file('foo_require_first.rb'), app_file('foo.rb')
|
47
|
+
execute "rake annotate"
|
48
|
+
assert_equal File.read(asset_file 'foo_require_first.rb' ), File.read(app_file 'foo.rb' )
|
49
|
+
end
|
50
|
+
|
51
|
+
test "annotating namespaced models" do
|
52
|
+
assert_equal File.read(asset_file 'moo_hoo_annotated.rb' ), File.read(app_file 'moo/hoo.rb' )
|
53
|
+
end
|
54
|
+
|
45
55
|
def asset_file(name)
|
46
56
|
File.join(File.expand_path("../assets/", __FILE__), name)
|
47
57
|
end
|
48
58
|
|
49
59
|
def app_file(name)
|
50
|
-
File.join(
|
60
|
+
File.join(TestApp.path,'app','models',name)
|
51
61
|
end
|
52
62
|
|
53
63
|
# Check exit code while grabbing output
|
54
64
|
def execute(command)
|
55
65
|
tmp = Tempfile.new "output"
|
56
|
-
assert system("#{command} > #{tmp.path}")
|
66
|
+
assert system("cd #{TestApp.path} && #{command} > #{tmp.path}")
|
57
67
|
output = tmp.read
|
58
68
|
tmp.unlink
|
59
69
|
output
|
@@ -1,8 +1,11 @@
|
|
1
1
|
# Attributes:
|
2
2
|
# * id [integer, primary, not null] - primary key
|
3
3
|
# * created_at [datetime, not null] - creation time
|
4
|
-
# * foo_id [integer] - belongs to
|
4
|
+
# * foo_id [integer] - belongs to :foo
|
5
|
+
# * poly_id [integer] - belongs to :poly (polymorphic)
|
6
|
+
# * poly_type [string] - belongs to :poly (polymorphic)
|
5
7
|
# * updated_at [datetime, not null] - last update time
|
6
8
|
class Boo < ActiveRecord::Base
|
7
9
|
belongs_to :foo
|
10
|
+
belongs_to :poly, :polymorphic => true
|
8
11
|
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'pp'
|
2
|
+
|
3
|
+
# Attributes:
|
4
|
+
# * id [integer, primary, not null] - primary key
|
5
|
+
# * body [text]
|
6
|
+
# * created_at [datetime, not null] - creation time
|
7
|
+
# * random_number [integer] - TODO: document me
|
8
|
+
# * title [string]
|
9
|
+
# * updated_at [datetime, not null] - last update time
|
10
|
+
class Foo < ActiveRecord::Base
|
11
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# Attributes:
|
2
|
+
# * id [integer, primary, not null] - primary key
|
3
|
+
# * body [text]
|
4
|
+
# * created_at [datetime, not null] - creation time
|
5
|
+
# * random_number [integer] - TODO: document me
|
6
|
+
# * title [string]
|
7
|
+
# * updated_at [datetime, not null] - last update time
|
8
|
+
# Some existing stupid comment
|
9
|
+
module Moo
|
10
|
+
class Hoo < ActiveRecord::Base
|
11
|
+
self.table_name = 'foos'
|
12
|
+
end
|
13
|
+
end
|
Binary file
|
data/test/dummy/db/schema.rb
CHANGED
@@ -11,7 +11,15 @@
|
|
11
11
|
#
|
12
12
|
# It's strongly recommended to check this file into your version control system.
|
13
13
|
|
14
|
-
ActiveRecord::Schema.define(:version =>
|
14
|
+
ActiveRecord::Schema.define(:version => 20120527025142) do
|
15
|
+
|
16
|
+
create_table "boos", :force => true do |t|
|
17
|
+
t.integer "foo_id"
|
18
|
+
t.integer "poly_id"
|
19
|
+
t.string "poly_type"
|
20
|
+
t.datetime "created_at", :null => false
|
21
|
+
t.datetime "updated_at", :null => false
|
22
|
+
end
|
15
23
|
|
16
24
|
create_table "foos", :force => true do |t|
|
17
25
|
t.text "body"
|
@@ -21,6 +29,15 @@ ActiveRecord::Schema.define(:version => 20120527020350) do
|
|
21
29
|
t.datetime "updated_at", :null => false
|
22
30
|
end
|
23
31
|
|
32
|
+
create_table "papers", :force => true do |t|
|
33
|
+
t.datetime "created_at", :null => false
|
34
|
+
t.datetime "updated_at", :null => false
|
35
|
+
t.string "avatar_file_name"
|
36
|
+
t.string "avatar_content_type"
|
37
|
+
t.integer "avatar_file_size"
|
38
|
+
t.datetime "avatar_updated_at"
|
39
|
+
end
|
40
|
+
|
24
41
|
create_table "users", :force => true do |t|
|
25
42
|
t.string "email", :default => "", :null => false
|
26
43
|
t.string "encrypted_password", :default => "", :null => false
|
@@ -71,3 +71,100 @@ Migrating to DeviseCreateUsers (20120527020350)
|
|
71
71
|
[1m[35m (0.0ms)[0m PRAGMA index_info('index_users_on_confirmation_token')
|
72
72
|
[1m[36m (0.0ms)[0m [1mPRAGMA index_info('index_users_on_reset_password_token')[0m
|
73
73
|
[1m[35m (0.0ms)[0m PRAGMA index_info('index_users_on_email')
|
74
|
+
[1m[36m (0.1ms)[0m [1mSELECT "schema_migrations"."version" FROM "schema_migrations" [0m
|
75
|
+
Migrating to CreateFoos (20120219112425)
|
76
|
+
Migrating to DeviseCreateUsers (20120527020350)
|
77
|
+
Migrating to CreatePapers (20120527023350)
|
78
|
+
[1m[35m (0.0ms)[0m select sqlite_version(*)
|
79
|
+
[1m[36m (0.0ms)[0m [1mbegin transaction[0m
|
80
|
+
[1m[35m (0.2ms)[0m CREATE TABLE "papers" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL)
|
81
|
+
[1m[36m (0.1ms)[0m [1mINSERT INTO "schema_migrations" ("version") VALUES ('20120527023350')[0m
|
82
|
+
[1m[35m (5.4ms)[0m commit transaction
|
83
|
+
Migrating to AddAttachmentAvatarToPapers (20120527023417)
|
84
|
+
[1m[36m (0.0ms)[0m [1mbegin transaction[0m
|
85
|
+
[1m[35m (0.3ms)[0m ALTER TABLE "papers" ADD "avatar_file_name" varchar(255)
|
86
|
+
[1m[36m (0.2ms)[0m [1mALTER TABLE "papers" ADD "avatar_content_type" varchar(255)[0m
|
87
|
+
[1m[35m (0.2ms)[0m ALTER TABLE "papers" ADD "avatar_file_size" integer
|
88
|
+
[1m[36m (0.2ms)[0m [1mALTER TABLE "papers" ADD "avatar_updated_at" datetime[0m
|
89
|
+
[1m[35m (0.1ms)[0m INSERT INTO "schema_migrations" ("version") VALUES ('20120527023417')
|
90
|
+
[1m[36m (3.8ms)[0m [1mcommit transaction[0m
|
91
|
+
Migrating to CreateBoos (20120527025142)
|
92
|
+
[1m[35m (0.0ms)[0m begin transaction
|
93
|
+
[1m[36m (0.4ms)[0m [1mCREATE TABLE "boos" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "foo_id" integer, "poly_id" integer, "poly_type" integer, "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL) [0m
|
94
|
+
[1m[35m (0.1ms)[0m INSERT INTO "schema_migrations" ("version") VALUES ('20120527025142')
|
95
|
+
[1m[36m (4.0ms)[0m [1mcommit transaction[0m
|
96
|
+
[1m[35m (0.4ms)[0m select sqlite_version(*)
|
97
|
+
[1m[36m (0.1ms)[0m [1mSELECT "schema_migrations"."version" FROM "schema_migrations" [0m
|
98
|
+
[1m[35m (0.0ms)[0m PRAGMA index_list("boos")
|
99
|
+
[1m[36m (0.0ms)[0m [1mPRAGMA index_list("foos")[0m
|
100
|
+
[1m[35m (0.0ms)[0m PRAGMA index_list("papers")
|
101
|
+
[1m[36m (0.1ms)[0m [1mPRAGMA index_list("users")[0m
|
102
|
+
[1m[35m (0.1ms)[0m PRAGMA index_info('index_users_on_authentication_token')
|
103
|
+
[1m[36m (0.1ms)[0m [1mPRAGMA index_info('index_users_on_unlock_token')[0m
|
104
|
+
[1m[35m (0.0ms)[0m PRAGMA index_info('index_users_on_confirmation_token')
|
105
|
+
[1m[36m (0.1ms)[0m [1mPRAGMA index_info('index_users_on_reset_password_token')[0m
|
106
|
+
[1m[35m (0.0ms)[0m PRAGMA index_info('index_users_on_email')
|
107
|
+
[1m[36m (0.1ms)[0m [1mselect sqlite_version(*)[0m
|
108
|
+
[1m[35m (14.9ms)[0m CREATE TABLE "schema_migrations" ("version" varchar(255) NOT NULL)
|
109
|
+
[1m[36m (0.0ms)[0m [1mPRAGMA index_list("schema_migrations")[0m
|
110
|
+
[1m[35m (4.1ms)[0m CREATE UNIQUE INDEX "unique_schema_migrations" ON "schema_migrations" ("version")
|
111
|
+
[1m[36m (0.1ms)[0m [1mSELECT "schema_migrations"."version" FROM "schema_migrations" [0m
|
112
|
+
Migrating to CreateFoos (20120219112425)
|
113
|
+
[1m[35m (0.0ms)[0m begin transaction
|
114
|
+
[1m[36m (0.4ms)[0m [1mCREATE TABLE "foos" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "body" text, "title" varchar(255), "random_number" integer, "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL) [0m
|
115
|
+
[1m[35m (0.1ms)[0m INSERT INTO "schema_migrations" ("version") VALUES ('20120219112425')
|
116
|
+
[1m[36m (7.1ms)[0m [1mcommit transaction[0m
|
117
|
+
Migrating to DeviseCreateUsers (20120527020350)
|
118
|
+
[1m[35m (0.0ms)[0m begin transaction
|
119
|
+
[1m[36m (0.4ms)[0m [1mCREATE TABLE "users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "email" varchar(255) DEFAULT '' NOT NULL, "encrypted_password" varchar(255) DEFAULT '' NOT NULL, "reset_password_token" varchar(255), "reset_password_sent_at" datetime, "remember_created_at" datetime, "sign_in_count" integer DEFAULT 0, "current_sign_in_at" datetime, "last_sign_in_at" datetime, "current_sign_in_ip" varchar(255), "last_sign_in_ip" varchar(255), "password_salt" varchar(255), "confirmation_token" varchar(255), "confirmed_at" datetime, "confirmation_sent_at" datetime, "unconfirmed_email" varchar(255), "failed_attempts" integer DEFAULT 0, "unlock_token" varchar(255), "locked_at" datetime, "authentication_token" varchar(255), "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL) [0m
|
120
|
+
[1m[35m (0.0ms)[0m PRAGMA index_list("users")
|
121
|
+
[1m[36m (0.3ms)[0m [1mCREATE UNIQUE INDEX "index_users_on_email" ON "users" ("email")[0m
|
122
|
+
[1m[35m (0.1ms)[0m PRAGMA index_list("users")
|
123
|
+
[1m[36m (0.0ms)[0m [1mPRAGMA index_info('index_users_on_email')[0m
|
124
|
+
[1m[35m (0.2ms)[0m CREATE UNIQUE INDEX "index_users_on_reset_password_token" ON "users" ("reset_password_token")
|
125
|
+
[1m[36m (0.1ms)[0m [1mPRAGMA index_list("users")[0m
|
126
|
+
[1m[35m (0.1ms)[0m PRAGMA index_info('index_users_on_reset_password_token')
|
127
|
+
[1m[36m (0.0ms)[0m [1mPRAGMA index_info('index_users_on_email')[0m
|
128
|
+
[1m[35m (0.2ms)[0m CREATE UNIQUE INDEX "index_users_on_confirmation_token" ON "users" ("confirmation_token")
|
129
|
+
[1m[36m (0.1ms)[0m [1mPRAGMA index_list("users")[0m
|
130
|
+
[1m[35m (0.1ms)[0m PRAGMA index_info('index_users_on_confirmation_token')
|
131
|
+
[1m[36m (0.0ms)[0m [1mPRAGMA index_info('index_users_on_reset_password_token')[0m
|
132
|
+
[1m[35m (0.0ms)[0m PRAGMA index_info('index_users_on_email')
|
133
|
+
[1m[36m (0.2ms)[0m [1mCREATE UNIQUE INDEX "index_users_on_unlock_token" ON "users" ("unlock_token")[0m
|
134
|
+
[1m[35m (0.1ms)[0m PRAGMA index_list("users")
|
135
|
+
[1m[36m (0.1ms)[0m [1mPRAGMA index_info('index_users_on_unlock_token')[0m
|
136
|
+
[1m[35m (0.0ms)[0m PRAGMA index_info('index_users_on_confirmation_token')
|
137
|
+
[1m[36m (0.0ms)[0m [1mPRAGMA index_info('index_users_on_reset_password_token')[0m
|
138
|
+
[1m[35m (0.0ms)[0m PRAGMA index_info('index_users_on_email')
|
139
|
+
[1m[36m (0.2ms)[0m [1mCREATE UNIQUE INDEX "index_users_on_authentication_token" ON "users" ("authentication_token")[0m
|
140
|
+
[1m[35m (0.1ms)[0m INSERT INTO "schema_migrations" ("version") VALUES ('20120527020350')
|
141
|
+
[1m[36m (3.8ms)[0m [1mcommit transaction[0m
|
142
|
+
Migrating to CreatePapers (20120527023350)
|
143
|
+
[1m[35m (0.0ms)[0m begin transaction
|
144
|
+
[1m[36m (0.2ms)[0m [1mCREATE TABLE "papers" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL) [0m
|
145
|
+
[1m[35m (0.1ms)[0m INSERT INTO "schema_migrations" ("version") VALUES ('20120527023350')
|
146
|
+
[1m[36m (3.8ms)[0m [1mcommit transaction[0m
|
147
|
+
Migrating to AddAttachmentAvatarToPapers (20120527023417)
|
148
|
+
[1m[35m (0.0ms)[0m begin transaction
|
149
|
+
[1m[36m (0.3ms)[0m [1mALTER TABLE "papers" ADD "avatar_file_name" varchar(255)[0m
|
150
|
+
[1m[35m (0.1ms)[0m ALTER TABLE "papers" ADD "avatar_content_type" varchar(255)
|
151
|
+
[1m[36m (0.2ms)[0m [1mALTER TABLE "papers" ADD "avatar_file_size" integer[0m
|
152
|
+
[1m[35m (0.2ms)[0m ALTER TABLE "papers" ADD "avatar_updated_at" datetime
|
153
|
+
[1m[36m (0.1ms)[0m [1mINSERT INTO "schema_migrations" ("version") VALUES ('20120527023417')[0m
|
154
|
+
[1m[35m (3.2ms)[0m commit transaction
|
155
|
+
Migrating to CreateBoos (20120527025142)
|
156
|
+
[1m[36m (0.0ms)[0m [1mbegin transaction[0m
|
157
|
+
[1m[35m (0.3ms)[0m CREATE TABLE "boos" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "foo_id" integer, "poly_id" integer, "poly_type" varchar(255), "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL)
|
158
|
+
[1m[36m (0.1ms)[0m [1mINSERT INTO "schema_migrations" ("version") VALUES ('20120527025142')[0m
|
159
|
+
[1m[35m (3.7ms)[0m commit transaction
|
160
|
+
[1m[36m (0.4ms)[0m [1mselect sqlite_version(*)[0m
|
161
|
+
[1m[35m (0.1ms)[0m SELECT "schema_migrations"."version" FROM "schema_migrations"
|
162
|
+
[1m[36m (0.0ms)[0m [1mPRAGMA index_list("boos")[0m
|
163
|
+
[1m[35m (0.0ms)[0m PRAGMA index_list("foos")
|
164
|
+
[1m[36m (0.0ms)[0m [1mPRAGMA index_list("papers")[0m
|
165
|
+
[1m[35m (0.0ms)[0m PRAGMA index_list("users")
|
166
|
+
[1m[36m (0.0ms)[0m [1mPRAGMA index_info('index_users_on_authentication_token')[0m
|
167
|
+
[1m[35m (0.0ms)[0m PRAGMA index_info('index_users_on_unlock_token')
|
168
|
+
[1m[36m (0.0ms)[0m [1mPRAGMA index_info('index_users_on_confirmation_token')[0m
|
169
|
+
[1m[35m (0.0ms)[0m PRAGMA index_info('index_users_on_reset_password_token')
|
170
|
+
[1m[36m (0.0ms)[0m [1mPRAGMA index_info('index_users_on_email')[0m
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module TestApp
|
2
|
+
|
3
|
+
# No mattr_accessor before initialization ;(
|
4
|
+
def self.path=(new_path)
|
5
|
+
@path = new_path
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.path
|
9
|
+
@path
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.prepare!
|
13
|
+
self.path = File.expand_path("../../../tmp/dummy", __FILE__)
|
14
|
+
FileUtils.rm_rf path
|
15
|
+
FileUtils.mkdir_p path
|
16
|
+
FileUtils.cp_r File.expand_path("../../dummy//", __FILE__), File.expand_path(path+"/../")
|
17
|
+
system("cd #{path} && bundle exec rake db:migrate > /dev/null")
|
18
|
+
end
|
19
|
+
end
|
data/test/test_helper.rb
CHANGED
@@ -3,17 +3,13 @@ require 'fileutils'
|
|
3
3
|
# Configure Rails Environment
|
4
4
|
ENV["RAILS_ENV"] = "test"
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
system("cd #{$test_app} && bundle exec rake db:migrate > /dev/null")
|
11
|
-
|
6
|
+
# Load support files
|
7
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
8
|
+
|
9
|
+
TestApp.prepare!
|
12
10
|
|
13
|
-
require File.expand_path("#{
|
11
|
+
require File.expand_path("#{TestApp.path}/config/environment.rb", __FILE__)
|
14
12
|
require "rails/test_help"
|
15
13
|
|
16
14
|
Rails.backtrace_cleaner.remove_silencers!
|
17
15
|
|
18
|
-
# Load support files
|
19
|
-
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: annotator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2012-05
|
13
|
+
date: 2012-06-05 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rails
|
@@ -53,11 +53,20 @@ extra_rdoc_files: []
|
|
53
53
|
files:
|
54
54
|
- lib/tasks/annotator_tasks.rake
|
55
55
|
- lib/annotator.rb
|
56
|
+
- lib/annotator/initial_description/belongs_to.rb
|
57
|
+
- lib/annotator/initial_description/devise.rb
|
58
|
+
- lib/annotator/initial_description/paperclip.rb
|
59
|
+
- lib/annotator/initial_description/base.rb
|
60
|
+
- lib/annotator/initial_description/rails.rb
|
61
|
+
- lib/annotator/model.rb
|
56
62
|
- lib/annotator/version.rb
|
63
|
+
- lib/annotator/attributes.rb
|
64
|
+
- lib/annotator/initial_description.rb
|
57
65
|
- lib/annotator/railtie.rb
|
58
66
|
- MIT-LICENSE
|
59
67
|
- Rakefile
|
60
68
|
- README.rdoc
|
69
|
+
- test/support/test_app.rb
|
61
70
|
- test/test_helper.rb
|
62
71
|
- test/assets/paper_annotated.rb
|
63
72
|
- test/assets/foo_annotated_bad_column.rb
|
@@ -67,6 +76,8 @@ files:
|
|
67
76
|
- test/assets/boo_annotated.rb
|
68
77
|
- test/assets/foo_annotated.rb
|
69
78
|
- test/assets/foo_annotated_column_fixed.rb
|
79
|
+
- test/assets/foo_require_first.rb
|
80
|
+
- test/assets/moo_hoo_annotated.rb
|
70
81
|
- test/annotator_test.rb
|
71
82
|
- test/dummy/public/500.html
|
72
83
|
- test/dummy/public/favicon.ico
|
@@ -93,6 +104,7 @@ files:
|
|
93
104
|
- test/dummy/app/helpers/application_helper.rb
|
94
105
|
- test/dummy/app/models/boo.rb
|
95
106
|
- test/dummy/app/models/paper.rb
|
107
|
+
- test/dummy/app/models/moo/hoo.rb
|
96
108
|
- test/dummy/app/models/user.rb
|
97
109
|
- test/dummy/app/models/foo.rb
|
98
110
|
- test/dummy/app/models/nomodel.rb
|
@@ -138,11 +150,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
138
150
|
version: '0'
|
139
151
|
requirements: []
|
140
152
|
rubyforge_project:
|
141
|
-
rubygems_version: 1.8.
|
153
|
+
rubygems_version: 1.8.23
|
142
154
|
signing_key:
|
143
155
|
specification_version: 3
|
144
156
|
summary: Annotate your models and keep your comments about fields.
|
145
157
|
test_files:
|
158
|
+
- test/support/test_app.rb
|
146
159
|
- test/test_helper.rb
|
147
160
|
- test/assets/paper_annotated.rb
|
148
161
|
- test/assets/foo_annotated_bad_column.rb
|
@@ -152,6 +165,8 @@ test_files:
|
|
152
165
|
- test/assets/boo_annotated.rb
|
153
166
|
- test/assets/foo_annotated.rb
|
154
167
|
- test/assets/foo_annotated_column_fixed.rb
|
168
|
+
- test/assets/foo_require_first.rb
|
169
|
+
- test/assets/moo_hoo_annotated.rb
|
155
170
|
- test/annotator_test.rb
|
156
171
|
- test/dummy/public/500.html
|
157
172
|
- test/dummy/public/favicon.ico
|
@@ -178,6 +193,7 @@ test_files:
|
|
178
193
|
- test/dummy/app/helpers/application_helper.rb
|
179
194
|
- test/dummy/app/models/boo.rb
|
180
195
|
- test/dummy/app/models/paper.rb
|
196
|
+
- test/dummy/app/models/moo/hoo.rb
|
181
197
|
- test/dummy/app/models/user.rb
|
182
198
|
- test/dummy/app/models/foo.rb
|
183
199
|
- test/dummy/app/models/nomodel.rb
|