inch 0.1.4 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/TODOS.md +5 -3
  3. data/bin/inch +9 -4
  4. data/inch.gemspec +9 -4
  5. data/lib/inch.rb +1 -0
  6. data/lib/inch/cli.rb +6 -0
  7. data/lib/inch/cli/command.rb +0 -6
  8. data/lib/inch/cli/command_parser.rb +0 -2
  9. data/lib/inch/code_object/nodoc_helper.rb +1 -1
  10. data/lib/inch/code_object/proxy/base.rb +18 -3
  11. data/lib/inch/code_object/proxy/method_object.rb +5 -0
  12. data/lib/inch/config.rb +53 -0
  13. data/lib/inch/evaluation.rb +1 -1
  14. data/lib/inch/evaluation/base.rb +45 -1
  15. data/lib/inch/evaluation/constant_object.rb +10 -5
  16. data/lib/inch/evaluation/criteria.rb +38 -0
  17. data/lib/inch/evaluation/method_object.rb +50 -42
  18. data/lib/inch/evaluation/namespace_object.rb +38 -33
  19. data/lib/inch/evaluation/role/constant.rb +1 -0
  20. data/lib/inch/evaluation/role/method.rb +41 -10
  21. data/lib/inch/evaluation/role/method_parameter.rb +16 -1
  22. data/lib/inch/evaluation/role/namespace.rb +17 -5
  23. data/lib/inch/evaluation/role/object.rb +35 -0
  24. data/lib/inch/version.rb +1 -1
  25. data/test/fixtures/simple/lib/foo.rb +0 -37
  26. data/test/fixtures/simple/lib/nodoc.rb +45 -0
  27. data/test/fixtures/simple/lib/role_methods.rb +4 -0
  28. data/test/inch/code_object/nodoc_helper_test.rb +3 -1
  29. data/test/inch/code_object/proxy/method_object_test.rb +9 -0
  30. metadata +26 -32
  31. data/lib/inch/cli/command/console.rb +0 -22
  32. data/lib/inch/cli/command/inspect.rb +0 -20
  33. data/lib/inch/cli/command/options/console.rb +0 -26
  34. data/lib/inch/cli/command/options/inspect.rb +0 -25
  35. data/lib/inch/cli/command/output/console.rb +0 -49
  36. data/lib/inch/cli/command/output/inspect.rb +0 -129
  37. data/test/inch/cli/command/console_test.rb +0 -59
  38. data/test/inch/cli/command/inspect_test.rb +0 -68
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 94f45218f025da4fe625a569967db6d85e9231a0
4
- data.tar.gz: 481b2138c2c48c35e1ca884e078d8265e578e39b
3
+ metadata.gz: cf840afb1d2d50573095b6a0592280e814d4329b
4
+ data.tar.gz: 95f117197464c1d151531ec48a43a90d4260341b
5
5
  SHA512:
6
- metadata.gz: 9d91370b78a36eb2a5fbd9541109a2b4bc5f97d6b67e3ce0de0cf9d8f22617821a9cd359dae170de49a6a80dde0e79e8437556e2a800c331d0bd0c45b96ab429
7
- data.tar.gz: c47ca4717186e9ed78161c3db7baa2742c1aac96a8208f0cae4e08c2b81a75bafe42fd23f356680180165b2dbe94cf69855c59a1fdfa0d3683ec2d79bac37e2b
6
+ metadata.gz: c58bc5692ce925bb99f44c885562a4c648289ca9a8331e255cf40b6718d8707775bacb30c37df19f86d462abfa9bad420c34f1751d8b90778f7f699336ee5b06
7
+ data.tar.gz: ccbb7641f546e75111cd698187ad1ad79c50ac5dc843b68481815649e54ee32758ad57f4200fe25281ec9e270ae4410a8f94b93334ccc4a18c8209286cc0d58e
data/TODOS.md CHANGED
@@ -7,10 +7,12 @@
7
7
  visibility options
8
8
  * Add support for multiple signatures for methods
9
9
  (realized via the @overload tag in YARD)
10
+
10
11
  * Think about implicit cases in terms of evaluation:
11
- * constructors without docstring/return_type
12
- * ?-methods with a return description
12
+ * constructors and ?-methods are automatically assigned a @return tag
13
+ * attr_* methods are automatically assigned a docstring and @param tag
14
+
13
15
  * Think about limiting the number of `B`-objects in `inch suggest`
14
16
  `inch suggest` shows too many `B`s even though there are still undocumented
15
17
  objects in the codebase. this becomes a problem, when one thinks of `B` as
16
- "good enough", which Inch itself suggests.
18
+ "good enough", which Inch itself suggests.
data/bin/inch CHANGED
@@ -6,11 +6,16 @@ Signal.trap("INT") do
6
6
  exit 1
7
7
  end
8
8
 
9
- path = __FILE__
10
- while File.symlink?(path)
11
- path = File.expand_path(File.readlink(path), File.dirname(path))
9
+ # @return [String] the path to the 'lib' directory of Inch
10
+ def find_lib_path
11
+ path = __FILE__
12
+ while File.symlink?(path)
13
+ path = File.expand_path(File.readlink(path), File.dirname(path))
14
+ end
15
+ File.join(File.dirname(File.expand_path(path)), '..', 'lib')
12
16
  end
13
- $:.unshift(File.join(File.dirname(File.expand_path(path)), '..', 'lib'))
17
+
18
+ $LOAD_PATH.unshift(find_lib_path)
14
19
 
15
20
  require 'inch'
16
21
 
@@ -13,16 +13,21 @@ Gem::Specification.new do |spec|
13
13
  spec.homepage = "http://trivelop.de/inch/"
14
14
  spec.license = "MIT"
15
15
 
16
- spec.files = `git ls-files -z`.split("\x0")
16
+ all_files = `git ls-files -z`.split("\x0")
17
+ files_without_dev_commands = all_files.select do |f|
18
+ f !~ /cli\/command\/.*(console|inspect)/
19
+ end
20
+
21
+ spec.files = files_without_dev_commands
17
22
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
23
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
24
  spec.require_paths = ["lib"]
20
25
 
21
26
  spec.add_development_dependency "bundler", "~> 1.5"
22
27
  spec.add_development_dependency "rake"
28
+ spec.add_development_dependency "pry"
23
29
 
24
- spec.add_dependency "yard", "~> 0.8.7"
30
+ spec.add_dependency 'sparkr', ">= 0.2.0"
25
31
  spec.add_dependency "term-ansicolor"
26
- spec.add_dependency 'sparkr', "~> 0.2.0"
27
- spec.add_dependency "pry"
32
+ spec.add_dependency "yard", "~> 0.8.7"
28
33
  end
@@ -7,4 +7,5 @@ require_relative 'inch/core_ext'
7
7
  require_relative 'inch/source_parser'
8
8
  require_relative 'inch/code_object'
9
9
  require_relative 'inch/evaluation'
10
+ require_relative 'inch/config'
10
11
  require_relative 'inch/cli'
@@ -22,3 +22,9 @@ require_relative 'cli/trace_helper'
22
22
  require_relative 'cli/yardopts_helper'
23
23
  require_relative 'cli/command'
24
24
  require_relative 'cli/command_parser'
25
+
26
+ console_rb = File.join(File.dirname(__FILE__), 'cli', 'command', 'console.rb')
27
+ if File.exists?(console_rb)
28
+ require_relative 'cli/command/console'
29
+ require_relative 'cli/command/inspect'
30
+ end
@@ -2,8 +2,6 @@ require_relative 'command/base'
2
2
  require_relative 'command/base_list'
3
3
  require_relative 'command/base_object'
4
4
 
5
- require_relative 'command/console'
6
- require_relative 'command/inspect'
7
5
  require_relative 'command/list'
8
6
  require_relative 'command/show'
9
7
  require_relative 'command/stats'
@@ -13,16 +11,12 @@ require_relative 'command/options/base'
13
11
  require_relative 'command/options/base_list'
14
12
  require_relative 'command/options/base_object'
15
13
 
16
- require_relative 'command/options/console'
17
- require_relative 'command/options/inspect'
18
14
  require_relative 'command/options/list'
19
15
  require_relative 'command/options/show'
20
16
  require_relative 'command/options/stats'
21
17
  require_relative 'command/options/suggest'
22
18
 
23
19
  require_relative 'command/output/base'
24
- require_relative 'command/output/console'
25
- require_relative 'command/output/inspect'
26
20
  require_relative 'command/output/list'
27
21
  require_relative 'command/output/show'
28
22
  require_relative 'command/output/stats'
@@ -44,8 +44,6 @@ module Inch
44
44
  end
45
45
 
46
46
  self.commands = {
47
- :console => Command::Console,
48
- :inspect => Command::Inspect,
49
47
  :list => Command::List,
50
48
  :show => Command::Show,
51
49
  :stats => Command::Stats,
@@ -8,7 +8,7 @@ module Inch
8
8
  # @note Doesnot recognize ":startdoc:" and ":stopdoc:"
9
9
  #
10
10
  def nodoc?
11
- object.tag(:private) || nodoc_comment?
11
+ private_tag? || nodoc_comment?
12
12
  end
13
13
 
14
14
  NO_DOC_REGEX = /#\s*\:nodoc\:/
@@ -8,7 +8,7 @@ module Inch
8
8
  extend Forwardable
9
9
  include NodocHelper
10
10
 
11
- # the actual (YARD) code object
11
+ # @return [YARD::CodeObjects::Base] the actual (YARD) code object
12
12
  attr_accessor :object
13
13
 
14
14
  # @return [Symbol]
@@ -17,7 +17,7 @@ module Inch
17
17
  attr_writer :grade
18
18
 
19
19
  # Tags considered by wrapper methods like {#has_code_example?}
20
- CONSIDERED_YARD_TAGS = %w(example param private return)
20
+ CONSIDERED_YARD_TAGS = %w(api example param private return)
21
21
 
22
22
  # convenient shortcuts to (YARD) code object
23
23
  def_delegators :object, :type, :path, :name, :namespace, :source, :source_type, :signature, :group, :dynamic, :visibility, :docstring
@@ -25,10 +25,15 @@ module Inch
25
25
  # convenient shortcuts to evalution object
26
26
  def_delegators :evaluation, :score, :roles, :priority
27
27
 
28
+ # @param object [YARD::CodeObjects::Base] the actual (YARD) code object
28
29
  def initialize(object)
29
30
  self.object = object
30
31
  end
31
32
 
33
+ def api_tag?
34
+ !object.tag(:api).nil? || (parent && parent.api_tag?)
35
+ end
36
+
32
37
  # To be overridden
33
38
  # @see Proxy::NamespaceObject
34
39
  # @return [Array,nil] the children of the current object or +nil+
@@ -36,10 +41,12 @@ module Inch
36
41
  nil
37
42
  end
38
43
 
44
+ # @return [Docstring]
39
45
  def docstring
40
46
  @docstring ||= Docstring.new(object.docstring)
41
47
  end
42
48
 
49
+ # @return [Evaluation::Base]
43
50
  def evaluation
44
51
  @evaluation ||= Evaluation.for(self)
45
52
  end
@@ -52,6 +59,7 @@ module Inch
52
59
  files.size > 0 ? files[0][0] : nil
53
60
  end
54
61
 
62
+ # @return [Symbol]
55
63
  def grade
56
64
  @grade ||= Evaluation.new_score_ranges.detect { |range|
57
65
  range.range.include?(score)
@@ -133,8 +141,15 @@ module Inch
133
141
  visibility == :private
134
142
  end
135
143
 
144
+ # @return [Boolean]
145
+ # +true+ if the object or its parent is tagged as @private
136
146
  def private_tag?
137
- !!object.tag(:private)
147
+ !object.tag(:private).nil? || (parent && parent.private_tag?)
148
+ end
149
+
150
+ def private_api_tag?
151
+ tag = object.tag(:api)
152
+ tag.text == 'private'
138
153
  end
139
154
 
140
155
  def protected?
@@ -3,6 +3,11 @@ module Inch
3
3
  module Proxy
4
4
  # Proxy class for methods
5
5
  class MethodObject < Base
6
+
7
+ def constructor?
8
+ name == :initialize
9
+ end
10
+
6
11
  def comment_and_abbrev_source
7
12
  comments.join('') + abbrev_source
8
13
  end
@@ -0,0 +1,53 @@
1
+ module Inch
2
+ module Evaluation
3
+
4
+ ConstantObject.criteria do
5
+ docstring 1.0
6
+
7
+ # optional:
8
+ unconsidered_tag 0.2
9
+ end
10
+
11
+ ClassObject.criteria do
12
+ docstring 1.0
13
+
14
+ # optional:
15
+ code_example_single 0.1
16
+ code_example_multi 0.2
17
+ unconsidered_tag 0.2
18
+ end
19
+
20
+ ModuleObject.criteria do
21
+ docstring 1.0
22
+
23
+ # optional:
24
+ code_example_single 0.1
25
+ code_example_multi 0.2
26
+ unconsidered_tag 0.2
27
+ end
28
+
29
+ MethodObject.criteria do
30
+ docstring 0.5
31
+ parameters 0.4
32
+ return_type 0.1
33
+ return_description 0.3
34
+
35
+ if object.constructor? || object.questioning_name?
36
+ parameters parameters + return_type
37
+ return_type 0.0
38
+ end
39
+
40
+ unless object.has_parameters?
41
+ return_description docstring + parameters
42
+ docstring docstring + parameters
43
+ parameters 0.0
44
+ end
45
+
46
+ # optional:
47
+ code_example_single 0.1
48
+ code_example_multi 0.25
49
+ unconsidered_tag 0.2
50
+ end
51
+
52
+ end
53
+ end
@@ -13,8 +13,8 @@ module Inch
13
13
  end
14
14
  end
15
15
 
16
+ require_relative 'evaluation/criteria'
16
17
  require_relative 'evaluation/file'
17
-
18
18
  require_relative 'evaluation/score_range'
19
19
 
20
20
  require_relative 'evaluation/role/base'
@@ -9,29 +9,36 @@ module Inch
9
9
 
10
10
  TAGGED_SCORE = 20 # assigned per unconsidered tag
11
11
 
12
-
12
+ # @return [CodeObject::Proxy::Base]
13
13
  attr_accessor :object
14
+
14
15
  attr_reader :min_score, :max_score
15
16
 
17
+ # @param object [CodeObject::Proxy::Base]
16
18
  def initialize(object)
17
19
  self.object = object
18
20
  @roles = []
19
21
  evaluate
20
22
  end
21
23
 
24
+ # Evaluates the objects and assigns roles
25
+ # @abstract
22
26
  def evaluate
23
27
  end
24
28
 
29
+ # @return [Float]
25
30
  def max_score
26
31
  arr = @roles.map(&:max_score).compact
27
32
  [MAX_SCORE].concat(arr).min
28
33
  end
29
34
 
35
+ # @return [Float]
30
36
  def min_score
31
37
  arr = @roles.map(&:min_score).compact
32
38
  [MIN_SCORE].concat(arr).max
33
39
  end
34
40
 
41
+ # @return [Float]
35
42
  def score
36
43
  value = @roles.inject(0) { |sum,r| sum + r.score.to_f }
37
44
  if value < min_score
@@ -43,19 +50,56 @@ module Inch
43
50
  end
44
51
  end
45
52
 
53
+ # @return [Fixnum]
46
54
  def priority
47
55
  @roles.inject(0) { |sum,r| sum + r.priority.to_i }
48
56
  end
49
57
 
58
+ # @return [Array<Evaluation::Role::Base>]
50
59
  def roles
51
60
  @roles
52
61
  end
53
62
 
63
+ class << self
64
+ attr_reader :criteria_map
65
+
66
+ # Defines the weights during evaluation for different criteria
67
+ #
68
+ # MethodObject.criteria do
69
+ # docstring 0.5
70
+ # parameters 0.4
71
+ # return_type 0.1
72
+ #
73
+ # if object.constructor?
74
+ # parameters 0.5
75
+ # return_type 0.0
76
+ # end
77
+ # end
78
+ #
79
+ # @return [void]
80
+ def criteria(&block)
81
+ @criteria_map ||= {}
82
+ @criteria_map[to_s] ||= Criteria.new(&block)
83
+ end
84
+ end
85
+
54
86
  protected
55
87
 
56
88
  def add_role(role)
57
89
  @roles << role
58
90
  end
91
+
92
+ def criteria
93
+ @criteria ||= begin
94
+ c = self.class.criteria_map[self.class.to_s]
95
+ c.evaluate(object)
96
+ c
97
+ end
98
+ end
99
+
100
+ def score_for(criteria_name)
101
+ criteria.send(criteria_name) * MAX_SCORE
102
+ end
59
103
  end
60
104
  end
61
105
  end
@@ -1,20 +1,25 @@
1
1
  module Inch
2
2
  module Evaluation
3
3
  class ConstantObject < Base
4
- DOC_SCORE = MAX_SCORE
5
-
6
4
  def evaluate
7
5
  if object.has_doc?
8
- add_role Role::Constant::WithDoc.new(object, DOC_SCORE)
6
+ add_role Role::Constant::WithDoc.new(object, score_for(:docstring))
9
7
  else
10
- add_role Role::Constant::WithoutDoc.new(object, DOC_SCORE)
8
+ add_role Role::Constant::WithoutDoc.new(object, score_for(:docstring))
11
9
  end
12
10
  if object.nodoc?
13
11
  add_role Role::Constant::TaggedAsNodoc.new(object)
14
12
  end
13
+ if object.api_tag?
14
+ if object.private_api_tag?
15
+ add_role Role::Object::TaggedAsPrivateAPI.new(object)
16
+ else
17
+ add_role Role::Object::TaggedAsAPI.new(object)
18
+ end
19
+ end
15
20
  if object.has_unconsidered_tags?
16
21
  count = object.unconsidered_tags.size
17
- add_role Role::Object::Tagged.new(object, TAGGED_SCORE * count)
22
+ add_role Role::Object::Tagged.new(object, score_for(:unconsidered_tag) * count)
18
23
  end
19
24
  if object.in_root?
20
25
  add_role Role::Constant::InRoot.new(object)
@@ -0,0 +1,38 @@
1
+ module Inch
2
+ module Evaluation
3
+ class Criteria
4
+ attr_reader :object
5
+
6
+ def initialize(&block)
7
+ @block = block
8
+ end
9
+
10
+ def evaluate(object)
11
+ @object = object
12
+ instance_eval(&@block)
13
+ end
14
+
15
+ NAMES = %w(
16
+ docstring
17
+ parameters
18
+ return_type
19
+ return_description
20
+ code_example_single
21
+ code_example_multi
22
+ unconsidered_tag
23
+ )
24
+
25
+ NAMES.each do |name|
26
+ class_eval """
27
+ def #{name}(value = nil)
28
+ if value.nil?
29
+ @#{name}.to_f
30
+ else
31
+ @#{name} = value
32
+ end
33
+ end
34
+ """
35
+ end
36
+ end
37
+ end
38
+ end