yard-activerecord 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,6 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+
6
+ .DS_Store
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in yard-activerecord.gemspec
4
+ gemspec
@@ -0,0 +1,59 @@
1
+ # YARD ActiveRecord Plugin #
2
+
3
+ A YARD extension that handles and interprets methods used when developing
4
+ applications with ActiveRecord. The extension handles attributes,
5
+ associations, delegates and scopes. A must for any Rails app using YARD as
6
+ documentation plugin.
7
+
8
+ ## Attributes ##
9
+
10
+ In order for this plugin to document any database attributes you need to add
11
+ `schema.rb` to your list of files. This is preferably done with in `.yardopts`.
12
+
13
+ The `schema.rb`-file should be added at the end as it needs all classes loaded
14
+ before it can add the attributes.
15
+
16
+ The plugin will then document all attributes in your documentation.
17
+
18
+ All attributes will be marked as writable. I will update the plugin to include
19
+ handling of `attr_accessible` at a later point.
20
+
21
+ Please note that any reference-fields that ends with `_id` will not be handled
22
+ as an attribute. Please see Associations.
23
+
24
+ There is an issue with namespaced classes. Currently this plugin will try and
25
+ fetch a class with a namespace if it does not find one at the first try.
26
+
27
+ Example:
28
+
29
+ Table name Class name
30
+ sales_people SalesPeople # does not exist
31
+ sales_people Sales::People # does exist
32
+
33
+ A problem then emerges if you have namespaces with two names.
34
+
35
+ Example:
36
+
37
+ Table name Class name
38
+ sales_force_people SalesForcePeople # does not exist
39
+ sales_force_people Sales::ForcePeople # does not exist
40
+
41
+ The documentation will then be skipped for this table/class.
42
+
43
+ ## Associations ##
44
+
45
+ The plugin handles `has_one`, `belongs_to`, `has_many` and
46
+ `has_and_belongs_to_many` associations. The annotation for each association
47
+ includes a link to the referred model. For associations with a list of objects
48
+ the documentation will simply be marked as `Array<ModelName>`.
49
+
50
+ ## Delegates ##
51
+
52
+ The plugin handles `delegate`-methods and marks these delegated instance
53
+ methods simply as aliases for the associated object.
54
+
55
+ ## Scopes ##
56
+
57
+ The plugin will add class methods for any scopes you have defined in your
58
+ models.
59
+
@@ -0,0 +1 @@
1
+ require 'bundler/gem_tasks'
@@ -0,0 +1,20 @@
1
+ require 'yard'
2
+
3
+ module YARD::Handlers::Ruby::ActiveRecord
4
+ end
5
+
6
+ root = File.expand_path(File.dirname(__FILE__))
7
+ $LOAD_PATH << root unless $LOAD_PATH.include? root
8
+
9
+ require 'yard-activerecord/fields/create_table_handler'
10
+ require 'yard-activerecord/fields/define_handler'
11
+ require 'yard-activerecord/fields/field_handler'
12
+
13
+ require 'yard-activerecord/associations/belongs_to_handler'
14
+ require 'yard-activerecord/associations/has_one_handler'
15
+ require 'yard-activerecord/associations/has_many_handler'
16
+ require 'yard-activerecord/associations/has_and_belongs_to_many_handler'
17
+
18
+ require 'yard-activerecord/delegations/delegate_handler'
19
+
20
+ require 'yard-activerecord/scopes/scope_handler'
@@ -0,0 +1,53 @@
1
+ require 'yard'
2
+ require 'active_support/inflector'
3
+
4
+ module YARD::Handlers::Ruby::ActiveRecord::Associations
5
+ class Base < YARD::Handlers::Ruby::MethodHandler
6
+ namespace_only
7
+
8
+ def process
9
+ group_name = "Active Record Associations"
10
+ namespace.groups << group_name unless namespace.groups.include? group_name
11
+
12
+ object = YARD::CodeObjects::MethodObject.new(namespace, method_name)
13
+ object.group = group_name
14
+ object.docstring = return_description
15
+ object.docstring.add_tag get_tag(:return, '', class_name)
16
+ object.docstring.add_tag get_tag(:see, 'http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html')
17
+ object.dynamic = true
18
+ register object
19
+ end
20
+
21
+ private
22
+ def method_name
23
+ call_params[0]
24
+ end
25
+
26
+ def class_name(singularize = false)
27
+ param_size = statement.parameters.size
28
+ if param_size > 2
29
+ i = 1
30
+ return_this = false
31
+ while i < param_size - 1
32
+ # May want to evaluate doing it this way
33
+ statement.parameters[i].jump(:hash).source =~ /(:class_name\s*=>|class_name:)\s*["']([^"']+)["']/
34
+ return $2 if $2
35
+ i += 1
36
+ end
37
+ end
38
+ if singularize == true
39
+ ActiveSupport::Inflector.singularize method_name.capitalize
40
+ else
41
+ method_name.capitalize
42
+ end
43
+ end
44
+
45
+ def return_description
46
+ "An array of associated #{method_name}."
47
+ end
48
+
49
+ def get_tag(tag, text, return_classes = [])
50
+ YARD::Tags::Tag.new(tag, text, [return_classes].flatten)
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,12 @@
1
+ require_relative 'singular_handler'
2
+
3
+ module YARD::Handlers::Ruby::ActiveRecord::Associations
4
+ class BelongsToHandler < SingularHandler
5
+ handles method_call(:belongs_to)
6
+
7
+ private
8
+ def return_description
9
+ "#{namespace} <b>belongs to</b> a #{class_name}"
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,11 @@
1
+ require_relative 'plural_handler'
2
+
3
+ module YARD::Handlers::Ruby::ActiveRecord::Associations
4
+ class HasAndBelongsToManyHandler < PluralHandler
5
+ handles method_call(:has_and_belongs_to_many)
6
+
7
+ def return_description
8
+ "#{namespace} <b>has and belongs to many</b> #{method_name}"
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ require_relative 'plural_handler'
2
+
3
+ module YARD::Handlers::Ruby::ActiveRecord::Associations
4
+ class HasManyHandler < PluralHandler
5
+ handles method_call(:has_many)
6
+
7
+ def return_description
8
+ "#{namespace} <b>has many</b> #{method_name}"
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ require_relative 'singular_handler'
2
+
3
+ module YARD::Handlers::Ruby::ActiveRecord::Associations
4
+ class HasOneHandler < SingularHandler
5
+ handles method_call(:has_one)
6
+
7
+ def return_description
8
+ "#{namespace} <b>has one</b> #{method_name}"
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ require_relative 'base'
2
+
3
+ module YARD::Handlers::Ruby::ActiveRecord::Associations
4
+ class PluralHandler < Base
5
+ def class_name
6
+ "Array<#{super(true)}>"
7
+ end
8
+
9
+ def return_description
10
+ "An array of associated #{method_name}"
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ require_relative 'base'
2
+
3
+ module YARD::Handlers::Ruby::ActiveRecord::Associations
4
+ class SingularHandler < Base
5
+ def class_name
6
+ super(false)
7
+ end
8
+
9
+ def return_description
10
+ "An associated #{method_name}"
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,31 @@
1
+ require 'yard'
2
+
3
+ module YARD::Handlers::Ruby::ActiveRecord::Delegations
4
+ class DelegateHandler < YARD::Handlers::Ruby::MethodHandler
5
+ handles method_call(:delegate)
6
+ namespace_only
7
+
8
+ def process
9
+ params = call_params
10
+ class_name = params.pop.capitalize
11
+ params.each do |method_name|
12
+ object = YARD::CodeObjects::MethodObject.new(namespace, method_name)
13
+ object.group = "Delegated Instance Attributes"
14
+ object.docstring = "Please refer to {#{class_name}##{method_name}}"
15
+ object.docstring.add_tag get_tag(:return,
16
+ "{#{class_name}##{method_name}}", 'Object')
17
+ object.docstring.add_tag get_tag(:see,
18
+ "http://api.rubyonrails.org/classes/Module.html#method-i-delegate")
19
+ register object
20
+ end
21
+ group_name = "Delegated Instance Attributes"
22
+ namespace.groups << group_name unless namespace.groups.include? group_name
23
+ end
24
+
25
+ private
26
+
27
+ def get_tag(tag, text, return_classes = [])
28
+ YARD::Tags::Tag.new(tag, text, [return_classes].flatten)
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,19 @@
1
+ require 'yard'
2
+ require 'active_support/inflector'
3
+
4
+ module YARD::Handlers::Ruby::ActiveRecord::Fields
5
+ class CreateTableHandler < YARD::Handlers::Ruby::MethodHandler
6
+ handles method_call(:create_table)
7
+
8
+ def process
9
+ return unless globals.ar_schema
10
+ globals.klass = ActiveSupport::Inflector.singularize call_params.first.camelize
11
+ if P(globals.klass).class == YARD::CodeObjects::Proxy
12
+ # Try module with the first part
13
+ globals.klass = globals.klass.underscore.split('_',2).map(&:camelize).join('::')
14
+ end
15
+ parse_block(statement.last.last)
16
+ globals.klass = nil
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,13 @@
1
+ module YARD::Handlers::Ruby::ActiveRecord::Fields
2
+ class DefineHandler < YARD::Handlers::Ruby::MethodHandler
3
+ handles method_call(:define)
4
+
5
+ def process
6
+ if statement.file == 'db/schema.rb'
7
+ globals.ar_schema = true
8
+ parse_block(statement.last.last)
9
+ globals.ar_schema = false
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,50 @@
1
+ module YARD::Handlers::Ruby::ActiveRecord::Fields
2
+ class FieldHandler < YARD::Handlers::Ruby::MethodHandler
3
+ handles method_call(:string)
4
+ handles method_call(:text)
5
+ handles method_call(:integer)
6
+ handles method_call(:float)
7
+ handles method_call(:boolean)
8
+ handles method_call(:datetime)
9
+
10
+ def process
11
+ return unless statement.namespace.jump(:ident).source == 't'
12
+ method_name = call_params.first
13
+ class_name = caller_method.capitalize
14
+
15
+ return if method_name['_id'] # Skip all id fields, associations will handle that
16
+
17
+ if class_name == "Datetime"
18
+ class_name = "DateTime"
19
+ end
20
+ ensure_loaded! P(globals.klass)
21
+ namespace = P(globals.klass)
22
+ return if namespace.nil?
23
+
24
+ r_object = YARD::CodeObjects::MethodObject.new(namespace, method_name)
25
+ r_object.docstring = description(method_name)
26
+ r_object.docstring.add_tag get_tag(:return, '', class_name)
27
+ r_object.dynamic = true
28
+ register r_object
29
+
30
+ w_object = YARD::CodeObjects::MethodObject.new(namespace, "#{method_name}=")
31
+ w_object.docstring = description(method_name)
32
+ w_object.docstring.add_tag get_tag(:return, '', class_name)
33
+ w_object.dynamic = true
34
+ register w_object
35
+
36
+ namespace.instance_attributes[method_name.to_sym] = {
37
+ read: r_object,
38
+ write: w_object
39
+ }
40
+ end
41
+
42
+ def description(method_name)
43
+ "Database field value of #{method_name}. Defined in {file:db/schema.rb}"
44
+ end
45
+
46
+ def get_tag(tag, text, return_classes)
47
+ YARD::Tags::Tag.new(:return, text, [return_classes].flatten)
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,36 @@
1
+ require 'active_support/inflector'
2
+
3
+ module YARD::Handlers::Ruby::ActiveRecord::Scopes
4
+ class ScopeHandler < YARD::Handlers::Ruby::MethodHandler
5
+ handles method_call(:scope)
6
+ namespace_only
7
+
8
+ def process
9
+ object = YARD::CodeObjects::MethodObject.new(namespace, method_name, :class)
10
+ object.docstring = return_description
11
+ object.docstring.add_tag get_tag(:return, '', class_name)
12
+ object.docstring.add_tag get_tag(:see,
13
+ 'http://api.rubyonrails.org/classes/ActiveRecord/NamedScope/ClassMethods.html')
14
+ register object
15
+ end
16
+
17
+ private
18
+ def method_name
19
+ call_params[0]
20
+ end
21
+
22
+ def return_description
23
+ "An array of #{ActiveSupport::Inflector.pluralize namespace.to_s} " +
24
+ "that are #{method_name.split('_').join(' ')}. " +
25
+ "<strong>Active Record Scope</strong>"
26
+ end
27
+
28
+ def class_name
29
+ "Array<#{namespace}>"
30
+ end
31
+
32
+ def get_tag(tag, text, return_classes = [])
33
+ YARD::Tags::Tag.new(tag, text, [return_classes].flatten)
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,5 @@
1
+ module YARD
2
+ module ActiveRecord
3
+ VERSION = "0.0.5"
4
+ end
5
+ end
data/test.rb ADDED
@@ -0,0 +1,4 @@
1
+ require 'bundler/setup'
2
+ require 'yard-activerecord'
3
+
4
+ YARD::Handlers::Ruby::ActiveRecord::Fields::CreateTable.new
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+
4
+ require "yard-activerecord/version"
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "yard-activerecord"
8
+ s.version = YARD::ActiveRecord::VERSION
9
+ s.authors = ["Theodor Tonum"]
10
+ s.email = ["theodor@tonum.no"]
11
+ s.homepage = ""
12
+ s.summary = %q{ActiveRecord Handlers for YARD}
13
+ s.description = %q{
14
+ YARD-Activerecord is a YARD extension that handles and interprets methods
15
+ used when developing applications with ActiveRecord. The extension handles
16
+ attributes, associations, delegates and scopes. A must for any Rails app
17
+ using YARD as documentation plugin. }
18
+
19
+ s.add_dependency 'yard', '>= 0.8.3'
20
+
21
+ s.files = `git ls-files`.split("\n")
22
+ s.require_path = "lib"
23
+ end
metadata ADDED
@@ -0,0 +1,85 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: yard-activerecord
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.5
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Theodor Tonum
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-02-05 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: yard
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 0.8.3
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 0.8.3
30
+ description: ! "\n YARD-Activerecord is a YARD extension that handles and interprets
31
+ methods\n used when developing applications with ActiveRecord. The extension
32
+ handles\n attributes, associations, delegates and scopes. A must for any Rails
33
+ app\n using YARD as documentation plugin. "
34
+ email:
35
+ - theodor@tonum.no
36
+ executables: []
37
+ extensions: []
38
+ extra_rdoc_files: []
39
+ files:
40
+ - .gitignore
41
+ - Gemfile
42
+ - README.md
43
+ - Rakefile
44
+ - lib/yard-activerecord.rb
45
+ - lib/yard-activerecord/associations/base.rb
46
+ - lib/yard-activerecord/associations/belongs_to_handler.rb
47
+ - lib/yard-activerecord/associations/has_and_belongs_to_many_handler.rb
48
+ - lib/yard-activerecord/associations/has_many_handler.rb
49
+ - lib/yard-activerecord/associations/has_one_handler.rb
50
+ - lib/yard-activerecord/associations/plural_handler.rb
51
+ - lib/yard-activerecord/associations/singular_handler.rb
52
+ - lib/yard-activerecord/delegations/delegate_handler.rb
53
+ - lib/yard-activerecord/fields/create_table_handler.rb
54
+ - lib/yard-activerecord/fields/define_handler.rb
55
+ - lib/yard-activerecord/fields/field_handler.rb
56
+ - lib/yard-activerecord/scopes/scope_handler.rb
57
+ - lib/yard-activerecord/version.rb
58
+ - test.rb
59
+ - yard-activerecord.gemspec
60
+ homepage: ''
61
+ licenses: []
62
+ post_install_message:
63
+ rdoc_options: []
64
+ require_paths:
65
+ - lib
66
+ required_ruby_version: !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ! '>='
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ requirements: []
79
+ rubyforge_project:
80
+ rubygems_version: 1.8.25
81
+ signing_key:
82
+ specification_version: 3
83
+ summary: ActiveRecord Handlers for YARD
84
+ test_files: []
85
+ has_rdoc: