inch 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (101) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -0
  3. data/README.md +335 -3
  4. data/Rakefile +8 -0
  5. data/TODOS.md +12 -0
  6. data/bin/inch +17 -0
  7. data/inch.gemspec +7 -2
  8. data/lib/inch.rb +6 -1
  9. data/lib/inch/cli.rb +24 -0
  10. data/lib/inch/cli/arguments.rb +45 -0
  11. data/lib/inch/cli/command.rb +29 -0
  12. data/lib/inch/cli/command/base.rb +62 -0
  13. data/lib/inch/cli/command/base_list.rb +75 -0
  14. data/lib/inch/cli/command/base_object.rb +40 -0
  15. data/lib/inch/cli/command/console.rb +22 -0
  16. data/lib/inch/cli/command/inspect.rb +20 -0
  17. data/lib/inch/cli/command/list.rb +25 -0
  18. data/lib/inch/cli/command/options/base.rb +137 -0
  19. data/lib/inch/cli/command/options/base_list.rb +84 -0
  20. data/lib/inch/cli/command/options/base_object.rb +47 -0
  21. data/lib/inch/cli/command/options/console.rb +26 -0
  22. data/lib/inch/cli/command/options/inspect.rb +25 -0
  23. data/lib/inch/cli/command/options/list.rb +30 -0
  24. data/lib/inch/cli/command/options/show.rb +27 -0
  25. data/lib/inch/cli/command/options/stats.rb +20 -0
  26. data/lib/inch/cli/command/options/suggest.rb +61 -0
  27. data/lib/inch/cli/command/output/base.rb +32 -0
  28. data/lib/inch/cli/command/output/console.rb +45 -0
  29. data/lib/inch/cli/command/output/inspect.rb +129 -0
  30. data/lib/inch/cli/command/output/list.rb +87 -0
  31. data/lib/inch/cli/command/output/show.rb +79 -0
  32. data/lib/inch/cli/command/output/stats.rb +111 -0
  33. data/lib/inch/cli/command/output/suggest.rb +104 -0
  34. data/lib/inch/cli/command/show.rb +20 -0
  35. data/lib/inch/cli/command/stats.rb +20 -0
  36. data/lib/inch/cli/command/suggest.rb +104 -0
  37. data/lib/inch/cli/command_parser.rb +82 -0
  38. data/lib/inch/cli/sparkline_helper.rb +31 -0
  39. data/lib/inch/cli/trace_helper.rb +42 -0
  40. data/lib/inch/cli/yardopts_helper.rb +49 -0
  41. data/lib/inch/code_object.rb +8 -0
  42. data/lib/inch/code_object/docstring.rb +97 -0
  43. data/lib/inch/code_object/nodoc_helper.rb +84 -0
  44. data/lib/inch/code_object/proxy.rb +37 -0
  45. data/lib/inch/code_object/proxy/base.rb +194 -0
  46. data/lib/inch/code_object/proxy/class_object.rb +9 -0
  47. data/lib/inch/code_object/proxy/constant_object.rb +8 -0
  48. data/lib/inch/code_object/proxy/method_object.rb +118 -0
  49. data/lib/inch/code_object/proxy/method_parameter_object.rb +81 -0
  50. data/lib/inch/code_object/proxy/module_object.rb +8 -0
  51. data/lib/inch/code_object/proxy/namespace_object.rb +38 -0
  52. data/lib/inch/core_ext.rb +2 -0
  53. data/lib/inch/core_ext/string.rb +3 -0
  54. data/lib/inch/core_ext/yard.rb +4 -0
  55. data/lib/inch/evaluation.rb +35 -0
  56. data/lib/inch/evaluation/base.rb +60 -0
  57. data/lib/inch/evaluation/class_object.rb +6 -0
  58. data/lib/inch/evaluation/constant_object.rb +34 -0
  59. data/lib/inch/evaluation/file.rb +66 -0
  60. data/lib/inch/evaluation/method_object.rb +127 -0
  61. data/lib/inch/evaluation/module_object.rb +6 -0
  62. data/lib/inch/evaluation/namespace_object.rb +94 -0
  63. data/lib/inch/evaluation/role/base.rb +49 -0
  64. data/lib/inch/evaluation/role/constant.rb +43 -0
  65. data/lib/inch/evaluation/role/method.rb +60 -0
  66. data/lib/inch/evaluation/role/method_parameter.rb +46 -0
  67. data/lib/inch/evaluation/role/missing.rb +20 -0
  68. data/lib/inch/evaluation/role/namespace.rb +58 -0
  69. data/lib/inch/evaluation/role/object.rb +64 -0
  70. data/lib/inch/evaluation/score_range.rb +26 -0
  71. data/lib/inch/rake.rb +1 -0
  72. data/lib/inch/rake/suggest.rb +26 -0
  73. data/lib/inch/source_parser.rb +36 -0
  74. data/lib/inch/version.rb +1 -1
  75. data/test/fixtures/code_examples/lib/foo.rb +87 -0
  76. data/test/fixtures/readme/lib/foo.rb +17 -0
  77. data/test/fixtures/simple/README +25 -0
  78. data/test/fixtures/simple/lib/broken.rb +10 -0
  79. data/test/fixtures/simple/lib/foo.rb +214 -0
  80. data/test/fixtures/simple/lib/role_methods.rb +78 -0
  81. data/test/fixtures/simple/lib/role_namespaces.rb +68 -0
  82. data/test/fixtures/visibility/lib/foo.rb +18 -0
  83. data/test/fixtures/yardopts/.yardopts +1 -0
  84. data/test/fixtures/yardopts/foo/bar.rb +6 -0
  85. data/test/inch/cli/arguments_test.rb +70 -0
  86. data/test/inch/cli/command/console_test.rb +59 -0
  87. data/test/inch/cli/command/inspect_test.rb +59 -0
  88. data/test/inch/cli/command/list_test.rb +61 -0
  89. data/test/inch/cli/command/show_test.rb +59 -0
  90. data/test/inch/cli/command/stats_test.rb +57 -0
  91. data/test/inch/cli/command/suggest_test.rb +57 -0
  92. data/test/inch/cli/command_parser_test.rb +33 -0
  93. data/test/inch/cli/yardopts_helper_test.rb +84 -0
  94. data/test/inch/code_object/docstring_test.rb +204 -0
  95. data/test/inch/code_object/nodoc_helper_test.rb +38 -0
  96. data/test/inch/code_object/proxy_test.rb +188 -0
  97. data/test/inch/source_parser_test.rb +23 -0
  98. data/test/integration/stats_options_test.rb +34 -0
  99. data/test/integration/visibility_options_test.rb +79 -0
  100. data/test/test_helper.rb +21 -0
  101. metadata +184 -7
@@ -0,0 +1,58 @@
1
+ module Inch
2
+ module Evaluation
3
+ module Role
4
+ module Namespace
5
+ class WithChildren < Base
6
+ # This role doesnot assign a score.
7
+ def score
8
+ 0
9
+ end
10
+
11
+ # This role sets a max_score.
12
+ def max_score
13
+ # @value.to_f
14
+ end
15
+ end
16
+ class WithManyChildren < Base
17
+ # +priority
18
+ def priority
19
+ +1
20
+ end
21
+ end
22
+ class WithManyAttributes < Base
23
+ # +priority
24
+ def priority
25
+ +1
26
+ end
27
+ end
28
+
29
+ class WithoutChildren < Base
30
+ end
31
+ class WithoutMethods < Base
32
+ # --priority
33
+ def priority
34
+ -2
35
+ end
36
+ end
37
+ # A 'pure' namespace has only namespaces as children
38
+ class Pure < Base
39
+ # --priority
40
+ def priority
41
+ -2
42
+ end
43
+ end
44
+ # A 'core' namespace is a class or module that is part of the Ruby
45
+ # core. It might appear in the object tree when monkey-patching
46
+ # functionality.
47
+ # But just because we patch Hash does not mean we need to document
48
+ # the Hash class itself.
49
+ class Core < Base
50
+ # --priority
51
+ def priority
52
+ -7
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,64 @@
1
+ module Inch
2
+ module Evaluation
3
+ module Role
4
+ module Object
5
+ class WithDoc < Base
6
+ end
7
+ class WithoutDoc < Missing
8
+ def suggestion
9
+ "Add a comment describing the #{object_type}"
10
+ end
11
+ end
12
+
13
+ # Tagged means tagged in an unconsidred way, i.e. YARD tags not
14
+ # considered by Inch. Since these tags are parsed from the docstring
15
+ # the object seems undocumented to Inch.
16
+ class Tagged < Base
17
+ def priority
18
+ -1
19
+ end
20
+ end
21
+ class TaggedAsNodoc < Base
22
+ def priority
23
+ -7
24
+ end
25
+ end
26
+ class InRoot < Base
27
+ def priority
28
+ +3
29
+ end
30
+ end
31
+
32
+ class Public < Base
33
+ def priority
34
+ if object.type == :constant
35
+ -1
36
+ else
37
+ +2
38
+ end
39
+ end
40
+ end
41
+ class Protected < Base
42
+ def priority
43
+ +1
44
+ end
45
+ end
46
+ class Private < Base
47
+ def priority
48
+ -2
49
+ end
50
+ end
51
+
52
+ class WithCodeExample < Base
53
+ end
54
+ class WithMultipleCodeExamples < Base
55
+ end
56
+ class WithoutCodeExample < Missing
57
+ def suggestion
58
+ "Add a code example (optional)"
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,26 @@
1
+ module Inch
2
+ module Evaluation
3
+ class ScoreRange < Struct.new(:range, :grade, :description, :color, :bg_color)
4
+ # Returns code_objects that received a score with the defined +range+
5
+ attr_reader :objects
6
+
7
+ def objects=(arr)
8
+ arr.each { |o| o.grade = grade }
9
+ @objects = arr
10
+ end
11
+ end
12
+
13
+ SCORE_RANGE_ARGS = [
14
+ [80..100, :A, "Seems really good", :green],
15
+ [50...80, :B, "Proper documentation present", :yellow],
16
+ [1...50, :C, "Needs work", :red],
17
+ [0..0, :U, "Undocumented", :color141, :color105],
18
+ ]
19
+
20
+ def self.new_score_ranges
21
+ SCORE_RANGE_ARGS.map do |args|
22
+ ScoreRange.new(*args)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1 @@
1
+ require_relative 'rake/suggest'
@@ -0,0 +1,26 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rake'
4
+ require 'rake/tasklib'
5
+
6
+ module Inch
7
+ module Rake
8
+ class Suggest < ::Rake::TaskLib
9
+ attr_accessor :name
10
+ attr_accessor :args
11
+
12
+ def initialize(name = "inch", *args, &block)
13
+ @name = name
14
+ @args = args
15
+ block.call(self) if block
16
+
17
+ desc "Suggest objects to add documention to"
18
+ task(@name) { suggest }
19
+ end
20
+
21
+ def suggest
22
+ CLI::Command::Suggest.run(*@args)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,36 @@
1
+ module Inch
2
+ # Parses the source tree
3
+ class SourceParser
4
+ def self.run(*args)
5
+ parser = self.new
6
+ parser.run(*args)
7
+ parser
8
+ end
9
+
10
+ def all_objects
11
+ @all_objects ||= all_parsed_objects.map do |o|
12
+ CodeObject::Proxy.for(o)
13
+ end.sort_by(&:path)
14
+ end
15
+
16
+ def find_object(path)
17
+ all_objects.detect { |o| o.path == path }
18
+ end
19
+ alias :[] :find_object
20
+
21
+ def find_objects(path)
22
+ all_objects.select { |o| o.path.start_with?(path) }
23
+ end
24
+
25
+ def run(paths, excluded = [])
26
+ YARD::Registry.clear
27
+ YARD.parse(paths, excluded)
28
+ end
29
+
30
+ private
31
+
32
+ def all_parsed_objects
33
+ YARD::Registry.all
34
+ end
35
+ end
36
+ end
@@ -1,3 +1,3 @@
1
1
  module Inch
2
- VERSION = "0.0.1"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -0,0 +1,87 @@
1
+ # The module 'Foo' has a doc string (this), but the class
2
+ # 'Foo::Bar' does not.
3
+ module Foo
4
+ class Bar
5
+ # This is an example:
6
+ #
7
+ # method_with_code_example() # => some value
8
+ #
9
+ # @param p1 [String] mandatory param
10
+ # @param p2 [String, nil] optionally param
11
+ # @return [void]
12
+ def method_with_code_example(p1, p2 = nil)
13
+ end
14
+
15
+ # This is an example:
16
+ #
17
+ # @example
18
+ # method_with_code_example() # => some value
19
+ #
20
+ # @param p1 [String] mandatory param
21
+ # @param p2 [String, nil] optionally param
22
+ # @return [void]
23
+ def method_with_code_example2(p1, p2 = nil)
24
+ end
25
+
26
+ #
27
+ # Options: noop verbose force
28
+ #
29
+ # Changes owner and group on the named files (in +list+)
30
+ # to the user +user+ and the group +group+ recursively.
31
+ # +user+ and +group+ may be an ID (Integer/String) or
32
+ # a name (String). If +user+ or +group+ is nil, this
33
+ # method does not change the attribute.
34
+ #
35
+ # object.method_with_examples 1, 'www', 'www', '/var/www/htdocs'
36
+ # object.method_with_examples 2, 'cvs', 'cvs', :verbose => true
37
+ #
38
+ def method_with_examples(user, group, list, options = {})
39
+ end
40
+
41
+ #
42
+ # Options: noop verbose force
43
+ #
44
+ # Changes owner and group on the named files (in +list+)
45
+ # to the user +user+ and the group +group+ recursively.
46
+ # +user+ and +group+ may be an ID (Integer/String) or
47
+ # a name (String). If +user+ or +group+ is nil, this
48
+ # method does not change the attribute.
49
+ #
50
+ # @example
51
+ # object.method_with_tagged_example 1, 'www', 'www', '/var/www/htdocs'
52
+ # object.method_with_tagged_example 2, 'cvs', 'cvs', :verbose => true
53
+ #
54
+ def method_with_tagged_example(user, group, list, options = {})
55
+ end
56
+
57
+ #
58
+ # Options: noop verbose force
59
+ #
60
+ # Changes owner and group on the named files (in +list+)
61
+ # to the user +user+ and the group +group+ recursively.
62
+ # +user+ and +group+ may be an ID (Integer/String) or
63
+ #
64
+ # @example
65
+ # object.method_with_examples 1, 'www', 'www', '/var/www/htdocs'
66
+ #
67
+ # a name (String). If +user+ or +group+ is nil, this
68
+ # method does not change the attribute.
69
+ #
70
+ # @example
71
+ # object.method_with_examples 2, 'cvs', 'cvs', :verbose => true
72
+ #
73
+ def method_with_2tagged_examples(user, group, list, options = {})
74
+ end
75
+
76
+ # Changes owner and group on the named files (in +list+)
77
+ #
78
+ # object.method_with_one_example_other :similar
79
+ # object.method_with_one_example 'www', 'www', '/var/www/htdocs'
80
+ # # => 'cvs'
81
+ #
82
+ # No code.
83
+ #
84
+ def method_with_one_example
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,17 @@
1
+ class Foo
2
+ # A complicated method
3
+ def complicated(o, i, *args, &block)
4
+ # ... snip ...
5
+ end
6
+
7
+ # An example of a method that takes a parameter (+param1+)
8
+ # and does nothing.
9
+ #
10
+ # Returns nil
11
+ def nothing(param1)
12
+ end
13
+
14
+ def filename
15
+ "#{self.class}_#{id}.foo"
16
+ end
17
+ end
@@ -0,0 +1,25 @@
1
+ # Inch 'simple' fixture
2
+
3
+ Here goes the fixture description
4
+
5
+ ## Installation
6
+
7
+ Or install it yourself as:
8
+
9
+ $ gem install inch
10
+
11
+ ## Usage
12
+
13
+ $ cd test/fixtures/simple
14
+
15
+ $ be inch
16
+
17
+ TODO: Write better usage instructions here
18
+
19
+ ## Contributing
20
+
21
+ 1. Fork it ( http://github.com/rrrene/inch/fork )
22
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
23
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
24
+ 4. Push to the branch (`git push origin my-new-feature`)
25
+ 5. Create new Pull Request
@@ -0,0 +1,10 @@
1
+ module Foo
2
+ # The problem here is that the @param tag is not given the name of the
3
+ # parameter it documents.
4
+ #
5
+ # @param [Encoding]
6
+ # @return [String]
7
+ def method_with_wrong_param_tag(e)
8
+
9
+ end
10
+ end
@@ -0,0 +1,214 @@
1
+ # The module 'Foo' has a doc string (this), but the class
2
+ # 'Foo::Bar' does not.
3
+ module Foo
4
+ class Bar
5
+ def method_without_doc
6
+ end
7
+
8
+ # Provides an example of a missing described parameter.
9
+ #
10
+ # @param param1 [String]
11
+ # @param param2 [String, nil]
12
+ # @return [void]
13
+ def method_with_missing_param_doc(param1, param2, param3)
14
+ end
15
+
16
+ # Provides an example of a wrongly described parameter.
17
+ #
18
+ # @param param1 [String]
19
+ # @param param4 [String, nil]
20
+ # @return [void]
21
+ def method_with_wrong_doc(param1, param2, param3)
22
+ end
23
+
24
+ # Provides an example of a fully described method.
25
+ #
26
+ # @param p1 [String] mandatory param
27
+ # @param p2 [String, nil] optionally param
28
+ # @return [void]
29
+ def method_with_full_doc(p1, p2 = nil)
30
+ end
31
+
32
+ # @param p1 [String] mandatory param
33
+ # @param p2 [String, nil] optionally param
34
+ # @return [void]
35
+ def method_without_docstring(p1, p2 = nil)
36
+ end
37
+
38
+ # @return [void]
39
+ def method_without_params_or_docstring
40
+ end
41
+
42
+ # Provides an example of a method without parameters
43
+ # missing the return type.
44
+ #
45
+ def method_without_params_or_return_type
46
+ end
47
+
48
+ # An example of a method using RDoc rather than YARD.
49
+ #
50
+ # == Parameters:
51
+ # param1::
52
+ # A Symbol declaring some markup language like `:md` or `:html`.
53
+ #
54
+ # == Returns:
55
+ # A string in the specified format.
56
+ #
57
+ def method_with_rdoc_doc(param1 = :html)
58
+ end
59
+
60
+ # Another example of a method using RDoc rather than YARD.
61
+ #
62
+ # Params:
63
+ # +param1+:: param1 line string to be executed by the system
64
+ # +param2+:: +Proc+ object that takes a pipe object as first and only param (may be nil)
65
+ # +param3+:: +Proc+ object that takes a pipe object as first and only param (may be nil)
66
+ def method_with_other_rdoc_doc(param1, param2, param3)
67
+ end
68
+
69
+ # An example of a method that takes a parameter (+param1+)
70
+ # and does nothing. But the previous sentence mentions said
71
+ # parameter.
72
+ #
73
+ def method_with_unstructured_doc(param1)
74
+ end
75
+
76
+ # Just because format_html is mentioned here, does not mean
77
+ # the first parameter is mentioned.
78
+ #
79
+ def method_with_unstructured_doc_missing_params(format)
80
+ end
81
+
82
+ # This is an example:
83
+ #
84
+ # method_with_code_example() # => some value
85
+ #
86
+ # @param p1 [String] mandatory param
87
+ # @param p2 [String, nil] optionally param
88
+ # @return [void]
89
+ def method_with_code_example(p1, p2 = nil)
90
+ end
91
+
92
+ # This is an example:
93
+ #
94
+ # @example
95
+ # method_with_code_example() # => some value
96
+ #
97
+ # @param p1 [String] mandatory param
98
+ # @param p2 [String, nil] optionally param
99
+ # @return [void]
100
+ def method_with_code_example2(p1, p2 = nil)
101
+ end
102
+
103
+ class Baz
104
+ def initialize(param1, param2, param3)
105
+ end
106
+
107
+ #
108
+ # Options: noop verbose force
109
+ #
110
+ # Changes owner and group on the named files (in +list+)
111
+ # to the user +user+ and the group +group+ recursively.
112
+ # +user+ and +group+ may be an ID (Integer/String) or
113
+ # a name (String). If +user+ or +group+ is nil, this
114
+ # method does not change the attribute.
115
+ #
116
+ # object.method_with_examples 1, 'www', 'www', '/var/www/htdocs'
117
+ # object.method_with_examples 2, 'cvs', 'cvs', :verbose => true
118
+ #
119
+ def method_with_examples(user, group, list, options = {})
120
+ end
121
+
122
+ #
123
+ # Options: noop verbose force
124
+ #
125
+ # Changes owner and group on the named files (in +list+)
126
+ # to the user +user+ and the group +group+ recursively.
127
+ # +user+ and +group+ may be an ID (Integer/String) or
128
+ # a name (String). If +user+ or +group+ is nil, this
129
+ # method does not change the attribute.
130
+ #
131
+ # @example
132
+ # object.method_with_tagged_example 1, 'www', 'www', '/var/www/htdocs'
133
+ # object.method_with_tagged_example 2, 'cvs', 'cvs', :verbose => true
134
+ #
135
+ def method_with_tagged_example(user, group, list, options = {})
136
+ end
137
+
138
+ #
139
+ # Options: noop verbose force
140
+ #
141
+ # Changes owner and group on the named files (in +list+)
142
+ # to the user +user+ and the group +group+ recursively.
143
+ # +user+ and +group+ may be an ID (Integer/String) or
144
+ #
145
+ # @example
146
+ # object.method_with_examples 1, 'www', 'www', '/var/www/htdocs'
147
+ #
148
+ # a name (String). If +user+ or +group+ is nil, this
149
+ # method does not change the attribute.
150
+ #
151
+ # @example
152
+ # object.method_with_examples 2, 'cvs', 'cvs', :verbose => true
153
+ #
154
+ def method_with_2tagged_examples(user, group, list, options = {})
155
+ end
156
+
157
+ # Changes owner and group on the named files (in +list+)
158
+ #
159
+ # object.method_with_one_example_other :similar
160
+ # object.method_with_one_example 'www', 'www', '/var/www/htdocs'
161
+ # # => 'cvs'
162
+ #
163
+ # No code.
164
+ #
165
+ def method_with_one_example
166
+ end
167
+ end
168
+ end
169
+
170
+ class Baz < Bar
171
+ def method_with_missing_param_doc(param1, param2, param3)
172
+ end
173
+ end
174
+
175
+ class Qux # :nodoc:
176
+ def method_with_implicit_nodoc
177
+ end
178
+
179
+ DOCCED_VALUE = 42 # :doc:
180
+
181
+ class Quux
182
+ def method_without_nodoc
183
+ end
184
+
185
+ PUBLIC_VALUE = :foo
186
+ PRIVATE_VALUE = :bar # :nodoc:
187
+
188
+ # @private
189
+ def method_with_private_tag
190
+ end
191
+
192
+ def method_with_explicit_nodoc # :nodoc:
193
+ end
194
+ end
195
+ end
196
+
197
+ class HiddenClass #:nodoc: all
198
+ def some_value
199
+ end
200
+
201
+ class EvenMoreHiddenClass
202
+ def method_with_implicit_nodoc
203
+ end
204
+
205
+ class SuddenlyVisibleClass # :doc:
206
+ def method_with_implicit_doc
207
+ end
208
+ end
209
+ end
210
+ end
211
+ end
212
+
213
+ def top
214
+ end