inch 0.2.3 → 0.3.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (111) hide show
  1. checksums.yaml +4 -4
  2. data/.simplecov +7 -0
  3. data/TODOS.md +0 -5
  4. data/config/defaults.rb +26 -1
  5. data/inch.gemspec +1 -0
  6. data/lib/inch.rb +2 -1
  7. data/lib/inch/api.rb +34 -0
  8. data/lib/inch/api/filter.rb +17 -0
  9. data/lib/inch/api/get.rb +30 -0
  10. data/lib/inch/api/list.rb +10 -0
  11. data/lib/inch/api/options/base.rb +45 -0
  12. data/lib/inch/api/options/filter.rb +25 -0
  13. data/lib/inch/api/options/suggest.rb +36 -0
  14. data/lib/inch/api/stats.rb +7 -0
  15. data/lib/inch/api/suggest.rb +110 -0
  16. data/lib/inch/cli.rb +4 -1
  17. data/lib/inch/cli/command/base.rb +1 -17
  18. data/lib/inch/cli/command/base_list.rb +3 -63
  19. data/lib/inch/cli/command/base_object.rb +6 -28
  20. data/lib/inch/cli/command/list.rb +3 -2
  21. data/lib/inch/cli/command/options/base.rb +1 -1
  22. data/lib/inch/cli/command/options/base_list.rb +4 -2
  23. data/lib/inch/cli/command/options/suggest.rb +9 -8
  24. data/lib/inch/cli/command/output/base.rb +9 -11
  25. data/lib/inch/cli/command/output/list.rb +2 -2
  26. data/lib/inch/cli/command/output/show.rb +2 -10
  27. data/lib/inch/cli/command/output/stats.rb +4 -3
  28. data/lib/inch/cli/command/output/suggest.rb +5 -5
  29. data/lib/inch/cli/command/stats.rb +4 -3
  30. data/lib/inch/cli/command/suggest.rb +4 -94
  31. data/lib/inch/code_object.rb +2 -2
  32. data/lib/inch/code_object/converter.rb +89 -0
  33. data/lib/inch/code_object/provider.rb +36 -0
  34. data/lib/inch/code_object/provider/yard.rb +19 -0
  35. data/lib/inch/code_object/provider/yard/docstring.rb +106 -0
  36. data/lib/inch/code_object/provider/yard/nodoc_helper.rb +93 -0
  37. data/lib/inch/code_object/provider/yard/object.rb +55 -0
  38. data/lib/inch/code_object/provider/yard/object/base.rb +262 -0
  39. data/lib/inch/code_object/provider/yard/object/class_object.rb +12 -0
  40. data/lib/inch/code_object/provider/yard/object/constant_object.rb +12 -0
  41. data/lib/inch/code_object/provider/yard/object/method_object.rb +126 -0
  42. data/lib/inch/code_object/provider/yard/object/method_parameter_object.rb +88 -0
  43. data/lib/inch/code_object/provider/yard/object/module_object.rb +12 -0
  44. data/lib/inch/code_object/provider/yard/object/namespace_object.rb +47 -0
  45. data/lib/inch/code_object/provider/yard/parser.rb +54 -0
  46. data/lib/inch/code_object/proxy.rb +5 -3
  47. data/lib/inch/code_object/proxy/base.rb +103 -110
  48. data/lib/inch/code_object/proxy/class_object.rb +0 -1
  49. data/lib/inch/code_object/proxy/method_object.rb +20 -99
  50. data/lib/inch/code_object/proxy/method_parameter_object.rb +15 -39
  51. data/lib/inch/code_object/proxy/namespace_object.rb +7 -18
  52. data/lib/inch/codebase.rb +19 -0
  53. data/lib/inch/codebase/objects.rb +73 -0
  54. data/lib/inch/codebase/objects_filter.rb +61 -0
  55. data/lib/inch/codebase/proxy.rb +22 -0
  56. data/lib/inch/config.rb +8 -1
  57. data/lib/inch/evaluation.rb +5 -7
  58. data/lib/inch/evaluation/file.rb +1 -1
  59. data/lib/inch/evaluation/grade.rb +1 -1
  60. data/lib/inch/evaluation/object_schema.rb +3 -1
  61. data/lib/inch/evaluation/priority_range.rb +44 -0
  62. data/lib/inch/evaluation/proxy.rb +25 -0
  63. data/lib/inch/evaluation/proxy/base.rb +146 -0
  64. data/lib/inch/evaluation/proxy/class_object.rb +8 -0
  65. data/lib/inch/evaluation/proxy/constant_object.rb +19 -0
  66. data/lib/inch/evaluation/proxy/method_object.rb +65 -0
  67. data/lib/inch/evaluation/proxy/module_object.rb +8 -0
  68. data/lib/inch/evaluation/proxy/namespace_object.rb +27 -0
  69. data/lib/inch/evaluation/role/base.rb +19 -0
  70. data/lib/inch/evaluation/role/constant.rb +16 -0
  71. data/lib/inch/evaluation/role/method.rb +22 -0
  72. data/lib/inch/evaluation/role/method_parameter.rb +31 -1
  73. data/lib/inch/evaluation/role/namespace.rb +15 -0
  74. data/lib/inch/evaluation/role/object.rb +24 -0
  75. data/lib/inch/rake/suggest.rb +1 -0
  76. data/lib/inch/utils/read_write_methods.rb +44 -0
  77. data/lib/inch/{cli → utils}/weighted_list.rb +1 -1
  78. data/lib/inch/version.rb +1 -1
  79. data/test/fixtures/simple/lib/broken.rb +8 -0
  80. data/test/inch/api/filter_test.rb +51 -0
  81. data/test/inch/api/get_test.rb +22 -0
  82. data/test/inch/api/list_test.rb +15 -0
  83. data/test/inch/api/options/base_test.rb +30 -0
  84. data/test/inch/api/stats_test.rb +15 -0
  85. data/test/inch/api/suggest_test.rb +26 -0
  86. data/test/inch/cli/command/list_test.rb +2 -1
  87. data/test/inch/code_object/converter_test.rb +29 -0
  88. data/test/inch/code_object/{docstring_test.rb → provider/yard/docstring_test.rb} +13 -13
  89. data/test/inch/code_object/{nodoc_helper_test.rb → provider/yard/nodoc_helper_test.rb} +6 -6
  90. data/test/inch/code_object/provider/yard_test.rb +11 -0
  91. data/test/inch/code_object/provider_test.rb +9 -0
  92. data/test/inch/code_object/proxy/method_object_test.rb +22 -22
  93. data/test/inch/code_object/proxy_test.rb +10 -10
  94. data/test/inch/codebase/objects_test.rb +28 -0
  95. data/test/inch/codebase/proxy_test.rb +17 -0
  96. data/test/inch/evaluation/role/base_test.rb +71 -0
  97. data/test/inch/{cli → utils}/weighted_list_test.rb +2 -2
  98. data/test/shared/base_list.rb +73 -0
  99. data/test/test_helper.rb +0 -95
  100. metadata +89 -24
  101. data/lib/inch/code_object/docstring.rb +0 -102
  102. data/lib/inch/code_object/nodoc_helper.rb +0 -107
  103. data/lib/inch/evaluation/base.rb +0 -157
  104. data/lib/inch/evaluation/class_object.rb +0 -6
  105. data/lib/inch/evaluation/constant_object.rb +0 -33
  106. data/lib/inch/evaluation/method_object.rb +0 -105
  107. data/lib/inch/evaluation/module_object.rb +0 -6
  108. data/lib/inch/evaluation/namespace_object.rb +0 -52
  109. data/lib/inch/evaluation/read_write_methods.rb +0 -21
  110. data/lib/inch/source_parser.rb +0 -62
  111. data/test/inch/source_parser_test.rb +0 -23
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 76a30cfdd0b22157bc5ef102e9f15cc96ec40147
4
- data.tar.gz: 21d1a3ecb2c12294579f4406059a322e25fb15ff
3
+ metadata.gz: fb172151aa6a4cebe01d50b2e38a5b43bc1d10ba
4
+ data.tar.gz: c19f22f6081241b240eeaee8bdbf2b2d910e7c68
5
5
  SHA512:
6
- metadata.gz: e60ae99656807e6731978c0b3bd29534ad313bcda1f8aabae5407dc062bb8aa3f1e589f3599b900f917973608047d1e6909bdfc52e872792d07e281b18cda16f
7
- data.tar.gz: 5bd8e9097b64d1cb9e454ef47e052e1d96ca1d2f562d2c12c9ae470b26de4db456e6c901563f5c9b9267eb013a6976ee25c2f31f768577806e826d6bf6be3b79
6
+ metadata.gz: c612a1a55be07cc3d6d120eb21a6e94670d16f3399b260b5837fc91f427cf89f4c54d2fa6bfd73aff747353543eb242032c7325fe871553fdff483f29bfb142e
7
+ data.tar.gz: ea91964f803278cea9ff25d202090ac67e709a08b96e046490198a48b42ec4e87c7f672c272f01e2ef63534053b80f16b6cc5cdca5f808132cf323a7b5e10ec9
@@ -0,0 +1,7 @@
1
+ SimpleCov.start do
2
+ add_filter '/test/'
3
+
4
+ add_group 'CLI', 'lib/inch/cli'
5
+ add_group 'Code Objects', 'lib/inch/code_object'
6
+ add_group 'Evaluation', 'lib/inch/evaluation'
7
+ end
data/TODOS.md CHANGED
@@ -3,10 +3,5 @@
3
3
  * Recognize all relevant options in .yardopts file
4
4
  * --plugin
5
5
  * --[no-]api API
6
- * Provide reusable context that filters code objects according to the
7
- visibility options
8
6
  * Add support for multiple signatures for methods
9
7
  (realized via the @overload tag in YARD)
10
-
11
- * Think about implicit cases in terms of evaluation:
12
- * attr_* methods are automatically assigned a docstring and @param tag
@@ -27,6 +27,31 @@ Inch::Config.run do
27
27
  bg_color :color105
28
28
  end
29
29
 
30
+ priority(:N) do
31
+ priorities 4..99
32
+ arrow "\u2191"
33
+ end
34
+
35
+ priority(:NE) do
36
+ priorities 2...4
37
+ arrow "\u2197"
38
+ end
39
+
40
+ priority(:E) do
41
+ priorities 0...2
42
+ arrow "\u2192"
43
+ end
44
+
45
+ priority(:SE) do
46
+ priorities -2...0
47
+ arrow "\u2198"
48
+ end
49
+
50
+ priority(:S) do
51
+ priorities -99...-2
52
+ arrow "\u2193"
53
+ end
54
+
30
55
  schema(:ConstantObject) do
31
56
  docstring 1.0
32
57
 
@@ -62,7 +87,7 @@ Inch::Config.run do
62
87
  parameters parameters + return_type
63
88
  return_type 0.0
64
89
  end
65
-
90
+
66
91
  if object.constructor?
67
92
  return_description 0.0
68
93
  end
@@ -26,6 +26,7 @@ Gem::Specification.new do |spec|
26
26
  spec.add_development_dependency "bundler", "~> 1.5"
27
27
  spec.add_development_dependency "rake"
28
28
  spec.add_development_dependency "pry"
29
+ spec.add_development_dependency "minitest", "~> 5.2"
29
30
 
30
31
  spec.add_dependency 'sparkr', ">= 0.2.0"
31
32
  spec.add_dependency "term-ansicolor"
@@ -3,8 +3,9 @@ require "inch/version"
3
3
  module Inch
4
4
  end
5
5
 
6
+ require_relative 'inch/api'
6
7
  require_relative 'inch/core_ext'
7
- require_relative 'inch/source_parser'
8
+ require_relative 'inch/codebase'
8
9
  require_relative 'inch/code_object'
9
10
  require_relative 'inch/evaluation'
10
11
  require_relative 'inch/cli'
@@ -0,0 +1,34 @@
1
+ module Inch
2
+ # The API module is the entry point for Inch's APIs
3
+ #
4
+ # APIs are kind of "use cases" that are utilized by the CLI classes to
5
+ # actually "do things".
6
+ #
7
+ # Example:
8
+ #
9
+ # $ inch list lib/**/*.rb --private
10
+ #
11
+ # This basically calls something like this:
12
+ #
13
+ # codebase = Codebase::Proxy.new(Dir.pwd, ["lib/**/*.rb"], [])
14
+ # options = {:visibility => [:public, :protected, :private]}
15
+ # context = API::List.new(codebase, options)
16
+ # context.objects # => Array
17
+ #
18
+ # The List API takes a Codebase::Proxy object and an options
19
+ # hash or a class in API::Options and returns objects and grade_lists
20
+ # matching that options.
21
+ #
22
+ module API
23
+ end
24
+ end
25
+
26
+ require_relative 'api/options/base'
27
+ require_relative 'api/options/filter'
28
+ require_relative 'api/options/suggest'
29
+
30
+ require_relative 'api/filter'
31
+ require_relative 'api/get'
32
+ require_relative 'api/list'
33
+ require_relative 'api/suggest'
34
+ require_relative 'api/stats'
@@ -0,0 +1,17 @@
1
+ module Inch
2
+ module API
3
+ # Filters a codebase's objects based on given options
4
+ class Filter
5
+ attr_reader :codebase
6
+ attr_reader :objects
7
+ attr_reader :grade_lists
8
+
9
+ def initialize(codebase, options)
10
+ @codebase = codebase
11
+ codebase.objects.filter! Options::Filter(options)
12
+ @objects = codebase.objects.to_a
13
+ @grade_lists = @codebase.grade_lists
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,30 @@
1
+ module Inch
2
+ module API
3
+ # Gets all objects matching the given +object_names+
4
+ class Get < Filter
5
+ attr_reader :object
6
+
7
+ def initialize(codebase, object_names)
8
+ super(codebase, {})
9
+ @objects = find_objects_with_names(object_names)
10
+ @object = objects.first
11
+ end
12
+
13
+ private
14
+
15
+ # Returns all objects matching the given +object_names+
16
+ #
17
+ # @param object_names [Array<String>]
18
+ # @return [Array<CodeObject::Proxy::Base>]
19
+ def find_objects_with_names(object_names)
20
+ object_names.map do |object_name|
21
+ if object = codebase.objects.find(object_name)
22
+ object
23
+ else
24
+ codebase.objects.starting_with(object_name)
25
+ end
26
+ end.flatten
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,10 @@
1
+ module Inch
2
+ module API
3
+ class List < Filter
4
+ def initialize(codebase, options)
5
+ super
6
+ @options = options
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,45 @@
1
+ module Inch
2
+ module API
3
+ module Options
4
+ class Base
5
+ class << self
6
+ # Creates an attribute with an optional default value
7
+ #
8
+ # @param name [Symbol] the name of the attribute
9
+ # @param default [nil] the default value of the attribute
10
+ # @return [void]
11
+ def attribute(name, default = nil)
12
+ define_method(name) do
13
+ instance_variable_get("@#{name}") || default
14
+ end
15
+ @attributes ||= {}
16
+ @attributes[to_s] ||= []
17
+ @attributes[to_s] << name
18
+ end
19
+
20
+ def attribute_names
21
+ @attributes ||= {}
22
+ @attributes[to_s] ||= []
23
+ end
24
+ end
25
+
26
+ def initialize(options_or_hash)
27
+ self.class.attribute_names.each do |name|
28
+ read options_or_hash, name
29
+ end
30
+ end
31
+
32
+ protected
33
+
34
+ def read(options_or_hash, name)
35
+ value = if options_or_hash.is_a?(Hash)
36
+ options_or_hash[name]
37
+ else
38
+ options_or_hash.send(name)
39
+ end
40
+ instance_variable_set("@#{name}", value)
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,25 @@
1
+ module Inch
2
+ module API
3
+ module Options
4
+ class Filter < Base
5
+ # This module is included here and in Command::Options::BaseList
6
+ # to ensure the same default values for the command-line and library
7
+ # interface
8
+ module DefaultAttributeValues
9
+ DEFAULT_VISIBILITY = [:public, :protected]
10
+ end
11
+
12
+ include DefaultAttributeValues
13
+
14
+ attribute :visibility, DEFAULT_VISIBILITY
15
+ attribute :namespaces
16
+ attribute :undocumented
17
+ attribute :depth
18
+ end
19
+
20
+ def self.Filter(options_or_hash)
21
+ Filter.new(options_or_hash)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,36 @@
1
+ require 'inch/evaluation/proxy/base'
2
+
3
+ module Inch
4
+ module API
5
+ module Options
6
+ class Suggest < Base
7
+ # This module is included here and in Command::Options::Suggest
8
+ # to ensure the same default values for the command-line and library
9
+ # interface
10
+ module DefaultAttributeValues
11
+ DEFAULT_OBJECT_COUNT = 20
12
+ DEFAULT_FILE_COUNT = 5
13
+ DEFAULT_PROPER_GRADES = [:A, :B]
14
+ DEFAULT_GRADES_TO_DISPLAY = [:B, :C, :U]
15
+ DEFAULT_GRADE_WEIGHTS = [0.2, 0.4, 0.4]
16
+ DEFAULT_OBJECT_MIN_PRIORITY = 0
17
+ DEFAULT_OBJECT_MAX_SCORE = ::Inch::Evaluation::Proxy::Base::MAX_SCORE
18
+ end
19
+
20
+ include DefaultAttributeValues
21
+
22
+ attribute :object_count, DEFAULT_OBJECT_COUNT
23
+ attribute :file_count, DEFAULT_FILE_COUNT
24
+ attribute :proper_grades, DEFAULT_PROPER_GRADES
25
+ attribute :grades_to_display, DEFAULT_GRADES_TO_DISPLAY
26
+ attribute :grade_weights, DEFAULT_GRADE_WEIGHTS
27
+ attribute :object_min_priority, DEFAULT_OBJECT_MIN_PRIORITY
28
+ attribute :object_max_score, DEFAULT_OBJECT_MAX_SCORE
29
+ end
30
+
31
+ def self.Suggest(options_or_hash)
32
+ Suggest.new(options_or_hash)
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,7 @@
1
+ module Inch
2
+ module API
3
+ class Stats < Filter
4
+
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,110 @@
1
+ require 'inch/utils/weighted_list'
2
+
3
+ module Inch
4
+ module API
5
+ class Suggest < Filter
6
+ def initialize(codebase, options)
7
+ super
8
+ @options = Options::Suggest(options)
9
+ end
10
+
11
+ def files
12
+ list = files_sorted_by_importance
13
+ how_many = @options.file_count || list.size
14
+ list[0...how_many]
15
+ end
16
+
17
+ # @return [Array] the +@options.object_count+ objects the API suggests
18
+ def objects
19
+ filter_objects_to_display
20
+ end
21
+
22
+
23
+ # @return [Array] all the objects that match +@options+
24
+ def all_objects
25
+ relevant_objects
26
+ end
27
+
28
+ private
29
+
30
+ # @return [Fixnum] how many objects should be displayed in the output
31
+ def object_count
32
+ @options.object_count
33
+ end
34
+
35
+ # @return [Array<Fixnum>]
36
+ # how many objects of each grade should be displayed in the output
37
+ def object_list_counts
38
+ @options.grade_weights.map { |w| w * object_count }
39
+ end
40
+
41
+ # @return [Array] the objects that should be displayed in the output
42
+ def filter_objects_to_display
43
+ graded_list = []
44
+ @options.grades_to_display.map do |grade|
45
+ r = grade_list(grade)
46
+ arr = select_by_priority(r.objects, @options.object_min_priority)
47
+ arr = arr.select { |o| o.score <= @options.object_max_score }
48
+ graded_list << arr
49
+ end
50
+
51
+ weighted_list = Utils::WeightedList.new(graded_list, object_list_counts)
52
+
53
+ list = Codebase::Objects.sort_by_priority(weighted_list.to_a.flatten)
54
+
55
+ if list.size > object_count
56
+ list = list[0...object_count]
57
+ end
58
+ list
59
+ end
60
+
61
+ def files_sorted_by_importance
62
+ list = all_filenames(relevant_objects).uniq.map do |filename|
63
+ f = Evaluation::File.for(filename, relevant_objects)
64
+ end
65
+
66
+ priority_list = list.select do |f|
67
+ relevant_grades.include?(f.grade) &&
68
+ relevant_priorities.include?(f.priority)
69
+ end
70
+
71
+ Codebase::Objects.sort_by_priority(priority_list.empty? ? list : priority_list)
72
+ end
73
+
74
+ def all_filenames(objects)
75
+ codebase.objects.map do |o|
76
+ o.files.map(&:first)
77
+ end.flatten
78
+ end
79
+
80
+ # Returns the unique grades assigned to objects
81
+ #
82
+ # grades # => [:A, :B, :C, :U]
83
+ #
84
+ # @return [Array<Symbol>]
85
+ def grades
86
+ codebase.objects.map(&:grade).uniq
87
+ end
88
+
89
+ def grade_list(grade_symbol)
90
+ grade_lists.detect { |r| r.grade.to_sym == grade_symbol }
91
+ end
92
+
93
+ def select_by_priority(list, min_priority)
94
+ list.select { |o| o.priority >= min_priority }
95
+ end
96
+
97
+ def relevant_grades
98
+ grades.size >= 2 ? grades[-2..-1] : [grades.last].compact
99
+ end
100
+
101
+ def relevant_objects
102
+ select_by_priority(codebase.objects, @options.object_min_priority)
103
+ end
104
+
105
+ def relevant_priorities
106
+ (@options.object_min_priority..99)
107
+ end
108
+ end
109
+ end
110
+ end
@@ -1,4 +1,8 @@
1
1
  module Inch
2
+ # The CLI module is tasked with the deconstruction of CLI calls
3
+ # into API calls.
4
+ #
5
+ # @see Inch::API
2
6
  module CLI
3
7
  class << self
4
8
  # Returns the columns of the terminal window
@@ -17,7 +21,6 @@ module Inch
17
21
  end
18
22
 
19
23
  require_relative 'cli/arguments'
20
- require_relative 'cli/weighted_list'
21
24
  require_relative 'cli/sparkline_helper'
22
25
  require_relative 'cli/trace_helper'
23
26
  require_relative 'cli/yardopts_helper'
@@ -38,7 +38,7 @@ module Inch
38
38
  class Base
39
39
  include TraceHelper
40
40
 
41
- attr_reader :source_parser # @return [SourceParser]
41
+ attr_reader :codebase # @return [Codebase::Proxy]
42
42
 
43
43
  # Helper method to run an instance with the given +args+
44
44
  #
@@ -97,22 +97,6 @@ module Inch
97
97
  def usage
98
98
  "Usage: inch #{name} [options]"
99
99
  end
100
-
101
- private
102
-
103
- # Returns the source parser against the given +paths+, while
104
- # excluding all paths given in +excluded+
105
- #
106
- # @param paths [Array<String>]
107
- # @param excluded [Array<String>]
108
- # @return [void]
109
- def run_source_parser(paths, excluded)
110
- debug "Parsing:\n" \
111
- " files: #{paths.inspect}\n" \
112
- " excluded: #{excluded.inspect}"
113
-
114
- @source_parser = SourceParser.run(paths, excluded)
115
- end
116
100
  end
117
101
  end
118
102
  end