inch 0.0.1 → 0.1.0

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.
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